API · Conventions
Acknowledgements
Per-action informed acknowledgements that bind a natural-person stakeholder to the consequences of a specific binding mutation.
Last updated
TL;DR
Every binding mutation declares the acknowledgements it requires. Each
acknowledgement is an affirmative click bound to a natural-person
stakeholder, captured with timestamp, IP, and user-agent. Acks expire
after 90 days. Fetch the canonical text from
GET /v1/acknowledgements. Two slugs (not_legal_advice,
not_tax_advice) accept account-level standing acceptance via
POST /v1/acknowledgements/accept; the other ten require per-action
capture.
After reading this page you'll know the full slug catalog, how to
satisfy a 422 acknowledgement_required error, where to post standing
account-level acks, and how the docs renderer surfaces required acks
inline next to each operation.
What an acknowledgement is
An acknowledgement is a stakeholder's affirmative, informed acceptance of a specific consequence of a specific action. It is not:
- A generic ToS click. The Terms of Service are accepted once at account creation; per-action acks are downstream of that.
- A waiver of liability. Matter does not absolve the customer of any liability — the ack is the customer's positive statement that they understand what they are about to do.
- A substitute for legal advice. Acks reinforce that Matter is a software platform, not a law firm.
Each ack is a structured record:
{
"slug": "formation_is_legally_binding",
"version": "2026-04-01",
"accepted_by_stakeholder_id": "stk_7Hpx9WxY",
"accepted_at": 1745539200,
"ip": "203.0.113.42",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_4) AppleWebKit/605.1.15"
}accepted_by_stakeholder_id must resolve to a natural-person Stakeholder
on the target entity (or, for token-creation acks, on the account). An
agent identity (agt_…) is never a valid value here. Acks are about
human consent.
The slug catalog
The AcknowledgementSlug enum has exactly twelve values. New slugs are
added via the API versioning process — they cannot appear silently.
| Slug | Purpose | Capture |
|---|---|---|
not_legal_advice | Confirms Matter is not the customer's law firm. | Standing or per-action. |
not_tax_advice | Confirms Matter is not the customer's tax advisor. | Standing or per-action. |
agent_action_binds_principal | Captured at token creation. The principal accepts that actions taken by the token are their actions. | Per-action (token creation). |
tier_4_standing_authority_acknowledged | Captured at token creation when tier: 4. Acknowledges the autonomous surface within limits. | Per-action (token creation). |
incorporator_signature_authorized | The standing UETA §14 ack at token creation when the token's allow[] permits entities.submit. Authorises the agent to act as the founder's electronic agent on formation submission. | Per-action (token creation). |
formation_is_legally_binding | Per-action ack on POST /v1/entities/{id}/submit. The signer affirms they understand the entity will exist after this call. | Per-action. |
formation_creates_tax_obligations | Per-action ack on POST /v1/entities/{id}/submit. The signer affirms they understand the entity will incur federal and state tax obligations from the moment of registration. | Per-action. |
83b_election_strict_30_day_deadline | Per-action ack on POST /v1/grants for restricted-stock grants. The signer affirms they understand the IRS 30-day window for §83(b) election is statutory and unextendable. | Per-action. |
equity_grant_is_securities_issuance | Per-action ack on POST /v1/grants. The signer affirms they understand the grant is a securities issuance subject to federal and state securities law. | Per-action. |
dissolution_is_irreversible | Per-action ack on POST /v1/entities/{id}/dissolve. The signer affirms the entity cannot be revived by API after dissolution. | Per-action. Hard-floor HITL — see legal basis. |
service_of_process_must_reach_human | Per-action ack on POST /v1/mail/{id}/acknowledge for service_of_process mail. The signer affirms a human will receive and act on the document. | Per-action. Hard-floor HITL. |
late_filing_penalty_accepted | Per-action ack when a filing is submitted past its deadline. The signer affirms they accept any state-imposed penalty. | Per-action. |
How operations declare requirements
Every binding operation in apps/docs/api-reference/openapi.yaml declares
the acknowledgements it requires via the x-matter-required-acknowledgements
extension:
paths:
/entities/{id}/submit:
post:
x-matter-required-acknowledgements:
- slug: formation_is_legally_binding
standing_via_token: incorporator_signature_authorized
- slug: formation_creates_tax_obligations
standing_via_token: incorporator_signature_authorized
- slug: not_legal_advice
standing_via_token: not_legal_advice
- slug: not_tax_advice
standing_via_token: not_tax_adviceThe standing_via_token field names the token-level ack that satisfies
the per-action requirement when the call comes from a Rail 2 agent. If
the call comes from a Rail 1 human session, the per-action ack must be
captured in the request body.
The docs renderer surfaces these requirements inline — every operation page shows a "Required acknowledgements" panel above the request shape, with a click-through to the canonical text.
Request shape
Binding mutations accept an acknowledgements: Acknowledgement[] body
field:
curl -X POST https://api.mattermode.com/v1/entities/ent_Nq3KcAbc/submit \
-H "Authorization: Bearer $MATTER_KEY" \
-H "Matter-Version: 2026-05-01" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"acknowledgements": [
{
"slug": "formation_is_legally_binding",
"version": "2026-04-01",
"accepted_by_stakeholder_id": "stk_7Hpx9WxY",
"accepted_at": 1745539200,
"ip": "203.0.113.42",
"user_agent": "Mozilla/5.0…"
},
{
"slug": "formation_creates_tax_obligations",
"version": "2026-04-01",
"accepted_by_stakeholder_id": "stk_7Hpx9WxY",
"accepted_at": 1745539200,
"ip": "203.0.113.42",
"user_agent": "Mozilla/5.0…"
}
]
}'Required fields per Acknowledgement:
| Field | Type | Notes |
|---|---|---|
slug | AcknowledgementSlug | One of the twelve enum values above. |
version | string | Date-coded version (e.g. 2026-04-01). Fetch the current version from GET /v1/acknowledgements. |
accepted_by_stakeholder_id | stk_… | The natural-person stakeholder who accepted. Must resolve to a Stakeholder on the target entity (or account, for token-creation acks). |
accepted_at | unix timestamp | The moment of affirmative acceptance. |
ip | string (optional) | Client IP at acceptance. Recommended for audit. |
user_agent | string (optional) | Client user-agent at acceptance. Recommended for audit. |
If any required slug is missing, the request fails with
422 acknowledgement_required. See
the error page for
the response shape and recovery flow.
Fetching the canonical catalog
Acknowledgement text is versioned. Always fetch the current text from
GET /v1/acknowledgements rather than hardcoding it in your client:
curl https://api.mattermode.com/v1/acknowledgements \
-H "Authorization: Bearer $MATTER_KEY" \
-H "Matter-Version: 2026-05-01"{
"object": "list",
"data": [
{
"slug": "formation_is_legally_binding",
"current_version": "2026-04-01",
"title": "Formation is legally binding",
"text": "By submitting this formation, I understand and agree that…",
"text_url": "https://mattermode.com/legal/acks/formation_is_legally_binding/2026-04-01",
"audience": "natural_person",
"expires_after_days": 90,
"supersedes": ["2025-09-01"]
},
{
"slug": "not_legal_advice",
"current_version": "2026-01-01",
"title": "Matter is not a law firm",
"text": "Matter is a software platform, not a law firm…",
"text_url": "https://mattermode.com/legal/acks/not_legal_advice/2026-01-01",
"audience": "account_holder",
"expires_after_days": 90,
"supersedes": ["2025-04-01"]
}
],
"has_more": false,
"url": "/v1/acknowledgements"
}You may also query a single slug:
curl https://api.mattermode.com/v1/acknowledgements?slug=dissolution_is_irreversible \
-H "Authorization: Bearer $MATTER_KEY" \
-H "Matter-Version: 2026-05-01"The text field is plain English suitable for direct presentation to the
stakeholder. The text_url resolves to a stable, content-addressable URL
for the exact version — useful for embedding in a signing UI's iframe.
Standing account-level acceptance
Two slugs — not_legal_advice and not_tax_advice — accept standing
account-level acceptance. The account holder accepts each one once and
the acceptance applies to every subsequent binding mutation on the
account, until the version is superseded.
curl -X POST https://api.mattermode.com/v1/acknowledgements/accept \
-H "Authorization: Bearer $MATTER_KEY" \
-H "Matter-Version: 2026-05-01" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"slug": "not_legal_advice",
"version": "2026-01-01",
"accepted_by_stakeholder_id": "stk_account_owner",
"ip": "203.0.113.42",
"user_agent": "Mozilla/5.0…"
}'{
"id": "ackacc_8sQp4LbR",
"object": "acknowledgement_acceptance",
"slug": "not_legal_advice",
"version": "2026-01-01",
"accepted_by_stakeholder_id": "stk_account_owner",
"accepted_at": 1745539200,
"expires_at": 1753315200,
"scope": "account",
"livemode": true
}Only not_legal_advice and not_tax_advice are valid for standing
account-level acceptance. Every other slug requires per-action capture
because the binding stakeholder may differ from the account holder
(for example, the founder named at entity.incorporator_stakeholder_id
on a formation submission).
POST /v1/acknowledgements/accept with any other slug returns
422 invalid_request with detail: "Slug X requires per-action capture; only not_legal_advice and not_tax_advice accept standing account-level acceptance."
The 422 acknowledgement_required error
When a binding mutation is missing one or more required acks, Matter returns RFC 7807:
{
"type": "https://mattermode.com/docs/errors/acknowledgement_required",
"title": "Acknowledgement required",
"status": 422,
"detail": "This action requires acknowledgements that are missing or expired.",
"code": "acknowledgement_required",
"request_id": "req_Qw9xYz8A",
"required": [
"formation_is_legally_binding",
"formation_creates_tax_obligations"
],
"text_url": "https://mattermode.com/legal/acks/?slugs=formation_is_legally_binding,formation_creates_tax_obligations",
"disclosure_packet_url": "https://api.mattermode.com/v1/entities/ent_Nq3KcAbc/submit?dry_run=true"
}The text_url resolves to a server-rendered HTML page with the
canonical text of every missing slug, suitable for embedding in a
signing UI. The disclosure_packet_url is a dry-run URL that returns
the full DisclosurePacket — see disclaimers.
The full recovery walkthrough lives at errors/acknowledgement-required.
Versioning
Each slug carries a date-coded version (e.g. 2026-04-01). When the
canonical text changes — typically because of a regulatory change or
a clarification — Matter mints a new version and the old version is
listed in supersedes[].
| Event | Effect on existing acks |
|---|---|
| Slug version bumped | Existing per-action acks remain valid for the action they signed. New mutations require the new version. Standing acks at the prior version are invalidated; the account holder must re-accept. |
| ToS supersession | All open standing acks are invalidated. Per-action acks already on file (already attached to a written audit entry) remain valid. |
| Slug retired | Listed as retired: true in GET /v1/acknowledgements. New mutations no longer require it. Past acks remain on file for audit. |
| Slug added | Annotated as since: <api_version>. Tokens pinned to a prior api_version are not yet subject to the new requirement; tokens pinned to or above since are. |
The acknowledgement layer is a hot path. Implementations should cache
the catalog with a short TTL (5 minutes is conservative) and re-fetch
on 422 acknowledgement_required rather than on a fixed schedule.
Expiry
Per-action acks have a 90-day expiry from accepted_at. After 90 days,
the same ack is no longer valid for a new mutation — the stakeholder
must re-acknowledge.
The 90-day window applies to future mutations. An ack already
written into an AuditEntry for a completed action remains valid as
audit evidence indefinitely. Expiry only governs whether the ack can
be re-presented as authorisation for a new action.
Standing account-level acks (not_legal_advice, not_tax_advice)
also expire after 90 days. The account holder must re-accept on the
next binding mutation after expiry.
Code example — recovering from a 422
The canonical client flow on acknowledgement_required:
import { MatterClient, MatterError } from "@mattermode/node";
async function submitWithAcks(matter: MatterClient, entityId: string, signerId: string) {
try {
return await matter.entities.submit(entityId, {
idempotencyKey: crypto.randomUUID(),
});
} catch (err) {
if (!(err instanceof MatterError) || err.code !== "acknowledgement_required") {
throw err;
}
// 1. Fetch canonical text for each missing slug.
const catalog = await matter.acknowledgements.list({ slug: err.required });
// 2. Present each to the natural-person stakeholder. Capture affirmative
// click on every slug. (Pseudo-code for your UI.)
const accepted = await ui.presentAndCapture(catalog.data, signerId);
// 3. Retry with the same Idempotency-Key would 409 — the body changed.
// Mint a fresh key and resend with acknowledgements[] populated.
return await matter.entities.submit(entityId, {
idempotencyKey: crypto.randomUUID(),
acknowledgements: accepted,
});
}
}Related
- Legal basis — how acknowledgements satisfy UETA §14 on Rail 2 agent signatures.
- Disclaimers — the disclaimer envelope on every binding response and the DisclosurePacket on dry-run.
- acknowledgement_required error — full 422 recovery walkthrough with cURL.
- Errors — the RFC 7807 envelope used by every Matter error.