Cookbook
Sign as a tier-3 agent
Server-to-server signing for documents under the tier-3 ceiling — operational paperwork the customer pre-authorized.
Last updated
Server-to-server signing for documents under the tier-3 ceiling — operational paperwork the customer pre-authorized.
Trigger
A document falls within a tier-3 standing authorization (NDAs, contractor agreements, routine grants).
Call sequence
1. Sign in one call
POST /v1/documents/{doc}/sign { actor: 'agent_policy_xyz' }Idempotency
Signing idempotent on `(document, actor)`.
Webhooks
| Event | Description |
|---|---|
document.signed | Signed via the tier-3 policy. |
Errors
| Status | Code | Description |
|---|---|---|
403 | above_tier_ceiling | Document exceeds the tier-3 ceiling. Escalate to tier-4 or human. |
Related
This is Rail 2: the agent itself is the signer under UETA §14, with the human principal having pre-authorised the agent's authority through the token DSL and the per-action acknowledgements. Contrast with signing via Claude, where the human is the signer and the agent only relays the typed intent.
Mint a tier-3 token
Tier-3 means "execute, with per-action human signature on high-stakes
calls." The token's allow[] declares the verbs the agent can attempt;
required_acknowledgements[] declares the slugs the human principal
accepted at token-mint time.
curl -X POST https://api.mattermode.com/v1/tokens \
-H "Authorization: Bearer $MATTER_KEY" \
-H "Matter-Version: 2026-05-01" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"tier": "tier_3",
"principal_stakeholder_id": "stk_F0und3rCEO",
"agent_identity": {
"name": "Waypoint Compliance Bot",
"vendor": "internal",
"version": "2026.04"
},
"allow": [
"documents.sign",
"filings.create",
"resolutions.create"
],
"scope": { "entity_id": "ent_Nq3KcAbc" },
"required_acknowledgements": [
"agent_action_binds_principal",
"not_legal_advice"
],
"limits": {
"max_spend_per_call": { "amount": 50000, "currency": "usd" },
"requires_human_signature": ["documents.sign", "filings.create"]
}
}'If the token's allow[] includes entities.submit (i.e. the agent can
file a Certificate of Incorporation), Matter additionally requires the
incorporator_signature_authorized slug at token-mint time. This is the
one-time consent that the agent may sign as the named incorporator.
Matter itself is never the named incorporator; the founder is, and they
pre-delegate that signing authority to the agent through this slug.
Acknowledgement gate
A first attempt at a mutation fails with 422 acknowledgement_required
when slugs beyond the token's mint-time floor are missing.
{
"type": "https://api.mattermode.com/problems/acknowledgement_required",
"title": "Acknowledgement required",
"status": 422,
"detail": "One or more acknowledgements must be captured from the principal before this call can proceed.",
"missing_acknowledgements": [
{
"slug": "late_filing_penalty_accepted",
"reason": "Annual reports filed after March 1 incur a $200 Delaware penalty plus 1.5% interest per month."
}
],
"request_id": "req_8K2nPzWq"
}Fetch the canonical plain-English text:
curl https://api.mattermode.com/v1/acknowledgements?slug=late_filing_penalty_accepted \
-H "Authorization: Bearer $MATTER_KEY" \
-H "Matter-Version: 2026-05-01"Render the body in your UI or chat, capture the click, then retry the
original call with the same Idempotency-Key and the captured slugs in
acknowledgements[].
What happens next depends on requires_human_signature in the token's
policy:
- Low-stakes (call not on the list) →
200 OK, the mutation lands. - High-stakes (call on the list) →
202 Acceptedwith a pendingAuthorizationresource and asignature_url.
High-stakes Authorization
High-stakes responses include an Authorization with a
signature_url:
{
"id": "flg_q4ZrT9Lp",
"status": "pending_authorization",
"authorization": {
"id": "auth_8mY3pQrL",
"status": "pending",
"principal_stakeholder_id": "stk_F0und3rCEO",
"agent_token_id": "tok_3aFv7mYpQ2",
"signature_url": "https://sign.mattermode.com/a/auth_8mY3pQrL/c_5pKf2nBw",
"expires_at": "2026-05-03T14:02:11Z",
"what_will_happen_if_approved": [
"File the 2025 Delaware Annual Report on behalf of ent_Nq3KcAbc.",
"Pay $200 in late penalty plus accrued interest from the entity's billing source.",
"Apply Waypoint Compliance Bot's electronic-agent signature under UETA §14."
]
}
}Two ways to approve. Hosted signature URL — send the human to
authorization.signature_url; they approve via a Matter-hosted page.
Headless approval — submit programmatically with a signature_token
minted from POST /v1/signing_sessions:
curl -X POST https://api.mattermode.com/v1/authorizations/auth_8mY3pQrL/approve \
-H "Authorization: Bearer sig_5pKf2nBw…" \
-H "Matter-Version: 2026-05-01" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"intent_text": "Jane Smith approves",
"signing_session_id": "sigsess_4Vy7nPq2"
}'Once the auth flips to approved, the cascade resumes. The agent's
signature is applied to any underlying document at the moment of dispatch.
What lands on the document
For any document signed during the cascade, Document.signatures[]
carries an agent_authority block instead of a consent record:
{
"signatures": [
{
"stakeholder_id": null,
"agent_token_id": "tok_3aFv7mYpQ2",
"signed_at": "2026-04-26T15:21:42Z",
"legal_basis": "ueta_electronic_agent",
"method": "agent_with_authorization",
"intent_text": null,
"consent_record": null,
"agent_authority": {
"principal_stakeholder_id": "stk_F0und3rCEO",
"agent_identity": {
"name": "Waypoint Compliance Bot",
"vendor": "internal",
"version": "2026.04"
},
"tier": "tier_3",
"authorization_id": "auth_8mY3pQrL",
"acknowledgements_at_signing": [
{ "slug": "agent_action_binds_principal", "version": "ack-2026-01" },
{ "slug": "not_legal_advice", "version": "ack-2026-01" },
{ "slug": "late_filing_penalty_accepted", "version": "ack-2026-01" }
]
}
}
]
}legal_basis is ueta_electronic_agent — the signature was applied by
an agent acting under UETA §14, with the principal having pre-authorised
the agent's authority and counter-signed the high-stakes call.
intent_text and consent_record are null — those fields belong to
the human-signer rail.
Failure modes
| Code | What happened | Recovery |
|---|---|---|
422 acknowledgement_required | One or more slugs missing from acknowledgements[]. | Fetch slugs from GET /v1/acknowledgements, present to the human, capture, retry with same Idempotency-Key. |
403 human_signature_required | Token attempted a call on requires_human_signature[] but the response was treated as final. | Soft 403 paired with the Authorization resource — follow the signature_url or call POST /v1/authorizations/{id}/approve. |
403 tier_insufficient | Token is tier-2 (prepare-only) or tier-1 (observe). | Re-issue the token at tier-3 with the relevant allow[] verbs. |
408 Request Timeout after authorization.created | Human didn't approve within the auth's expires_at. | The auth flips to expired. Re-fire the original call with a new Idempotency-Key. |
409 Conflict acknowledgement_version_stale | The principal accepted version ack-2026-01 but Matter has since published ack-2026-02. | Re-fetch the acknowledgement, re-present, re-capture, retry. Old versions are not honoured. |
Tier-3 vs tier-4
| Behaviour | Tier 3 (this recipe) | Tier 4 |
|---|---|---|
| Per-action human countersign | Required for requires_human_signature[] calls. | Not required during the standing window. |
| Standing authorisation | None — every call evaluates against the live token policy. | Yes, captured up front via tier_4_standing_authority_acknowledged. |
| Acknowledgement floor | Slugs declared at mint time. | Same, plus the standing-authority slug. |
Document legal_basis | ueta_electronic_agent. | ueta_electronic_agent. |
| Authority block | Includes authorization_id. | Includes standing_authorization_id. |
Tier-4 is for narrow, recurring tasks (annual filings, BOI updates,
scheduled franchise tax). It is not available for entities.submit,
entities.dissolve, or any corporate_transactions.* verb under any
policy.