Tally exposes several read endpoints that let you inspect identity data at different levels of granularity — from the latest resolved state of a subject, to a specific historical version, to a paginated audit trail of every change ever recorded. All read endpoints respect both your tenant’s membership role and any grants that govern cross-tenant access.
Get the current state
The most common read operation is fetching the current resolved state of a subject. Call GET /v1/subjects/:subject_type/:subject_id (or the tenant-scoped variant) to receive a structured response that includes the subject identity, the current snapshot summary, provenance metadata, and optional verification data.
curl https://api.tally.io/v1/tenants/acme-kyc/subjects/entity/ent_acme_001 \
-H "Authorization: Bearer $TALLY_API_KEY"
Response shape:
{
"subject": {
"subject_type": "entity",
"subject_id": "ent_acme_001"
},
"current_snapshot": {
"snapshot_id": "3f0b2c2c-2e46-4b58-8c45-3b5c58f4e9b2",
"snapshot_version": 3,
"generated_at": "2026-02-20T14:25:30Z",
"hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"prev_hash": "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"
},
"identity": {
"legal_name": "Acme Industrial Supply, Inc.",
"jurisdiction": "US-DE",
"status": "active",
"registered_address": {
"line1": "1200 Market St",
"city": "Wilmington",
"region": "DE",
"postal_code": "19801",
"country": "US"
}
},
"provenance": {
"evidence_count": 2,
"has_attribute_paths": true,
"has_audit": true
}
}
When you pass verify=hash or verify=chain as a query parameter, the response gains a verification object — see Verification modes below.
Get a specific snapshot
By version
By snapshot ID
Latest
Retrieve the exact snapshot at a known version number:curl https://api.tally.io/v1/tenants/acme-kyc/subjects/entity/ent_acme_001/snapshots/2 \
-H "Authorization: Bearer $TALLY_API_KEY"
This requires the read_lineage grant scope when accessing another tenant’s subject. Retrieve a snapshot when you have its UUID but not its version:curl https://api.tally.io/v1/tenants/acme-kyc/snapshots/3f0b2c2c-2e46-4b58-8c45-3b5c58f4e9b2 \
-H "Authorization: Bearer $TALLY_API_KEY"
This requires the read_snapshot_by_id grant scope when accessing another tenant’s subject. Retrieve the most recent snapshot envelope without constructing a version number:curl https://api.tally.io/v1/tenants/acme-kyc/subjects/entity/ent_acme_001/snapshots/latest \
-H "Authorization: Bearer $TALLY_API_KEY"
This returns the same snapshot as GET /v1/subjects/:subject_type/:subject_id but in the list-item format rather than the current-state format.
List snapshot history
GET /v1/subjects/:subject_type/:subject_id/history (also aliased at /snapshots) returns a paginated list of all snapshots for a subject, ordered by version.
curl "https://api.tally.io/v1/tenants/acme-kyc/subjects/entity/ent_acme_001/history?order=desc&limit=10" \
-H "Authorization: Bearer $TALLY_API_KEY"
Query parameters
| Parameter | Type | Default | Description |
|---|
limit | integer | 50 | Number of items per page (max 200) |
order | asc | desc | desc | Sort order by snapshot_version |
cursor | string | — | Base64url pagination cursor from a previous response |
view | header | full | full | Controls response verbosity (see View modes) |
verify | none | hash | chain | none | Enables inline cryptographic verification (see Verification modes) |
Example response:
{
"items": [
{
"snapshot_id": "3f0b2c2c-2e46-4b58-8c45-3b5c58f4e9b2",
"snapshot_version": 3,
"subject": {
"subject_type": "entity",
"subject_id": "ent_acme_001"
},
"generated_at": "2026-02-20T14:25:30Z",
"created_at": "2026-02-20T14:25:31Z",
"envelope": { ... }
},
{
"snapshot_id": "c2d3e4f5-a6b7-8901-cdef-234567890abc",
"snapshot_version": 2,
"subject": {
"subject_type": "entity",
"subject_id": "ent_acme_001"
},
"generated_at": "2026-02-19T09:00:00Z",
"created_at": "2026-02-19T09:00:01Z",
"envelope": { ... }
}
],
"page": {
"order": "desc",
"limit": 10,
"next_cursor": "eyJzdiI6MSwic2lkIjoiYjFhMmMzZDQtZTVmNi03ODkwLWFiY2QtZWYxMjM0NTY3ODkwIn0"
}
}
To fetch the next page, pass the next_cursor value as the cursor query parameter. When next_cursor is null, you have reached the last page.
View modes
The view query parameter controls how much of each snapshot is included in the response. It is available on all list and single-snapshot endpoints.
| Value | Returns |
|---|
header | snapshot_id, snapshot_version, generated_at, subject, created_at |
full (default) | Full envelope including attributes, evidence, audit, and attribute_paths |
Use view=header when you only need to traverse the version history or build a changelog UI, and want to avoid transferring large envelope payloads.
Verification modes
The verify query parameter asks Tally to perform cryptographic verification and return the result inline with the response. This is useful for spot-checks without needing to export and run the CLI.
| Value | Behavior |
|---|
none (default) | No verification is performed |
hash | Verifies the stored envelope_hash against a freshly computed SHA-256 hash of the RFC 8785–canonicalized envelope |
chain | Verifies that prev_hash matches the envelope_hash of the parent snapshot, tracing the chain link |
When you set verify=chain, you can also pass depth=N (integer ≥ 1) to traverse up to N chain links in a single request.
Example with hash verification:
curl "https://api.tally.io/v1/tenants/acme-kyc/subjects/entity/ent_acme_001?verify=hash" \
-H "Authorization: Bearer $TALLY_API_KEY"
The response gains a verification block:
{
"subject": { ... },
"current_snapshot": { ... },
"identity": { ... },
"provenance": { ... },
"verification": {
"mode": "hash",
"chain_supported": true,
"hash": {
"alg": "sha-256",
"value": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"stored": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"valid": true,
"method_used": "rfc8785",
"matches": true
},
"chain": {
"prev_hash": null,
"valid": null
}
}
}
Exporting all snapshots
GET /v1/subjects/:subject_type/:subject_id/export returns all snapshots for a subject in a single JSON payload intended for offline cryptographic verification.
curl "https://api.tally.io/v1/tenants/acme-kyc/subjects/entity/ent_acme_001/export" \
-H "Authorization: Bearer $TALLY_API_KEY" \
-o acme_001_export.json
The response structure:
{
"subject": {
"subject_type": "entity",
"subject_id": "ent_acme_001"
},
"canonicalization_method": "rfc8785",
"hash_algorithm": "sha-256",
"snapshots": [
{
"snapshot_version": 1,
"snapshot_id": "b1a2c3d4-e5f6-7890-abcd-ef1234567890",
"envelope": { ... },
"envelope_hash": "a665a45920422f9d...",
"prev_hash": null
},
{
"snapshot_version": 2,
"snapshot_id": "c2d3e4f5-a6b7-8901-cdef-234567890abc",
"envelope": { ... },
"envelope_hash": "e3b0c44298fc1c14...",
"prev_hash": "a665a45920422f9d..."
}
]
}
The export endpoint has a server-configured maximum size (1,000 snapshots by default). If a subject has more snapshots than this limit, the request returns 400 with a validation_error. Contact your Tally administrator to increase the limit for your deployment.
Once you have an export file, verify its integrity offline using the Tally CLI. See Verifying Exports for step-by-step instructions.
Listing your subjects
GET /v1/tenants/:tenant_id/subjects returns all subjects your tenant owns along with a summary of each subject’s latest snapshot.
curl https://api.tally.io/v1/tenants/acme-kyc/subjects \
-H "Authorization: Bearer $TALLY_API_KEY"
{
"subjects": [
{
"subject_type": "entity",
"subject_id": "ent_acme_001",
"latest_snapshot_id": "3f0b2c2c-2e46-4b58-8c45-3b5c58f4e9b2",
"latest_snapshot_version": 3,
"latest_generated_at": "2026-02-20T14:25:30Z"
},
{
"subject_type": "individual",
"subject_id": "ind_jordan_lee_99",
"latest_snapshot_id": "9a33c76e-0b08-4e90-b3fb-5e0f8f6c9a1d",
"latest_snapshot_version": 2,
"latest_generated_at": "2026-02-20T15:05:10Z"
}
]
}
This endpoint requires any active api_functional_role on your tenant (at minimum tenant_reader).