Skip to main content
The Entity States API is the primary write path for Tally. You submit a fully-materialized entity state envelope — a JSON document describing a subject’s current identity attributes, the evidence that supports them, and audit provenance — and Tally stores it as an immutable, versioned snapshot. Each accepted snapshot is content-hashed and chained to the previous version for that subject, building a tamper-evident lineage you can later read, diff, and export.

POST /v1/entity-states

This is the unauthenticated, legacy path and is available for local development or migration scenarios. For production use, prefer the tenant-scoped path below.
Submit a new identity snapshot. The request body must be a conforming entity_state_envelope_v1 document.
POST /v1/entity-states
Content-Type: application/json

POST /v1/tenants/:tenant_id/entity-states

The recommended path for production. Tally authenticates the caller against the tenant’s membership roster, enforces subject ownership on snapshot versions ≥ 2, and records the write against your tenant’s usage quota.
POST /v1/tenants/:tenant_id/entity-states
Content-Type: application/json
Authorization: Bearer <token>

Path parameters

tenant_id
string
required
The UUID of your tenant. The authenticated principal must hold the tenant_editor role within this tenant.

Request body

Both endpoints accept an identical request body: a single JSON object conforming to entity_state_envelope_v1.

Top-level fields

envelope_version
string
required
Must be the literal string "entity_state_envelope_v1". Tally rejects any other value.
snapshot_id
string
required
A client-generated UUID (v4 recommended) that uniquely identifies this snapshot across all subjects and tenants. Tally rejects a duplicate snapshot_id with 409 conflict.
snapshot_version
integer
required
The monotonically increasing version for this subject. Must be an integer ≥ 1. Tally rejects a duplicate (subject_id, snapshot_version) pair with 409 conflict. On the tenant-scoped path, snapshot_version: 1 automatically declares your tenant as the subject’s owner; all subsequent versions require pre-existing ownership.
generated_at
string
required
The RFC 3339 datetime at which this snapshot was generated by the producer, e.g. "2026-02-20T14:25:30Z". Must include a timezone offset (Z or ±HH:MM).
subject
object
required
Identifies the entity or individual this snapshot describes.
attributes
object
required
A JSON object containing the materialized identity attributes for the subject at generated_at. Attribute values may be any JSON type — string, number, boolean, object, array, or null. The object may be sparse; you do not need to include every attribute on every snapshot. Unknown keys are preserved and returned as-is.
evidence
array
required
An array of evidence metadata objects that support the attributes in this snapshot. May be empty ([]). Each object must include:
audit
object
required
Provenance metadata describing who created this snapshot and from which system.
attribute_paths
object
Optional attribution map linking JSON Pointer paths (RFC 6901) to the evidence items that support them. Keys are paths such as "/attributes/legal_name". Values are arrays of evidence reference objects, each containing at minimum evidence_id and evidence_type, and optionally role ("primary", "corroborating", or "conflicting"). Paths absent from this object are interpreted as having no attribution.
diff
object
Optional RFC 6902 diff describing changes relative to the prior snapshot. Must contain format: "rfc6902" and ops (array of JSON Patch operations). Tally treats this as metadata; the attributes object is always authoritative.

Example request

