Skip to content

Is this document still readable, and was its deletion certified?

GET
/v1/api/custody/status/{id}
curl --request GET \
--url https://testnet.permafrost.live/v1/api/custody/status/3f2a9c18-5b7e-4d61-9a0c-8e2f1d4b6a37 \
--header 'Authorization: Bearer <token>'

The full custody view of one object. alive is the field to read: it is true while the key lives, and false once it has been destroyed.

A 404 means “not yours, or not there”. An id another tenant owns, an id with no owner recorded, and an id that was never stored are one answer, so the surface cannot be used to discover ids.

No key, key identifier, custody backend or owner ever appears in a response from this surface.

id
required
string format: uuid
Example
3f2a9c18-5b7e-4d61-9a0c-8e2f1d4b6a37

The custody object identifier returned by POST /v1/api/custody/store.

The custody view.

Media typeapplication/json

The custody view of one held document. No key, key identifier, custody backend or owner appears here.

object
id
required
string format: uuid
content_hash

Sha256 of the plaintext — the hash the certificate names.

string | null
stored_hash

Sha256 of the stored ciphertext — the hash the verify route indexes.

string | null
alive
required

True while the key lives and the document can still be served.

boolean | null
incinerated

The complement of alive. True once the key has been destroyed.

boolean | null
incinerated_at

When the key was destroyed, in UTC. null while it lives.

string | null format: date-time
certificate_object_id

The on-chain certificate’s object id, once one has been minted.

string | null
certificate_tx_digest

The transaction that minted the certificate.

string | null
certificate_status
required

minted once the certificate exists. not_minted when the key was destroyed and no certificate landed — the destruction is no less final for it.

string
Allowed values: minted not_minted
deletion_mode

The claim the certificate makes, recorded on chain verbatim: auditable_vendor_side. null while the document is alive.

string | null
Example
{
"id": "3f2a9c18-5b7e-4d61-9a0c-8e2f1d4b6a37",
"content_hash": "7d1a2b3c4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8f9",
"stored_hash": "0c9b8a7d6e5f40312213a4b5c6d7e8f90a1b2c3d4e5f6071829304b5c6d7e8fa",
"alive": true,
"incinerated": false,
"incinerated_at": null,
"certificate_object_id": null,
"certificate_tx_digest": null,
"certificate_status": "minted",
"deletion_mode": null
}

No tenant on the request. Through the public edge this is the edge’s own refusal of the credential; the custody surface’s own generic refusal has the same status and carries no hint about which header, which surface, or whether the id exists.

Media typeapplication/json

The refusal shape. detail is present on a few routes and deliberately absent from the custody surface, where a detail string could carry an internal path.

object
error
required

The code, or a short fixed sentence.

string
detail

A human-readable note, where a route carries one.

string
Example
{
"error": "unauthorized"
}

No such custody object, an object owned by another tenant, or an object with no owner recorded. One answer for all three.

Media typeapplication/json

The refusal shape. detail is present on a few routes and deliberately absent from the custody surface, where a detail string could carry an internal path.

object
error
required

The code, or a short fixed sentence.

string
detail

A human-readable note, where a route carries one.

string
Example
{
"error": "not found"
}

The tenant is over an allowance. Retry-After carries whole seconds, rounded up and never zero. The per-tenant refusal also carries retry_after_ms; the custody surface’s own local limiter carries the code alone. Both are per tenant, keyed by the tenant address — one tenant spending its allowance does not consume another’s.

Media typeapplication/json
object
error
required
string
retry_after_ms

How long until one token is available, in milliseconds. Present on the per-tenant refusal.

integer
>= 1
Example
{
"error": "rate_limited",
"retry_after_ms": 240
}
Retry-After
integer
>= 1
Example
1

Whole seconds to wait before retrying.

Permafrost runs on Sui testnet and Walrus testnet. Everything here describes a shipped testnet instance, not a production service.