Skip to content

Fingerprint a tenant's footprint (relocation verify gate)

GET
/v1/tenant-verify-digest
curl --request GET \
--url 'https://api.aerandil.com/v1/tenant-verify-digest?tenant_id=2489E9AD-2EE2-8E00-8EC9-32D5F69181C0' \
--header 'Authorization: Bearer <token>'

Return an independent per-table count and content checksum for the tenant’s objects / links / events (cloud proposal 0007 §4 step 5). The cross-cell relocation cutover job reads this from the source and the target cell and refuses to switch traffic until the two fingerprints agree — a re-query of each cell’s actual persisted state, independent of the import’s self-reported tally. The checksum covers exactly the portable columns the import preserves verbatim (events fold on the portable tenant_seq, never the source-local seq / commit_xid). Reads stay live in every write-mode.

Operator-level scope: tenant_admin:write (same surface as tenant export / import / write-mode / erasure).

tenant_id
required
string format: uuid

The tenant whose footprint is fingerprinted.

The tenant’s per-table count + content checksum.

Media typeapplication/json

An independent content fingerprint of a tenant’s footprint for the relocation cutover verify gate (0007 §4 step 5). Two cells whose digests compare equal hold identical portable content for the tenant.

object
events
required

One table’s fingerprint: a row count plus a 64-hex SHA-256-XOR checksum over the table’s portable columns (all-zero hex when the table is empty for the tenant). The XOR fold is order- and collation-independent, so two cells need not return rows in the same order to compare equal.

object
checksum
required

64-hex content checksum; all-zero when the table is empty.

string
count
required

Row count for the tenant in this table.

integer format: int64
links
required

One table’s fingerprint: a row count plus a 64-hex SHA-256-XOR checksum over the table’s portable columns (all-zero hex when the table is empty for the tenant). The XOR fold is order- and collation-independent, so two cells need not return rows in the same order to compare equal.

object
checksum
required

64-hex content checksum; all-zero when the table is empty.

string
count
required

Row count for the tenant in this table.

integer format: int64
objects
required

One table’s fingerprint: a row count plus a 64-hex SHA-256-XOR checksum over the table’s portable columns (all-zero hex when the table is empty for the tenant). The XOR fold is order- and collation-independent, so two cells need not return rows in the same order to compare equal.

object
checksum
required

64-hex content checksum; all-zero when the table is empty.

string
count
required

Row count for the tenant in this table.

integer format: int64
tenant_id
required
string format: uuid
Examplegenerated
{
"events": {
"checksum": "example",
"count": 1
},
"links": {
"checksum": "example",
"count": 1
},
"objects": {
"checksum": "example",
"count": 1
},
"tenant_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0"
}

Missing the tenant_admin:write scope. Tenant-level tokens MUST NOT carry this scope.

Media typeapplication/json

Structured error wrapper. Every non-2xx response from any Aerandil endpoint serialises to this shape; the HTTP status carries the failure class (4xx/5xx), the body adds a stable code for programmatic dispatch plus a human-readable message.

object
error
required
object
code
required

Stable, programmatic error code (e.g. unauthorized, forbidden, not_found, invalid_body, invalid_url, precondition_failed, no_secondary_key). Clients dispatch on code, not on the message (which may be localised or contextualised in future versions).

string
instance_id

Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.

string
message
required

Human-readable explanation of the failure.

string
parameters

Per-error structured detail. The shape varies by code (e.g. forbidden_action carries {"action": "..."}; precondition_failed carries {"current_version": N}).

Examplegenerated
{
"error": {
"code": "example",
"instance_id": "example",
"message": "example",
"parameters": "example"
}
}