The following example submits version 3 of an entity snapshot for ent_acme_001 with two evidence items and an attribution map.
curl -X POST https://api.tally.io/v1/tenants/t_9f4a2d/entity-states \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
  "envelope_version": "entity_state_envelope_v1",
  "snapshot_id": "3f0b2c2c-2e46-4b58-8c45-3b5c58f4e9b2",
  "snapshot_version": 3,
  "generated_at": "2026-02-20T14:25:30Z",
  "subject": {
    "subject_type": "entity",
    "subject_id": "ent_acme_001"
  },
  "attributes": {
    "legal_name": "Acme Industrial Supply, Inc.",
    "trade_names": ["Acme Supply"],
    "jurisdiction": "US-DE",
    "incorporation_date": "2008-05-12",
    "status": "active",
    "registered_address": {
      "line1": "1200 Market St",
      "city": "Wilmington",
      "region": "DE",
      "postal_code": "19801",
      "country": "US"
    },
    "relationships": [
      {
        "relationship_type": "beneficial_owner",
        "target": {
          "subject_type": "individual",
          "subject_id": "ind_jordan_lee_99"
        },
        "ownership_percent": 35,
        "effective_date": "2021-06-01"
      }
    ]
  },
  "evidence": [
    {
      "evidence_id": "ev_2026_0001",
      "evidence_type": "government_registry_extract",
      "source": "Delaware Division of Corporations",
      "captured_at": "2026-02-18T16:10:00Z",
      "retrieved_at": "2026-02-18T16:12:00Z",
      "locator": "registry://de/corp/2288117",
      "hash": {
        "alg": "SHA-256",
        "value": "b3c1f1f0d9c06a8b3c2b9f4a2d5c1e9a0b5e1f5c8a7d9e0f1a2b3c4d5e6f7a8b"
      }
    },
    {
      "evidence_id": "ev_2026_0002",
      "evidence_type": "beneficial_ownership_attestation",
      "source": "Acme Compliance Portal",
      "captured_at": "2026-02-19T09:30:00Z",
      "notes": "Attested by compliance officer"
    }
  ],
  "audit": {
    "created_by": "kyc_service",
    "created_at": "2026-02-20T14:25:30Z",
    "source": "tally_ingest",
    "request_id": "req_6a1e2c",
    "correlation_id": "corr_55b7e1"
  },
  "attribute_paths": {
    "/attributes/legal_name": [
      {
        "evidence_id": "ev_2026_0001",
        "evidence_type": "government_registry_extract",
        "role": "primary"
      }
    ],
    "/attributes/registered_address/country": [
      {
        "evidence_id": "ev_2026_0001",
        "evidence_type": "government_registry_extract"
      }
    ],
    "/attributes/relationships/0/relationship_type": [
      {
        "evidence_id": "ev_2026_0002",
        "evidence_type": "beneficial_ownership_attestation",
        "role": "primary"
      }
    ],
    "/attributes/relationships/0/ownership_percent": [
      {
        "evidence_id": "ev_2026_0002",
        "evidence_type": "beneficial_ownership_attestation"
      }
    ]
  }
}'

Responses

Tally accepted and stored the snapshot. The response body is the stored snapshot document, identical to what you submitted plus any server-side fields Tally adds (such as internal timestamps).
{
  "envelope_version": "entity_state_envelope_v1",
  "snapshot_id": "3f0b2c2c-2e46-4b58-8c45-3b5c58f4e9b2",
  "snapshot_version": 3,
  "generated_at": "2026-02-20T14:25:30Z",
  "subject": {
    "subject_type": "entity",
    "subject_id": "ent_acme_001"
  },
  "attributes": { "legal_name": "Acme Industrial Supply, Inc." },
  "evidence": [],
  "audit": {
    "created_by": "kyc_service",
    "created_at": "2026-02-20T14:25:30Z",
    "source": "tally_ingest"
  }
}

GET /v1/tenants/:tenant_id/subjects

List all subjects owned by a tenant, along with a summary of each subject’s latest snapshot.
GET /v1/tenants/:tenant_id/subjects
Authorization: Bearer <token>

Path parameters

tenant_id
string
required
The UUID of your tenant. The authenticated principal must hold any active api_functional_role within this tenant.

Response

subjects
array
An array of subject summary objects.
{
  "subjects": [
    {
      "subject_type": "entity",
      "subject_id": "ent_acme_001",
      "latest_snapshot": {
        "snapshot_id": "3f0b2c2c-2e46-4b58-8c45-3b5c58f4e9b2",
        "snapshot_version": 3,
        "generated_at": "2026-02-20T14:25:30Z"
      }
    },
    {
      "subject_type": "individual",
      "subject_id": "ind_jordan_lee_99",
      "latest_snapshot": {
        "snapshot_id": "9a33c76e-0b08-4e90-b3fb-5e0f8f6c9a1d",
        "snapshot_version": 2,
        "generated_at": "2026-02-20T15:05:10Z"
      }
    }
  ]
}

GET /v1/entity-states/:snapshot_id

Fetch any snapshot directly by its UUID. This endpoint does not require tenant authentication and is available on the legacy path.
GET /v1/entity-states/:snapshot_id

Path parameters

snapshot_id
string
required
The UUID of the snapshot to retrieve.

Response

Returns 200 OK with the full stored snapshot envelope, or 404 not_found if no snapshot exists for the given UUID.
{
  "envelope_version": "entity_state_envelope_v1",
  "snapshot_id": "9a33c76e-0b08-4e90-b3fb-5e0f8f6c9a1d",
  "snapshot_version": 2,
  "generated_at": "2026-02-20T15:05:10Z",
  "subject": {
    "subject_type": "individual",
    "subject_id": "ind_jordan_lee_99"
  },
  "attributes": {
    "full_name": "Jordan Lee",
    "date_of_birth": "1987-11-04",
    "nationality": "US"
  },
  "evidence": [],
  "audit": {
    "created_by": "kyc_service",
    "created_at": "2026-02-20T15:05:10Z",
    "source": "tally_ingest"
  }
}