API reference
Every endpoint on the Mandate Labs platform — onboarding through authorization — with the auth it needs, its parameters, and a real request/response pair. All requests are HTTPS and exchange JSON.
Introduction
The Mandate Labs API is organized around the object hierarchy Client → Program → Principal → Agent → Mandate → Authorization. If you haven't yet, read Core concepts for how those objects nest and why.
All endpoints share a single base URL and are versioned under /api/v1:
https://api.mandatelabs.ai/api/v1
Requests and responses are application/json. Monetary amounts are strings or numbers in the minor-unit-free decimal form (e.g. "42.99"); IDs are prefixed by object type (cli_, prg_, prn_, agt_, mnd_, auth_). Errors use a uniform envelope — see Errors & idempotency.
The platform has three distinct authentication contexts: the Client key drives onboarding, the Principal key drives the live agent/authorization endpoints, and the Admin key provisions Clients. Each endpoint below notes which one it expects.
Authentication
Mandate Labs uses three credential types. Which one an endpoint accepts depends on the plane it belongs to.
Client API key onboarding
Pass a Client key in the X-API-Key header. Client keys are issued by Mandate Labs when your organization is provisioned (or via the Admin API) and authenticate the onboarding endpoints — everything that creates Principals, Agents, and Mandates on behalf of your tenant.
X-API-Key: mdt_live_… # live X-API-Key: mdt_test_… # sandbox
Principal API key runtime
Also passed as X-API-Key, a Principal key authenticates the runtime endpoints — /authorize, /agents, /mandates, /webhooks, and /thresholds. Every read and write on these planes is scoped (tenant-isolated) to the authenticated Principal. In the sandbox playground, a per-Principal sandbox key is minted for you (see Onboarding).
Provisioning
Client provisioning and credential lifecycle are performed by Mandate Labs using an internal operator key. Those endpoints are not part of the public API — your Client and its API key are issued to you during onboarding (book a call).
OAuth2 client-credentials is also supported for Client authentication — present the issued bearer token as Authorization: Bearer … instead of X-API-Key. The environment is implied by the key prefix: mdt_live_ is live, mdt_test_ is sandbox. Sandbox keys behave identically but never touch real rails.
Onboarding
Client-authenticated endpoints that build your tenant graph. The core invariant: a Principal is one stable prn_ that owns many Agents — create the Principal once, then add agents to it. All create endpoints accept an Idempotency-Key header (see idempotency).
Create a full onboarding bundle
/api/v1/onboardAtomically creates a Principal, its first Agent, and a Mandate in one call. Client key Ideal for quickstart and sandbox; use the decoupled endpoints below to add more agents later. Returns 201 (or 202 when the Principal needs platform verification).
| Body param | Type | Req | Notes |
|---|---|---|---|
principal | object | yes | A full Principal registration object (see Register a Principal). |
agent | object | yes | name (required), plus optional capabilities, program_id, external_agent_ref, metadata. |
mandate | object | yes | rails + limits (see Create a Mandate). |
curl -X POST https://api.mandatelabs.ai/api/v1/onboard \ -H "X-API-Key: mdt_live_…" -H "Content-Type: application/json" \ -d '{ "principal": { "principal_kind": "merchant", "program_ids": ["prg_…"], "client_customer_ref": "acme-001", "profile": { "display_name": "Acme Corp", "email": "[email protected]", "country": "US" }, "verification": { "type": "KYB", "mode": "client_attested", "attestation": { "attested_by": "[email protected]", "scope": "Tier-2 CDD", "statement": "Acme performed CDD on this merchant", "evidence_ref": "case-123" } } }, "agent": { "name": "Shopping Assistant v1", "capabilities": ["payments.authorize"] }, "mandate": { "rails": ["card"], "limits": { "max_amount_per_transaction": 500, "max_daily_amount": 2000, "currency": "USD" } } }'
{
"principal": {
"id": "prn_…",
"client_id": "cli_…",
"principal_kind": "merchant",
"client_customer_ref": "acme-001",
"verification_status": "VERIFIED",
"verification_mode": "client_attested",
"risk_tier": "LOW",
"programs": ["prg_…"],
"agents": [],
"verification_session": null,
"created_at": "2026-06-27T18:04:11Z"
},
"agent": {
"id": "agt_…",
"principal_id": "prn_…",
"program_id": "prg_…",
"did": "did:key:z6Mk…",
"name": "Shopping Assistant v1",
"status": "ACTIVE",
"trust_level": "REGISTERED",
"kya_score": null
},
"mandate": {
"id": "mnd_…",
"agent_id": "agt_…",
"program_id": "prg_…",
"status": "ACTIVE",
"rails": ["card"],
"limits": { "max_amount_per_transaction": 500.0, "max_daily_amount": 2000.0, "currency": "USD" },
"mandate_hash": "sha256:…",
"valid_until": "2027-06-27T18:04:11Z"
}
}
Register a Principal
/api/v1/principalsRegisters a Principal under the Client and enrolls it into one or more Programs. Client key Returns 201 for client_attested (verified immediately) or 202 for platform_provider (verification pending; the response carries a verification_session).
| Body param | Type | Req | Notes |
|---|---|---|---|
principal_kind | string | yes | "personal" or "merchant". |
program_ids | string[] | yes | ≥1 Program the Client owns; the Principal is enrolled in each. |
profile | object | yes | display_name, email (required); optional phone (E.164), country. |
verification | object | yes | type (KYC/KYB), mode (client_attested/platform_provider), and attestation (required for client_attested). |
client_customer_ref | string | no | Your own reference; unique per Client. |
step_up | object | no | method (sms/email) + optional phone. |
metadata | object | no | Arbitrary key/value pairs. |
curl -X POST https://api.mandatelabs.ai/api/v1/principals \ -H "X-API-Key: mdt_live_…" -H "Content-Type: application/json" \ -d '{ "principal_kind": "merchant", "program_ids": ["prg_…"], "client_customer_ref": "acme-001", "profile": { "display_name": "Acme Corp", "email": "[email protected]", "country": "US" }, "verification": { "type": "KYB", "mode": "client_attested", "attestation": { "attested_by": "[email protected]", "scope": "Tier-2 CDD", "statement": "Acme performed CDD on this merchant", "evidence_ref": "case-123" } } }'
{
"id": "prn_…",
"client_id": "cli_…",
"principal_kind": "merchant",
"client_customer_ref": "acme-001",
"verification_status": "VERIFIED",
"verification_mode": "client_attested",
"risk_tier": "LOW",
"programs": ["prg_…"],
"agents": [],
"verification_session": null,
"created_at": "2026-06-27T18:04:11Z"
}
Get a Principal
/api/v1/principals/{principal_id}Returns the authenticated Principal's own record. Principal key A Principal can only read itself — requesting another prn_ returns 403.
curl https://api.mandatelabs.ai/api/v1/principals/prn_… \
-H "X-API-Key: mdt_live_…"
{
"id": "prn_…",
"principal_kind": "merchant",
"verification_status": "VERIFIED",
"risk_tier": "LOW",
"client_customer_ref": "acme-001"
}
Enroll a Principal into another Program
/api/v1/principals/{principal_id}/programsAdds an existing Principal to an additional Program (many-to-many). Client key Idempotent — re-enrolling is a safe no-op. Returns the full list of enrolled program IDs.
Body: program_id (string, required) — a Program the Client owns.
curl -X POST https://api.mandatelabs.ai/api/v1/principals/prn_…/programs \ -H "X-API-Key: mdt_live_…" -H "Content-Type: application/json" \ -d '{ "program_id": "prg_crypto_…" }'
{
"principal_id": "prn_…",
"programs": ["prg_…", "prg_crypto_…"]
}
Add an Agent under a Principal
/api/v1/principals/{principal_id}/agentsRegisters a new Agent under an existing Principal — call once per agent. Client key This is how you honor the one-identity-many-agents invariant. If the Principal is enrolled in exactly one Program the agent inherits it; otherwise pass program_id.
| Body param | Type | Req | Notes |
|---|---|---|---|
name | string | yes | Display name for the agent. |
program_id | string | no | Required only when the Principal is enrolled in 0 or >1 Programs. |
capabilities | string[] | no | Declared capabilities (defaults to ["PURCHASE"]). |
external_agent_ref | string | no | Your own reference for the agent. |
metadata | object | no | Arbitrary key/value pairs. |
curl -X POST https://api.mandatelabs.ai/api/v1/principals/prn_…/agents \ -H "X-API-Key: mdt_live_…" -H "Content-Type: application/json" \ -d '{ "name": "Shopping Assistant v2", "capabilities": ["payments.authorize"] }'
{
"id": "agt_…",
"principal_id": "prn_…",
"client_id": "cli_…",
"program_id": "prg_…",
"did": "did:key:z6Mk…",
"name": "Shopping Assistant v2",
"status": "ACTIVE",
"trust_level": "REGISTERED",
"kya_score": null,
"created_at": "2026-06-27T18:06:02Z"
}
List a Principal's Agents
/api/v1/principals/{principal_id}/agentsLists every Agent registered under the Principal. Client key
curl https://api.mandatelabs.ai/api/v1/principals/prn_…/agents \
-H "X-API-Key: mdt_live_…"
{
"principal_id": "prn_…",
"agents": [
{ "id": "agt_…", "name": "Shopping Assistant v1", "status": "ACTIVE", "trust_level": "VERIFIED", "kya_score": 0.81 },
{ "id": "agt_…", "name": "Shopping Assistant v2", "status": "ACTIVE", "trust_level": "REGISTERED", "kya_score": null }
],
"count": 2
}
Create a Mandate for an Agent
/api/v1/agents/{agent_id}/mandatesGrants spending authority to an Agent — card, crypto, or both. Client key When crypto is in rails, a crypto block is required.
| Body param | Type | Req | Notes |
|---|---|---|---|
rails | string[] | yes | Subset of {"card","crypto"}. |
limits | object | yes | max_amount_per_transaction, max_daily_amount (both >0), currency (ISO 4217). |
allowed_mccs | string[] | no | Allowed Merchant Category Codes. |
allowed_countries | string[] | no | Allowed ISO country codes. |
crypto | object | cond. | chains, assets, optional max_transfer. Required iff crypto ∈ rails. |
valid_until | datetime | no | Expiry; defaults to ~1 year. |
curl -X POST https://api.mandatelabs.ai/api/v1/agents/agt_…/mandates \ -H "X-API-Key: mdt_live_…" -H "Content-Type: application/json" \ -d '{ "rails": ["card"], "limits": { "max_amount_per_transaction": 500, "max_daily_amount": 2000, "currency": "USD" }, "allowed_mccs": ["5411", "5812"], "allowed_countries": ["US"] }'
{
"id": "mnd_…",
"agent_id": "agt_…",
"program_id": "prg_…",
"status": "ACTIVE",
"rails": ["card"],
"limits": { "max_amount_per_transaction": 500.0, "max_daily_amount": 2000.0, "currency": "USD" },
"mandate_hash": "sha256:…",
"valid_until": "2027-06-27T18:08:40Z",
"created_at": "2026-06-27T18:08:40Z"
}
Mint a sandbox key for a Principal
/api/v1/principals/{principal_id}/sandbox-keyMints a per-Principal sandbox API key so a freshly onboarded dev Principal can drive the runtime endpoints itself. Client key (sandbox) Playground-only — refused (403 sandbox_only) with a live credential. The key is shown once.
curl -X POST https://api.mandatelabs.ai/api/v1/principals/prn_…/sandbox-key \
-H "X-API-Key: mdt_test_…"
{
"principal_id": "prn_…",
"api_key": "mdt_test_…",
"env": "sandbox",
"message": "Sandbox key for this Principal — use as X-API-Key. Shown once."
}
Authorization
The runtime decision plane. POST /authorize is the core operation — every transaction an agent attempts is evaluated here against its mandate, velocity limits, and KYA trust score, and recorded as an immutable Authorization. Principal key
Authorize a transaction
/api/v1/authorizeEvaluates a transaction and returns a real-time APPROVE / DECLINE / STEP_UP decision with reason codes, KYA score, and a structured risk assessment. Provide at least one of agent_id or agent_did. intent_context is mandatory on every request.
| Body param | Type | Req | Notes |
|---|---|---|---|
agent_id / agent_did | string | one | Identify the agent (agt_ id or its DID). |
amount | decimal | yes | Transaction amount, >0. |
currency | string | no | ISO 4217, defaults to USD. |
mcc | string | no | 4-digit Merchant Category Code. |
merchant_name / merchant_id | string | no | Merchant display name / identifier. |
country | string | no | ISO 3166-1 alpha-3. |
intent_context | object | yes | intent_type, task_reference (required), plus optional reasoning_summary, confidence, alternatives_considered. |
rail | string | no | CARD (default) or CRYPTO; CRYPTO requires a crypto block. |
idempotency_key | string | no | 8–128 chars; prevents duplicate authorizations. |
curl -X POST https://api.mandatelabs.ai/api/v1/authorize \ -H "X-API-Key: mdt_live_…" -H "Content-Type: application/json" \ -d '{ "agent_id": "agt_…", "amount": "42.99", "currency": "USD", "merchant_name": "Whole Foods Market #1042", "mcc": "5411", "intent_context": { "intent_type": "PURCHASE", "task_reference": "weekly_grocery_purchase", "reasoning_summary": "Weekly organic produce restock; compared 3 nearby grocers", "confidence": 0.91, "alternatives_considered": 3 } }'
{
"authorization_id": "auth_…",
"decision": "APPROVE",
"reason_codes": [],
"reason_detail": "",
"agent_id": "agt_…",
"mandate_id": "mnd_…",
"kya_score": 0.87,
"trust_level": "VERIFIED",
"risk_score": 0.12,
"risk_assessment": {
"score": 0.12, "reason_codes": [], "condition_code": "00",
"velocity_indicator": false, "highest_severity": "NONE"
},
"daily_amount_used": 128.40,
"daily_count_used": 3,
"intent_context_provided": true,
"intent_anomaly_score": 0.05,
"intent_anomaly_triggered": false,
"cognitive_limit_active": false,
"cognitive_limit_multiplier": 1.0,
"processing_time_ms": 8.4
}
Get an authorization log entry
/api/v1/authorize/log/{authorization_id}Retrieves a single authorization decision from the audit log. Principal key Tenant-scoped — only the owning Principal's authorizations are visible.
curl https://api.mandatelabs.ai/api/v1/authorize/log/auth_… \
-H "X-API-Key: mdt_live_…"
{
"id": "auth_…",
"agent_id": "agt_…",
"mandate_id": "mnd_…",
"amount": 42.99,
"currency": "USD",
"mcc": "5411",
"merchant_id": null,
"country": "USA",
"decision": "APPROVE",
"reason_codes": [],
"kya_score": 0.87,
"trust_level": "VERIFIED",
"processing_time_ms": 8.4,
"created_at": "2026-06-27T18:10:55Z"
}
List an agent's authorization history
/api/v1/authorize/log/agent/{agent_id}Returns the agent's authorization history, newest first, paginated. Principal key
Query: standard pagination params (e.g. limit, cursor).
curl https://api.mandatelabs.ai/api/v1/authorize/log/agent/agt_…?limit=2 \
-H "X-API-Key: mdt_live_…"
{
"items": [
{ "id": "auth_…", "decision": "APPROVE", "amount": 42.99, "currency": "USD", "created_at": "2026-06-27T18:10:55Z" },
{ "id": "auth_…", "decision": "STEP_UP", "amount": 4800.00, "currency": "USD", "created_at": "2026-06-27T17:55:01Z" }
],
"next_cursor": "…"
}
Agents
Manage and query agents under the authenticated Principal. Principal key Note: in onboarding you add agents via /principals/{id}/agents; these endpoints operate on the runtime plane.
Register an agent
/api/v1/agentsRegisters a new agent for the authenticated Principal. Principal key If principal_id is supplied it must match the key's Principal.
| Body param | Type | Req | Notes |
|---|---|---|---|
display_name | string | yes | Agent display name. |
capabilities | string[] | yes | ≥1 of PURCHASE, SUBSCRIPTION, REFUND_REQUEST, BALANCE_INQUIRY, TRANSFER. |
did | string | no | W3C DID; a did:key is auto-generated if omitted. |
public_key_jwk + registration_proof | object / string | no | Agent key + proof of possession (required for Verifiable Intent). |
curl -X POST https://api.mandatelabs.ai/api/v1/agents \ -H "X-API-Key: mdt_live_…" -H "Content-Type: application/json" \ -d '{ "display_name": "Procurement Bot", "capabilities": ["PURCHASE"] }'
{
"id": "agt_…",
"did": "did:key:z6Mk…",
"did_method": "key",
"display_name": "Procurement Bot",
"principal_id": "prn_…",
"status": "ACTIVE",
"trust_level": "REGISTERED",
"capabilities": ["PURCHASE"],
"total_transactions": 0,
"decline_rate": 0.0,
"created_at": "2026-06-27T18:12:00Z"
}
List agents
/api/v1/agentsLists agents belonging to the authenticated Principal. Principal key
Query: status, trust_level, page (≥1), page_size (1–100).
curl "https://api.mandatelabs.ai/api/v1/agents?trust_level=VERIFIED&page_size=50" \ -H "X-API-Key: mdt_live_…"
{
"agents": [ { "id": "agt_…", "display_name": "Procurement Bot", "trust_level": "VERIFIED", "status": "ACTIVE" } ],
"total": 1,
"page": 1,
"page_size": 50
}
Get an agent
/api/v1/agents/{agent_id}Fetches a single agent (must belong to the authenticated Principal). Principal key
curl https://api.mandatelabs.ai/api/v1/agents/agt_… \
-H "X-API-Key: mdt_live_…"
{
"id": "agt_…",
"display_name": "Procurement Bot",
"trust_level": "VERIFIED",
"status": "ACTIVE",
"capabilities": ["PURCHASE"],
"total_transactions": 214,
"decline_rate": 0.03
}
Get agent metrics
/api/v1/agents/{agent_id}/metricsReturns behavioral metrics and trust-promotion status for an agent. Principal key
curl https://api.mandatelabs.ai/api/v1/agents/agt_…/metrics \
-H "X-API-Key: mdt_live_…"
{
"agent_id": "agt_…",
"trust_level": "VERIFIED",
"total_transactions": 214,
"successful_transactions": 207,
"declined_transactions": 7,
"decline_rate": 0.03,
"dispute_deflection_rate": 0.98,
"trust_promotion_eligible": true,
"next_trust_level": "TRUSTED",
"promotion_criteria": { "min_successful_txns": { "required": 200, "actual": 207, "met": true } }
}
Update agent status
/api/v1/agents/{agent_id}/statusSuspends, reactivates, or revokes an agent. Principal key
Body: status (new AgentStatus) and reason (1–500 chars), both required.
curl -X PATCH https://api.mandatelabs.ai/api/v1/agents/agt_…/status \ -H "X-API-Key: mdt_live_…" -H "Content-Type: application/json" \ -d '{ "status": "SUSPENDED", "reason": "Manual review pending" }'
{
"id": "agt_…",
"status": "SUSPENDED",
"trust_level": "VERIFIED",
"display_name": "Procurement Bot"
}
Mandates
Create and query spending mandates on the runtime plane. Principal key The agent a mandate targets must belong to the authenticated Principal.
Create a mandate
/api/v1/mandatesCreates a new spending mandate for an agent (AP2-compatible). Principal key
| Body param | Type | Req | Notes |
|---|---|---|---|
agent_id | string | yes | Target agent (owned by the Principal). |
valid_until | datetime | yes | Mandate expiry. |
max_amount_per_transaction | decimal | yes | >0, 2 decimal places. |
currency | string | no | ISO 4217, defaults to USD. |
max_daily_amount / max_monthly_amount | decimal | no | Velocity caps. |
allowed_mccs / blocked_mccs | string[] | no | MCC allow/block lists. |
allowed_countries / blocked_countries | string[] | no | Country allow/block lists. |
allowed_chains / allowed_assets / allowed_counterparties | string[] | no | Crypto-rail constraints. |
curl -X POST https://api.mandatelabs.ai/api/v1/mandates \ -H "X-API-Key: mdt_live_…" -H "Content-Type: application/json" \ -d '{ "agent_id": "agt_…", "valid_until": "2027-01-01T00:00:00Z", "max_amount_per_transaction": "500.00", "max_daily_amount": "2000.00", "currency": "USD", "allowed_mccs": ["5411", "5812"] }'
{
"id": "mnd_…",
"agent_id": "agt_…",
"principal_id": "prn_…",
"status": "ACTIVE",
"valid_from": "2026-06-27T18:14:30Z",
"valid_until": "2027-01-01T00:00:00Z",
"max_amount_per_transaction": 500.00,
"currency": "USD",
"max_daily_amount": 2000.00,
"allowed_mccs": ["5411", "5812"],
"mandate_hash": "sha256:…",
"created_at": "2026-06-27T18:14:30Z"
}
Get a mandate
/api/v1/mandates/{mandate_id}Fetches a mandate (ownership is verified through its agent). Principal key
curl https://api.mandatelabs.ai/api/v1/mandates/mnd_… \
-H "X-API-Key: mdt_live_…"
{
"id": "mnd_…",
"agent_id": "agt_…",
"status": "ACTIVE",
"max_amount_per_transaction": 500.00,
"currency": "USD",
"valid_until": "2027-01-01T00:00:00Z"
}
List an agent's mandates
/api/v1/mandates/agent/{agent_id}Lists all mandates for a given agent. Principal key
Query: status (optional MandateStatus filter).
curl https://api.mandatelabs.ai/api/v1/mandates/agent/agt_… \
-H "X-API-Key: mdt_live_…"
{
"mandates": [ { "id": "mnd_…", "status": "ACTIVE", "max_amount_per_transaction": 500.00, "currency": "USD" } ],
"total": 1
}
Webhooks
Register HTTPS endpoints to receive real-time events. Principal key Webhook URLs must be public HTTPS endpoints; the signing secret (used to verify X-Mandate-Signature) is returned once on create. See the Webhooks guide for payloads and signature verification.
Register a webhook
/api/v1/webhooksCreates a webhook subscription and returns its signing secret (shown only once). Principal key
| Body param | Type | Req | Notes |
|---|---|---|---|
url | string | yes | Public HTTPS endpoint (≤2048 chars). |
event_types | string[] | yes | ≥1 of gate.fired, kya.zone.red, kya.zone.critical, session.terminate, authorization.decline, trust.promotion, step_up.created, *. |
description | string | no | ≤255 chars. |
curl -X POST https://api.mandatelabs.ai/api/v1/webhooks \ -H "X-API-Key: mdt_live_…" -H "Content-Type: application/json" \ -d '{ "url": "https://your-app.com/webhooks/mandate-ai", "event_types": ["gate.fired", "authorization.decline", "trust.promotion"], "description": "Production alerting webhook" }'
{
"webhook": {
"id": "wh_…",
"url": "https://your-app.com/webhooks/mandate-ai",
"event_types": ["gate.fired", "authorization.decline", "trust.promotion"],
"active": true,
"consecutive_failures": 0,
"created_at": "2026-06-27T18:16:10Z"
},
"signing_secret": "whsec_…"
}
List webhooks
/api/v1/webhooksLists all webhooks for the authenticated Principal (paginated). Principal key
curl https://api.mandatelabs.ai/api/v1/webhooks \
-H "X-API-Key: mdt_live_…"
{
"items": [ { "id": "wh_…", "url": "https://your-app.com/webhooks/mandate-ai", "active": true, "last_status_code": 200 } ],
"next_cursor": null
}
Get a webhook
/api/v1/webhooks/{webhook_id}Fetches a single webhook by ID. Principal key
curl https://api.mandatelabs.ai/api/v1/webhooks/wh_… \
-H "X-API-Key: mdt_live_…"
{
"id": "wh_…",
"url": "https://your-app.com/webhooks/mandate-ai",
"event_types": ["gate.fired", "authorization.decline"],
"active": true,
"last_delivery_at": "2026-06-27T18:15:00Z",
"last_status_code": 200,
"consecutive_failures": 0
}
Update a webhook
/api/v1/webhooks/{webhook_id}Updates a webhook's URL, events, active flag, or description. Principal key Re-enabling (active: true) resets the failure counter.
Body (all optional): url, event_types, active, description.
curl -X PATCH https://api.mandatelabs.ai/api/v1/webhooks/wh_… \ -H "X-API-Key: mdt_live_…" -H "Content-Type: application/json" \ -d '{ "event_types": ["*"], "active": true }'
{
"id": "wh_…",
"url": "https://your-app.com/webhooks/mandate-ai",
"event_types": ["*"],
"active": true,
"consecutive_failures": 0
}
Send a test event
/api/v1/webhooks/{webhook_id}/testDispatches a realistic sample payload to the webhook so you can verify your handler. Principal key The payload includes "test": true. The webhook must be active.
Query: event_type (defaults to gate.fired).
curl -X POST "https://api.mandatelabs.ai/api/v1/webhooks/wh_…/test?event_type=authorization.decline" \ -H "X-API-Key: mdt_live_…"
{
"status": "sent",
"event_type": "authorization.decline",
"message": "Test 'authorization.decline' event dispatched to https://your-app.com/webhooks/mandate-ai."
}
Delete a webhook
/api/v1/webhooks/{webhook_id}Permanently deletes a webhook. Principal key Returns 204 No Content.
curl -X DELETE https://api.mandatelabs.ai/api/v1/webhooks/wh_… \ -H "X-API-Key: mdt_live_…" # → 204 No Content
List webhook events
/api/v1/webhooks/eventsReturns every available event type with a description and a sample payload — use it to build and test your handler. No auth required
curl https://api.mandatelabs.ai/api/v1/webhooks/events
{
"event_types": [
{
"type": "gate.fired",
"description": "Intent Anomaly Gate triggered — suspicious behavioral shift detected in agent session.",
"sample_payload": { "agent_id": "agent_sample_01", "decision": "STEP_UP", "anomaly_score": 0.62 }
}
],
"wildcard": "Use '*' when registering to receive all event types."
}
Thresholds
Tune your own gate, risk, and trust-promotion thresholds. Principal key Reads return the fully-resolved values (your overrides merged over the platform defaults). Updates are validated for logical consistency (e.g. trust zones must stay ordered green > amber > red).
Get resolved thresholds
/api/v1/thresholdsReturns effective thresholds along with which fields you've customized vs. defaults. Principal key
curl https://api.mandatelabs.ai/api/v1/thresholds \
-H "X-API-Key: mdt_live_…"
{
"thresholds": { "authorize_step_up_threshold": 0.6, "cts_green_threshold": 0.8, "risk_score_hard_decline": 0.85 },
"overrides": { "authorize_step_up_threshold": 0.6 },
"platform_defaults": { "authorize_step_up_threshold": 0.5, "cts_green_threshold": 0.8 }
}
Update thresholds
/api/v1/thresholdsSets issuer-specific overrides — include only the fields you want to change; set a field to null to revert it to default. Principal key Validates cross-field consistency.
Body: any subset of threshold fields, e.g. authorize_step_up_threshold, cts_green_threshold, risk_score_hard_decline, verified_min_successful_txns.
curl -X PUT https://api.mandatelabs.ai/api/v1/thresholds \ -H "X-API-Key: mdt_live_…" -H "Content-Type: application/json" \ -d '{ "authorize_step_up_threshold": 0.6, "risk_score_hard_decline": 0.9 }'
{
"status": "updated",
"fields_changed": ["authorize_step_up_threshold", "risk_score_hard_decline"],
"effective_thresholds": { "authorize_step_up_threshold": 0.6, "risk_score_hard_decline": 0.9 }
}
Reset thresholds
/api/v1/thresholdsDeletes all your overrides, reverting every threshold to the platform default. Principal key
curl -X DELETE https://api.mandatelabs.ai/api/v1/thresholds \
-H "X-API-Key: mdt_live_…"
{
"status": "reset",
"message": "All thresholds reverted to platform defaults"
}