A subject is the fundamental unit of identity data in Tally. Every snapshot you write, every piece of evidence you attach, and every grant you issue refers to a subject. Subjects come in two flavors — organizations and people — and are permanently owned by the tenant that first registers them. Understanding subjects is the starting point for working with any part of the Tally platform.
Subject types
Tally models two distinct subject types. Choosing the correct type at creation time matters because it determines which canonical attribute vocabulary applies, how Tally indexes the subject, and what relationship types are expected.
| Type | Example subject_id | Use case |
|---|
entity | ent_acme_001 | Companies, LLCs, trusts, funds, and other legal organizations |
individual | ind_jordan_lee_99 | Natural persons — beneficial owners, directors, authorized signatories |
entity
An entity subject represents any non-human legal person: a corporation, LLC, partnership, trust, fund, or similar construct. Use entity subjects when you need to capture structured organizational attributes like registered address, jurisdiction of formation, or LEI code, and when you need to link the organization to its ultimate beneficial owners and control persons.
individual
An individual subject represents a natural person. Use individual subjects for any human actor in your KYC/KYB workflow — beneficial owners, directors, senior managers, authorized agents, and identity-verified end users. Individual subjects carry structured personal attributes like legal name components, date of birth, nationalities, and residential address.
Subject identity
Tally identifies every subject by a composite key of (subject_type, subject_id). Both parts are required, and together they must be unique within the platform.
The subject_id is a stable, opaque string you assign from your own system. Tally does not auto-generate subject IDs — you are responsible for maintaining stability. If you change the subject_id for a subject, Tally treats it as an entirely different subject and will create a new ownership record.
We recommend using a prefixed ID convention to make subject_type obvious at a glance and to reduce the risk of collisions between your entity and individual ID spaces:
ent_<your_stable_id> → entity subjects
ind_<your_stable_id> → individual subjects
These prefixes come directly from the real snapshots in Tally’s example corpus:
// From entity.snapshot.json
{
"subject": {
"subject_type": "entity",
"subject_id": "ent_acme_001"
}
}
// From individual.snapshot.json
{
"subject": {
"subject_type": "individual",
"subject_id": "ind_jordan_lee_99"
}
}
Your subject_id values will typically be primary keys or stable external
identifiers from your CRM, onboarding system, or data warehouse. Avoid
using mutable values like email addresses or display names as subject IDs.
Subject ownership
When you submit the first snapshot for a subject (snapshot_version: 1) under a given tenant, that tenant automatically becomes the permanent owner of the subject. Ownership is established once, at write time, and is structural — it never moves.
Only the owning tenant can:
- Write new snapshots or version updates for that subject
- Create grants that share the subject with other tenants
- Revoke grants they have previously issued
You can inspect who owns a subject at any time:
curl https://api.tally.so/v1/tenants/{tenant_id}/subjects/entity/ent_acme_001/owners \
-H "Authorization: Bearer <token>"
{
"items": [
{
"tenant_id": "acme-kyc-tenant",
"name": "Acme KYC Team",
"owner_since": "2026-02-18T09:00:00Z"
}
]
}
Ownership is a 1:1 relationship between a subject and a tenant. A subject
cannot have multiple owning tenants, and ownership cannot be transferred in
the current release. To share access with another tenant, use
grants instead.
Canonical attributes
Tally defines a canonical attribute vocabulary for each subject type. Using the canonical attributes ensures your data is interoperable across tenants, enables Tally’s display name inference, and keeps your attribute shapes predictable for consumers.
You are not required to use canonical attributes — the attributes field on a snapshot is a free-form JSON object and Tally will accept any shape. However, canonical attributes receive first-class treatment in the platform (display name derivation, search indexes, structured diffs).
Entity canonical attributes
Defined in packages/schema/src/identity.ts as CanonicalOrganizationAttributesZ:
| Attribute | Type | Notes |
|---|
legal_name | string | Required for canonical org subjects |
entity_kind | "organization" | Literal discriminator |
legal_form | string (optional) | e.g., "Limited Liability Company" |
legal_form_code | string (optional) | e.g., "LLC" |
formation_jurisdiction_code | string (optional) | ISO 3166-1 + subdivision, e.g., "US-DE" |
registry_identifier | string (optional) | Company number or EIN |
formation_date | YYYY-MM-DD (optional) | |
registered_address | Address object (optional) | See address schema |
entity_status | "active" | "inactive" | "dissolved" | "in_administration" (optional) | |
lei | 20-char alphanumeric (optional) | Legal Entity Identifier |
tax_identifier | string (optional) | |
website | URL (optional) | |
Individual canonical attributes
Defined in packages/schema/src/identity.ts as CanonicalIndividualAttributesZ:
| Attribute | Type | Notes |
|---|
name | IndividualName object | Required — first_name, last_name, optional middle_name, name_suffix |
birth_date | YYYY-MM-DD (optional) | |
nationalities | string[] (optional) | Array of ISO 3166-1 alpha-2 codes, e.g., ["US", "CA"] |
residential_address | Address object (optional) | |
tax_identifier | string (optional) | |
email | email string (optional) | |
phone | string (optional) | |
Relationships
Subjects can declare structured relationships to other subjects in their attributes. A relationship entry links the subject (the source) to another subject (the object) via a typed edge, with optional date ranges and provenance.
Tally defines five canonical relationship types in packages/schema/src/relationships.ts:
| Relationship type | Direction | Typical use |
|---|
parent_organization | Entity → Entity | The subject is a subsidiary; this points to its parent |
subsidiary | Entity → Entity | The subject has a subsidiary; this points to it |
control_person | Entity → Individual | The individual exercises control over the entity |
authorized_agent | Entity → Individual | The individual is authorized to act on behalf of the entity |
beneficial_owner | Entity → Individual | The individual holds a beneficial ownership stake |
Here is a real relationship entry from entity.snapshot.json:
{
"attributes": {
"legal_name": "Acme Industrial Supply, Inc.",
"relationships": [
{
"relationship_type": "beneficial_owner",
"target": {
"subject_type": "individual",
"subject_id": "ind_jordan_lee_99"
},
"ownership_percent": 35,
"effective_date": "2021-06-01"
}
]
}
}
When you use Tally’s canonical relationship_set vocabulary (from the RelationshipItemZ schema), each relationship entry carries additional structured fields:
{
"relationship_set": [
{
"relationship_id": "rel_bo_001",
"relationship_type": "beneficial_owner",
"object": {
"subject_type": "individual",
"subject_id": "ind_jordan_lee_99"
},
"attributes": {
"authority_scope": ["financial_transactions"]
},
"effective_from": "2021-06-01",
"effective_to": null
}
]
}
Each relationship entry should reference a subject that also exists (or will
exist) in Tally. While Tally does not enforce referential integrity today,
consistent subject IDs across your entity and individual subjects are what
make cross-subject graph queries and grant-based sharing meaningful.