Core concepts

Mandate Labs is built on a small set of objects arranged in a hierarchy. Understanding how they nest — and why each layer exists — is the foundation for every integration.

Overview

Every action on the platform — onboarding a user, registering an agent, authorizing a payment — maps to one of six objects. They form a single ownership chain from the contracting organization down to an individual transaction decision:

Client → Program → Principal → Agent → Mandate → Authorization.

The split isn't arbitrary. It separates the three things a payments platform has to keep distinct: who is accountable (the Client and the Principal it KYC's), what is allowed (the Program's rails and the Mandate's limits), and what actually happened (the Authorization and its outcome). That separation is what lets one verified identity safely run many autonomous agents.

The object hierarchy

A Client is the tenant. It owns one or more Programs (the rails + policy) and onboards Principals (the people or merchants it has verified). Each Principal owns one or many Agents; each Agent is bounded by one or more Mandates; and every transaction an Agent attempts produces an Authorization.

owns enrols in (many-to-many) owns one → many bounded by decides each transaction Client cli_ Contracting organisation · tenant · credential holder Program prg_ Card / crypto rails + program-level policy Principal prn_ A person or merchant — KYC / KYB verified Agent agt_ An AI system that transacts under the Principal Mandate mnd_ Per-agent limits, MCCs, rails, expiry Authorization auth_ Real-time APPROVE / DECLINE / STEP_UP decision
The ownership chain. Identity (Client, Principal) is separated from authority (Program, Mandate) and from the decision record (Authorization).
The core invariant

A Principal is one stable prn_ that owns many Agents — you never mint a new Principal per agent. Add the 2nd…Nth agent to the same Principal. One KYC'd identity, many autonomous agents.

The objects

Client cli_

The contracting organisation and the tenant boundary. Every other object belongs to exactly one Client. The Client holds the API credentials, is the party Mandate Labs has a commercial agreement with, and is the obligated entity for compliance.

Created by Mandate Labs (POST /admin/clients) after a sales/KYB conversation — there is no self-serve sign-up.

Program prg_

A card and/or crypto program under a Client. It carries the enabled rails (card, crypto), program-level default limits, BIN/sponsor binding, and the verification mode. A Client can run several Programs (e.g. a card program and a stablecoin program), and a Principal can be enrolled in more than one.

Metering and policy are attributed at the Program level.

Principal prn_

A person or merchant the Client onboards and the platform KYC/KYB-verifies — not the contracting organisation (that's the Client). A Principal is the accountable identity behind the agents: it carries the verification status, the risk tier, and the Client's own customer reference (client_customer_ref) so a transaction can always be traced back to a real, verified subject.

Verification is either client-attested (the Client is the obligated entity and attests it ran CDD) or platform-provider (Mandate Labs runs KYC/KYB).

Agent agt_

An AI system that transacts on behalf of a Principal. Each Agent gets a unique id and a DID, starts at the REGISTERED trust level, and accrues a behavioural Decision-Trust (KYA) score over time. A Principal can own many Agents; each is independently scored and bounded.

An Agent can be registered before its Principal is verified, but it cannot hold an active Mandate or authorize until the Principal is VERIFIED.

Mandate mnd_

The spending authority granted to an Agent: max amount per transaction, daily/monthly limits, allowed merchant categories (MCCs), allowed countries, rails, and an expiry. An Agent transacts only within the bounds of an active Mandate; everything outside is declined before it reaches the trust engine.

A Mandate inherits its Agent's Program; program-level defaults apply unless the Mandate overrides them.

Authorization auth_

The decision record for a single transaction. Every request an Agent makes produces an Authorization with a verdict — APPROVE, STEP_UP, or DECLINE — plus the KYA score, risk signals, and full reason codes. Authorizations are the immutable, queryable history of what every agent did and why.

Outcomes (settlement, chargeback, dispute) attach back to the Authorization to close the trust loop.

Relationships

The cardinalities that matter when you model your integration:

FromToCardinalityNotes
ClientProgram1 → manyA Client runs one or more rails programs.
ClientPrincipal1 → manyEvery Principal belongs to exactly one Client.
PrincipalProgrammany ↔ manyA Principal enrols in one or more of its Client's Programs.
PrincipalAgent1 → manyThe core invariant — one identity, many agents.
AgentMandate1 → manyAn agent can hold multiple mandates (e.g. card + crypto).
AgentAuthorization1 → manyEvery transaction attempt is recorded.
ClientAPI credential1 → manyCredentials are held at the Client, optionally scoped per Program/env.

The lifecycle

How the objects come into being, end to end:

Client Principal Agent Mandate Authorize Outcome
  1. Provision the Client. After a sales/KYB conversation, Mandate Labs creates the Client and a default Program and issues the Client's API credential.
  2. Onboard a Principal. The Client onboards a person or merchant (POST /principals) and enrols them in a Program — verified client-attested (immediate) or platform-provider (pending KYC).
  3. Register Agents. The Client adds one or more Agents under that same Principal (POST /principals/{prn}/agents).
  4. Grant Mandates. Each Agent gets a Mandate (POST /agents/{agt}/mandates) bounding what it may spend.
  5. Authorize. The Agent requests authorization for each transaction (POST /authorize) and receives APPROVE / DECLINE / STEP_UP in real time.
  6. Close the loop. Settlement and dispute outcomes feed back, the Agent's trust score updates, and webhooks notify your systems.

Steps 2–4 can be done in one call with the POST /onboard bundle for quickstart and sandbox; the decoupled endpoints stay canonical for adding more agents later.

Two ways in

How you obtain the objects depends on whether you're experimenting or going live:

Next steps