Download OpenAPI specification:Download
Neutral, trustworthy infrastructure for verifiable delegated authority between humans and AI agents.
Lists onboarding access requests. Supports optional status filtering (PENDING, APPROVED, REJECTED) and cursor-based pagination. Requires Cognito JWT with mandaitor-admins group membership.
| status | string Enum: "PENDING" "APPROVED" "REJECTED" Filter by request status |
| limit | integer [ 1 .. 200 ] Default: 50 |
| cursor | string Base64url-encoded pagination cursor |
{- "requests": [
- {
- "request_id": "string",
- "company_name": "string",
- "contact_name": "string",
- "contact_email": "user@example.com",
- "use_case": "string",
- "industry": "construction",
- "lead_source": "string",
- "beta_track": "string",
- "asset": "string",
- "status": "PENDING",
- "submitted_at": "2019-08-24T14:15:22Z",
- "reviewed_at": "2019-08-24T14:15:22Z",
- "reviewed_by": "string",
- "tenant_id": "string"
}
], - "next_cursor": "string"
}Processes an admin action on an onboarding request.
Supported values for {action}: approve, reject.
| requestId required | string |
| action required | string Enum: "approve" "reject" |
| notes | string |
{- "notes": "string"
}{- "tenant_id": "string",
- "company_name": "string",
- "plan": "string",
- "status": "ACTIVE",
- "created_at": "2019-08-24T14:15:22Z",
- "api_keys": [
- {
- "key_id": "string",
- "name": "string",
- "scopes": [
- "string"
], - "created_at": "2019-08-24T14:15:22Z"
}
]
}Returns a single tenant's config, linked onboarding metadata, API key count, and mandate status counts (capped at the first 600 mandates).
Requires Cognito JWT with mandaitor-admins group membership.
| id required | string Example: tnt_ABC123 |
{- "tenant_id": "string",
- "display_name": "string",
- "contact_name": "string",
- "contact_email": "string",
- "status": "ACTIVE",
- "created_at": "2019-08-24T14:15:22Z",
- "usage_plan": {
- "tier": "standard",
- "rate_limit": 0,
- "quota_limit": 0,
- "quota_period": "string"
}, - "api_key_count": 0,
- "mandate_stats": {
- "total": 0,
- "active": 0,
- "suspended": 0,
- "revoked": 0,
- "expired": 0,
- "draft": 0
}, - "onboarding": {
- "request_id": "string",
- "use_case": "string",
- "website": "string",
- "submitted_at": "2019-08-24T14:15:22Z",
- "reviewed_at": "2019-08-24T14:15:22Z",
- "reviewed_by": "string"
}
}EMERGENCY OPERATION — Stops what a tenant's agents may do and revokes its ACTIVE, SUSPENDED and PENDING_APPROVAL mandates. This is an irreversible bulk operation intended for security incidents, compliance breaches, or contract terminations.
It takes effect on the execution path before it answers: every tool
the tenant has enabled is disabled, so from then on no execution is
created, approved or dispatched, and the MCP server lists no tool.
The tenant enables its tools again, one by one, once the incident is
over; the execution lists them as tools_disabled. While it runs, a
request-bound decision is DENY with KILL_SWITCH, and an
authorization given before it is not redeemed.
The rest runs asynchronously. The call records an execution, queues
it and returns 202 Accepted with an execution_id. A worker then
stops the tenant's executions waiting for an approval or for their
dispatch, each DENIED with KILL_SWITCH (one already dispatched
finishes: nothing recalls it), and revokes the mandates page by
page, checkpointing its progress on the execution, which
GET /admin/tenants/{id}/kill-switch/{executionId} reports until the
status is COMPLETED or FAILED. Executions for one tenant run one
at a time; calling again while one is running queues a second
execution that finds nothing left to stop.
Requires Cognito JWT with mandaitor-admins group membership. A
MANDATE_REVOKED audit event is emitted per mandate with
details.kill_switch_triggered = true and details.execution_id,
and an EXECUTION_DENIED event per execution stopped, with
details.stage = kill_switch and details.kill_switch_execution_id.
| id required | string Example: tnt_ABC123 |
| reason required | string <= 1000 characters Mandatory reason for the emergency kill-switch |
{- "reason": "Security incident — unauthorized access detected"
}{- "tenant_id": "string",
- "execution_id": "ks_01HXYZ...",
- "status": "QUEUED",
- "status_path": "/admin/tenants/tnt_ABC123/kill-switch/ks_01HXYZ...",
- "requested_at": "2019-08-24T14:15:22Z",
- "requested_by": "string"
}The twenty most recent kill-switch executions for the tenant, newest
first, with their status and counts. Requires Cognito JWT with
mandaitor-admins group membership.
| id required | string Example: tnt_ABC123 |
{- "tenant_id": "string",
- "executions": [
- {
- "execution_id": "string",
- "tenant_id": "string",
- "status": "QUEUED",
- "reason": "string",
- "requested_by": "string",
- "requested_at": "2019-08-24T14:15:22Z",
- "started_at": "2019-08-24T14:15:22Z",
- "finished_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "phase": "TOOLS",
- "tools_disabled": [
- {
- "tool_id": "string",
- "version": 1,
- "environment": "qas",
- "connector_id": "string"
}
], - "executions_cancelled": 0,
- "executions_in_flight": 0,
- "executions_busy": 0,
- "executions_failed": 0,
- "revoked_count": 0,
- "skipped_count": 0,
- "failed_count": 0,
- "audit_event_failures": 0,
- "pages_processed": 0,
- "continuations": 0,
- "attempts": 0,
- "last_error": "string"
}
]
}Progress of one kill-switch execution: status, how many mandates were
revoked, skipped or failed so far, and the last error if any. Poll
this after a 202 until status is COMPLETED or FAILED.
Requires Cognito JWT with mandaitor-admins group membership.
| id required | string Example: tnt_ABC123 |
| executionId required | string Example: ks_01HXYZ... |
{- "execution_id": "string",
- "tenant_id": "string",
- "status": "QUEUED",
- "reason": "string",
- "requested_by": "string",
- "requested_at": "2019-08-24T14:15:22Z",
- "started_at": "2019-08-24T14:15:22Z",
- "finished_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "phase": "TOOLS",
- "tools_disabled": [
- {
- "tool_id": "string",
- "version": 1,
- "environment": "qas",
- "connector_id": "string"
}
], - "executions_cancelled": 0,
- "executions_in_flight": 0,
- "executions_busy": 0,
- "executions_failed": 0,
- "revoked_count": 0,
- "skipped_count": 0,
- "failed_count": 0,
- "audit_event_failures": 0,
- "pages_processed": 0,
- "continuations": 0,
- "attempts": 0,
- "last_error": "string"
}Returns the current system mode (growth, sustain, maintenance, frozen)
and associated metadata. Requires Cognito JWT with mandaitor-admins
group membership.
{- "mode": "growth",
- "reason": "Default operational mode",
- "changed_at": "2019-08-24T14:15:22Z",
- "changed_by": "string",
- "estimated_duration_minutes": 0
}Changes the system operational mode. This immediately affects all API endpoints:
Mode changes propagate within ~10 seconds via in-memory cache TTL.
Requires Cognito JWT with mandaitor-admins group membership.
| mode required | string Enum: "growth" "sustain" "maintenance" "frozen" |
| reason | string |
| estimated_duration_minutes | integer |
{- "mode": "maintenance",
- "reason": "CDK stack update — estimated 30 minutes",
- "estimated_duration_minutes": 30
}{- "mode": "growth",
- "reason": "Default operational mode",
- "changed_at": "2019-08-24T14:15:22Z",
- "changed_by": "string",
- "estimated_duration_minutes": 0
}Proxies authentication requests to Cognito from the browser, bypassing
the ESC Cognito IDP endpoint DNS resolution issue. The {action}
path parameter determines the operation:
InitiateAuth with USER_PASSWORD_AUTHRespondToAuthChallenge (NEW_PASSWORD_REQUIRED, MFA)REFRESH_TOKEN_AUTHGlobalSignOutForgotPasswordConfirmForgotPassword| action required | string Enum: "login" "respond" "refresh" "sign-out" "forgot-password" "confirm-forgot-password" |
Request body varies by action:
{ email, password }{ challengeName, session, responses }{ refreshToken }{ accessToken }{ email }{ email, code, newPassword }{ }{ }Admin-only, dry-run-first Customer inventory. Every mapped Customer is
retrieved read-only and checked against the exact Mandaitor product,
stage, and opaque owner metadata. The default request never writes.
{ "apply": true } creates Customers only for unmapped tenants and is
rejected unless BILLING_CUSTOMER_SYNC_APPLY_ENABLED=true. It never
creates subscriptions and is not scheduled automatically.
| apply | boolean Default: false Request gated Customer creation for unmapped tenants |
{- "apply": false
}{- "mode": "dry_run",
- "scanned": 0,
- "verified_owned": 0,
- "legacy_mapping_requires_review": 0,
- "missing_customer": 0,
- "deleted_customer": 0,
- "metadata_mismatch": 0,
- "remote_lookup_failed": 0,
- "created": 0,
- "failed": 0
}| agent_id required | string |
| display_name required | string |
| tagline required | string <= 120 characters |
| description required | string |
| logo_url | string <uri> |
| docs_url | string <uri> |
required | Array of objects (CapabilityDeclaration) non-empty |
required | object (PricingInfo) |
| tags | Array of strings |
| supported_regions | Array of strings |
| certifications | Array of strings |
{- "agent_id": "string",
- "display_name": "string",
- "tagline": "string",
- "description": "string",
- "capabilities": [
- {
- "capability_id": "string",
- "name": "string",
- "description": "string",
- "category": "DOCUMENT_PROCESSING",
- "required_scopes": [
- "string"
], - "input_schema": { },
- "output_schema": { },
- "avg_execution_ms": 0,
- "max_execution_ms": 0
}
], - "pricing": {
- "model": "FREE",
- "unit_price": 0,
- "currency": "string",
- "free_tier_limit": 0,
- "custom_description": "string"
}, - "tags": [
- "string"
], - "supported_regions": [
- "string"
], - "certifications": [
- "string"
]
}{- "listing_id": "string",
- "agent_id": "string",
- "owner_tenant_id": "string",
- "status": "DRAFT",
- "display_name": "string",
- "tagline": "string",
- "description": "string",
- "capabilities": [
- {
- "capability_id": "string",
- "name": "string",
- "description": "string",
- "category": "DOCUMENT_PROCESSING",
- "required_scopes": [
- "string"
], - "input_schema": { },
- "output_schema": { },
- "avg_execution_ms": 0,
- "max_execution_ms": 0
}
], - "pricing": {
- "model": "FREE",
- "unit_price": 0,
- "currency": "string",
- "free_tier_limit": 0,
- "custom_description": "string"
}, - "trust_metrics": {
- "trust_score": 1,
- "avg_rating": 1,
- "review_count": 0,
- "total_invocations": 0,
- "success_rate": 1,
- "avg_response_ms": 0,
- "drift_score": 1,
- "uptime": 1,
- "computed_at": "2019-08-24T14:15:22Z"
}, - "tags": [
- "string"
], - "supported_regions": [
- "string"
], - "certifications": [
- "string"
], - "version": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "published_at": "2019-08-24T14:15:22Z"
}| cursor | string |
| limit | integer [ 1 .. 50 ] Default: 20 |
{- "items": [
- {
- "listing_id": "string",
- "agent_id": "string",
- "owner_tenant_id": "string",
- "status": "DRAFT",
- "display_name": "string",
- "tagline": "string",
- "description": "string",
- "capabilities": [
- {
- "capability_id": "string",
- "name": "string",
- "description": "string",
- "category": "DOCUMENT_PROCESSING",
- "required_scopes": [
- "string"
], - "input_schema": { },
- "output_schema": { },
- "avg_execution_ms": 0,
- "max_execution_ms": 0
}
], - "pricing": {
- "model": "FREE",
- "unit_price": 0,
- "currency": "string",
- "free_tier_limit": 0,
- "custom_description": "string"
}, - "trust_metrics": {
- "trust_score": 1,
- "avg_rating": 1,
- "review_count": 0,
- "total_invocations": 0,
- "success_rate": 1,
- "avg_response_ms": 0,
- "drift_score": 1,
- "uptime": 1,
- "computed_at": "2019-08-24T14:15:22Z"
}, - "tags": [
- "string"
], - "supported_regions": [
- "string"
], - "certifications": [
- "string"
], - "version": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "published_at": "2019-08-24T14:15:22Z"
}
], - "next_cursor": "string",
- "total_count": 0
}{- "listing_id": "string",
- "agent_id": "string",
- "owner_tenant_id": "string",
- "status": "DRAFT",
- "display_name": "string",
- "tagline": "string",
- "description": "string",
- "capabilities": [
- {
- "capability_id": "string",
- "name": "string",
- "description": "string",
- "category": "DOCUMENT_PROCESSING",
- "required_scopes": [
- "string"
], - "input_schema": { },
- "output_schema": { },
- "avg_execution_ms": 0,
- "max_execution_ms": 0
}
], - "pricing": {
- "model": "FREE",
- "unit_price": 0,
- "currency": "string",
- "free_tier_limit": 0,
- "custom_description": "string"
}, - "trust_metrics": {
- "trust_score": 1,
- "avg_rating": 1,
- "review_count": 0,
- "total_invocations": 0,
- "success_rate": 1,
- "avg_response_ms": 0,
- "drift_score": 1,
- "uptime": 1,
- "computed_at": "2019-08-24T14:15:22Z"
}, - "tags": [
- "string"
], - "supported_regions": [
- "string"
], - "certifications": [
- "string"
], - "version": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "published_at": "2019-08-24T14:15:22Z"
}| listingId required | string |
| display_name | string |
| tagline | string <= 120 characters |
| description | string |
| logo_url | string <uri> |
| docs_url | string <uri> |
Array of objects (CapabilityDeclaration) | |
object (PricingInfo) | |
| tags | Array of strings |
| supported_regions | Array of strings |
| certifications | Array of strings |
{- "display_name": "string",
- "tagline": "string",
- "description": "string",
- "capabilities": [
- {
- "capability_id": "string",
- "name": "string",
- "description": "string",
- "category": "DOCUMENT_PROCESSING",
- "required_scopes": [
- "string"
], - "input_schema": { },
- "output_schema": { },
- "avg_execution_ms": 0,
- "max_execution_ms": 0
}
], - "pricing": {
- "model": "FREE",
- "unit_price": 0,
- "currency": "string",
- "free_tier_limit": 0,
- "custom_description": "string"
}, - "tags": [
- "string"
], - "supported_regions": [
- "string"
], - "certifications": [
- "string"
]
}{- "listing_id": "string",
- "agent_id": "string",
- "owner_tenant_id": "string",
- "status": "DRAFT",
- "display_name": "string",
- "tagline": "string",
- "description": "string",
- "capabilities": [
- {
- "capability_id": "string",
- "name": "string",
- "description": "string",
- "category": "DOCUMENT_PROCESSING",
- "required_scopes": [
- "string"
], - "input_schema": { },
- "output_schema": { },
- "avg_execution_ms": 0,
- "max_execution_ms": 0
}
], - "pricing": {
- "model": "FREE",
- "unit_price": 0,
- "currency": "string",
- "free_tier_limit": 0,
- "custom_description": "string"
}, - "trust_metrics": {
- "trust_score": 1,
- "avg_rating": 1,
- "review_count": 0,
- "total_invocations": 0,
- "success_rate": 1,
- "avg_response_ms": 0,
- "drift_score": 1,
- "uptime": 1,
- "computed_at": "2019-08-24T14:15:22Z"
}, - "tags": [
- "string"
], - "supported_regions": [
- "string"
], - "certifications": [
- "string"
], - "version": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "published_at": "2019-08-24T14:15:22Z"
}{- "listing_id": "string",
- "agent_id": "string",
- "owner_tenant_id": "string",
- "status": "DRAFT",
- "display_name": "string",
- "tagline": "string",
- "description": "string",
- "capabilities": [
- {
- "capability_id": "string",
- "name": "string",
- "description": "string",
- "category": "DOCUMENT_PROCESSING",
- "required_scopes": [
- "string"
], - "input_schema": { },
- "output_schema": { },
- "avg_execution_ms": 0,
- "max_execution_ms": 0
}
], - "pricing": {
- "model": "FREE",
- "unit_price": 0,
- "currency": "string",
- "free_tier_limit": 0,
- "custom_description": "string"
}, - "trust_metrics": {
- "trust_score": 1,
- "avg_rating": 1,
- "review_count": 0,
- "total_invocations": 0,
- "success_rate": 1,
- "avg_response_ms": 0,
- "drift_score": 1,
- "uptime": 1,
- "computed_at": "2019-08-24T14:15:22Z"
}, - "tags": [
- "string"
], - "supported_regions": [
- "string"
], - "certifications": [
- "string"
], - "version": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "published_at": "2019-08-24T14:15:22Z"
}| listingId required | string |
{- "listing_id": "string",
- "agent_id": "string",
- "owner_tenant_id": "string",
- "status": "DRAFT",
- "display_name": "string",
- "tagline": "string",
- "description": "string",
- "capabilities": [
- {
- "capability_id": "string",
- "name": "string",
- "description": "string",
- "category": "DOCUMENT_PROCESSING",
- "required_scopes": [
- "string"
], - "input_schema": { },
- "output_schema": { },
- "avg_execution_ms": 0,
- "max_execution_ms": 0
}
], - "pricing": {
- "model": "FREE",
- "unit_price": 0,
- "currency": "string",
- "free_tier_limit": 0,
- "custom_description": "string"
}, - "trust_metrics": {
- "trust_score": 1,
- "avg_rating": 1,
- "review_count": 0,
- "total_invocations": 0,
- "success_rate": 1,
- "avg_response_ms": 0,
- "drift_score": 1,
- "uptime": 1,
- "computed_at": "2019-08-24T14:15:22Z"
}, - "tags": [
- "string"
], - "supported_regions": [
- "string"
], - "certifications": [
- "string"
], - "version": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "published_at": "2019-08-24T14:15:22Z"
}| q | string Free-text search |
| category | string (CapabilityCategory) Enum: "DOCUMENT_PROCESSING" "DATA_ANALYSIS" "COMMUNICATION" "FINANCIAL" "LEGAL" "COMPLIANCE" "IDENTITY" "INTEGRATION" "AUTOMATION" "CUSTOM" |
| min_trust_score | number [ 0 .. 1 ] |
| min_rating | number [ 1 .. 5 ] |
| pricing_model | string (PricingModel) Enum: "FREE" "PER_CALL" "PER_MINUTE" "MONTHLY" "CUSTOM" |
| sort_by | string Enum: "trust_score" "rating" "invocations" "response_time" "created_at" |
| sort_order | string Enum: "asc" "desc" |
| cursor | string |
| limit | integer [ 1 .. 50 ] Default: 20 |
{- "listings": [
- {
- "listing_id": "string",
- "agent_id": "string",
- "owner_tenant_id": "string",
- "status": "DRAFT",
- "display_name": "string",
- "tagline": "string",
- "description": "string",
- "capabilities": [
- {
- "capability_id": "string",
- "name": "string",
- "description": "string",
- "category": "DOCUMENT_PROCESSING",
- "required_scopes": [
- "string"
], - "input_schema": { },
- "output_schema": { },
- "avg_execution_ms": 0,
- "max_execution_ms": 0
}
], - "pricing": {
- "model": "FREE",
- "unit_price": 0,
- "currency": "string",
- "free_tier_limit": 0,
- "custom_description": "string"
}, - "trust_metrics": {
- "trust_score": 1,
- "avg_rating": 1,
- "review_count": 0,
- "total_invocations": 0,
- "success_rate": 1,
- "avg_response_ms": 0,
- "drift_score": 1,
- "uptime": 1,
- "computed_at": "2019-08-24T14:15:22Z"
}, - "tags": [
- "string"
], - "supported_regions": [
- "string"
], - "certifications": [
- "string"
], - "version": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "published_at": "2019-08-24T14:15:22Z"
}
], - "next_cursor": "string",
- "total_count": 0
}| task_description required | string Natural language description of the task |
| required_capabilities | Array of strings Specific capability IDs needed |
| max_results | integer [ 1 .. 20 ] Default: 5 |
{- "task_description": "string",
- "required_capabilities": [
- "string"
], - "max_results": 5
}{- "listings": [
- {
- "listing_id": "string",
- "agent_id": "string",
- "owner_tenant_id": "string",
- "status": "DRAFT",
- "display_name": "string",
- "tagline": "string",
- "description": "string",
- "capabilities": [
- {
- "capability_id": "string",
- "name": "string",
- "description": "string",
- "category": "DOCUMENT_PROCESSING",
- "required_scopes": [
- "string"
], - "input_schema": { },
- "output_schema": { },
- "avg_execution_ms": 0,
- "max_execution_ms": 0
}
], - "pricing": {
- "model": "FREE",
- "unit_price": 0,
- "currency": "string",
- "free_tier_limit": 0,
- "custom_description": "string"
}, - "trust_metrics": {
- "trust_score": 1,
- "avg_rating": 1,
- "review_count": 0,
- "total_invocations": 0,
- "success_rate": 1,
- "avg_response_ms": 0,
- "drift_score": 1,
- "uptime": 1,
- "computed_at": "2019-08-24T14:15:22Z"
}, - "tags": [
- "string"
], - "supported_regions": [
- "string"
], - "certifications": [
- "string"
], - "version": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "published_at": "2019-08-24T14:15:22Z"
}
], - "next_cursor": "string",
- "total_count": 0
}| listing_id required | string |
| rating required | integer [ 1 .. 5 ] |
| comment | string |
| capability_id | string |
| consent_request_id | string |
{- "listing_id": "string",
- "rating": 1,
- "comment": "string",
- "capability_id": "string",
- "consent_request_id": "string"
}{- "review_id": "string",
- "listing_id": "string",
- "agent_id": "string",
- "reviewer_tenant_id": "string",
- "rating": 1,
- "comment": "string",
- "capability_id": "string",
- "consent_request_id": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}| listingId required | string |
| cursor | string |
| limit | integer [ 1 .. 50 ] Default: 20 |
{- "items": [
- {
- "review_id": "string",
- "listing_id": "string",
- "agent_id": "string",
- "reviewer_tenant_id": "string",
- "rating": 1,
- "comment": "string",
- "capability_id": "string",
- "consent_request_id": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}
], - "next_cursor": "string",
- "total_count": 0
}Creates a new agent identity with a DID, KMS-backed key pair, and initial ACTIVE status. The agent can then be bound to mandates.
| name required | string Human-readable agent name |
| description | string Agent description |
| algorithm | string Default: "ES256" Enum: "ES256" "ES384" "EdDSA" Key algorithm for the agent's verification method |
object (ClientPublicKeyJwk) Bring-your-own-key registration: the agent generates its key pair
locally and registers only the public half. Required for any agent that
authenticates with | |
object Arbitrary metadata attached to the agent | |
| environment | string <= 32 characters ^[a-z][a-z0-9-]{0,31}$ The environment the agent acts in, |
{- "name": "string",
- "description": "string",
- "algorithm": "ES256",
- "public_key_jwk": {
- "kty": "EC",
- "crv": "P-256",
- "x": "string",
- "y": "string",
- "alg": "ES256"
}, - "metadata": { },
- "environment": "qas"
}{- "agent_id": "string",
- "tenant_id": "string",
- "did": "string",
- "name": "string",
- "description": "string",
- "status": "ACTIVE",
- "verification_methods": [
- {
- "id": "string",
- "type": "string",
- "publicKeyJwk": { },
- "status": "ACTIVE"
}
], - "bound_mandates": [
- "string"
], - "environment": "qas",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}Returns a paginated list of agent identities for the authenticated tenant.
| status | string Enum: "ACTIVE" "SUSPENDED" "REVOKED" |
| limit | integer [ 1 .. 200 ] Default: 50 |
| cursor | string Base64url-encoded pagination cursor |
{- "items": [
- {
- "agent_id": "string",
- "tenant_id": "string",
- "did": "string",
- "name": "string",
- "description": "string",
- "status": "ACTIVE",
- "verification_methods": [
- {
- "id": "string",
- "type": "string",
- "publicKeyJwk": { },
- "status": "ACTIVE"
}
], - "bound_mandates": [
- "string"
], - "environment": "qas",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}
], - "cursor": "string"
}{- "agent_id": "string",
- "tenant_id": "string",
- "did": "string",
- "name": "string",
- "description": "string",
- "status": "ACTIVE",
- "verification_methods": [
- {
- "id": "string",
- "type": "string",
- "publicKeyJwk": { },
- "status": "ACTIVE"
}
], - "bound_mandates": [
- "string"
], - "environment": "qas",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}| id required | string |
| algorithm | string Default: "ES256" Enum: "ES256" "ES384" "EdDSA" |
object (ClientPublicKeyJwk) Bring-your-own-key registration: the agent generates its key pair
locally and registers only the public half. Required for any agent that
authenticates with |
{- "algorithm": "ES256",
- "public_key_jwk": {
- "kty": "EC",
- "crv": "P-256",
- "x": "string",
- "y": "string",
- "alg": "ES256"
}
}{- "agent_id": "string",
- "tenant_id": "string",
- "did": "string",
- "name": "string",
- "description": "string",
- "status": "ACTIVE",
- "verification_methods": [
- {
- "id": "string",
- "type": "string",
- "publicKeyJwk": { },
- "status": "ACTIVE"
}
], - "bound_mandates": [
- "string"
], - "environment": "qas",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}Lets the agent present a mandate in its MCP sessions. The mandate must be
delegated to this agent: its delegate.subject_id is the agent's DID or
agent id. A binding grants no authority of its own: /mcp/token issues
a session only to an agent bound to a mandate that names it, and an
execution is decided on the agent's active mandates, bound or not.
| id required | string |
| mandate_id required | string |
{- "mandate_id": "string"
}{- "agent_id": "string",
- "tenant_id": "string",
- "did": "string",
- "name": "string",
- "description": "string",
- "status": "ACTIVE",
- "verification_methods": [
- {
- "id": "string",
- "type": "string",
- "publicKeyJwk": { },
- "status": "ACTIVE"
}
], - "bound_mandates": [
- "string"
], - "environment": "qas",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}MCP sessions the agent already holds stop using the mandate at once.
| id required | string |
| mandateId required | string |
{- "agent_id": "string",
- "tenant_id": "string",
- "did": "string",
- "name": "string",
- "description": "string",
- "status": "ACTIVE",
- "verification_methods": [
- {
- "id": "string",
- "type": "string",
- "publicKeyJwk": { },
- "status": "ACTIVE"
}
], - "bound_mandates": [
- "string"
], - "environment": "qas",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}Ends every MCP session the agent holds, at once. The agent cannot obtain a token while suspended, and its earlier sessions stay dead after it is reactivated.
| id required | string |
{- "agent_id": "string",
- "tenant_id": "string",
- "did": "string",
- "name": "string",
- "description": "string",
- "status": "ACTIVE",
- "verification_methods": [
- {
- "id": "string",
- "type": "string",
- "publicKeyJwk": { },
- "status": "ACTIVE"
}
], - "bound_mandates": [
- "string"
], - "environment": "qas",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}The agent may request a new token from /mcp/token. Sessions issued
before the suspension stay dead.
| id required | string |
{- "agent_id": "string",
- "tenant_id": "string",
- "did": "string",
- "name": "string",
- "description": "string",
- "status": "ACTIVE",
- "verification_methods": [
- {
- "id": "string",
- "type": "string",
- "publicKeyJwk": { },
- "status": "ACTIVE"
}
], - "bound_mandates": [
- "string"
], - "environment": "qas",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}Revokes the agent's keys and ends every MCP session it holds. The agent can never obtain a token again.
| id required | string |
{- "agent_id": "string",
- "tenant_id": "string",
- "did": "string",
- "name": "string",
- "description": "string",
- "status": "ACTIVE",
- "verification_methods": [
- {
- "id": "string",
- "type": "string",
- "publicKeyJwk": { },
- "status": "ACTIVE"
}
], - "bound_mandates": [
- "string"
], - "environment": "qas",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}Returns usage data for the authenticated tenant's current or specified billing period. Includes total units, per-endpoint breakdown, daily usage timeline, and per-API-key breakdown. The tenant path parameter must match the authenticated caller.
| id required | string |
| period | string^\d{4}-\d{2}$ Example: period=2026-04 Billing period in YYYY-MM format. Defaults to current month. |
| granularity | string Default: "daily" Enum: "daily" "hourly" |
{- "tenant_id": "string",
- "billing_period": "2026-04",
- "total_units": 0.1,
- "endpoint_breakdown": {
- "property1": 0,
- "property2": 0
}, - "daily_usage": [
- {
- "date": "2019-08-24",
- "units": 0.1
}
], - "api_key_breakdown": [
- {
- "api_key_id": "string",
- "total_units": 0.1
}
], - "granularity": "daily",
- "allowance": {
- "metered": true,
- "period": "string",
- "limit": 0,
- "used": 0,
- "remaining": 0
}
}Returns the side-effect-free local billing projection for the authenticated tenant: the single approved metered offer, payment and entitlement state, recent invoices, and current-period usage. This GET never creates a Stripe Customer Portal session. The tenant path parameter must match the authenticated caller.
| id required | string |
{- "tenant_id": "string",
- "catalog_version": "string",
- "offer": {
- "id": "metered",
- "name": "string",
- "currency": "eur",
- "unit_amount_minor": 10,
- "billing_block_units": 1000
}, - "billing_status": "string",
- "billing_plan": "metered",
- "billing_plan_name": "string",
- "entitlement_status": "active",
- "activation_authority": "string",
- "has_payment_method": true,
- "stripe_connected": true,
- "portal_available": true,
- "subscription": {
- "id": "string",
- "status": "string",
- "current_period_start": "2019-08-24T14:15:22Z",
- "current_period_end": "2019-08-24T14:15:22Z",
- "cancel_at_period_end": true
}, - "invoices": [
- {
- "id": "string",
- "number": "string",
- "billing_period": "string",
- "status": "string",
- "amount_due": 0,
- "amount_paid": 0,
- "currency": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "paid_at": "2019-08-24T14:15:22Z",
}
], - "current_period": {
- "billing_period": "string",
- "total_units": 0.1,
- "endpoint_breakdown": {
- "property1": 0,
- "property2": 0
}, - "estimated_amount_minor": 0,
- "currency": "eur"
}
}Starts product-owned payment-method collection for the tenant when the rollout flags are enabled. A successful SetupIntent never activates paid access. Returns a client secret for Stripe.js / Stripe Elements.
| id required | string |
{- "client_secret": "string",
- "status": "pending",
- "message": "string"
}Starts or resumes the single EUR 0.10 per 1,000 unit Mandaitor offer when rollout flags are enabled. The handler records a pending attempt; it never grants paid access. Activation is projected only after an eligible owned subscription and a paid or legitimately zero initial invoice. If payment details are missing, a SetupIntent client secret is returned without activating service.
| id required | string |
| plan required | string Value: "metered" The only approved Mandaitor paid offer |
{- "plan": "metered"
}{- "plan": "metered",
- "plan_name": "string",
- "status": "active",
- "requires_payment": true,
- "requires_action": true,
- "subscription_id": "string",
- "client_secret": "string",
- "payment_client_secret": "string",
- "message": "string"
}Receives and processes Stripe webhook events. Authentication is performed via Stripe signature verification (not API key or JWT). Handles invoice lifecycle events (payment succeeded/failed/finalized) and subscription changes (updated/deleted).
Raw Stripe webhook event payload
{ }{- "received": true
}Admin-only, dry-run-first Customer inventory. Every mapped Customer is
retrieved read-only and checked against the exact Mandaitor product,
stage, and opaque owner metadata. The default request never writes.
{ "apply": true } creates Customers only for unmapped tenants and is
rejected unless BILLING_CUSTOMER_SYNC_APPLY_ENABLED=true. It never
creates subscriptions and is not scheduled automatically.
| apply | boolean Default: false Request gated Customer creation for unmapped tenants |
{- "apply": false
}{- "mode": "dry_run",
- "scanned": 0,
- "verified_owned": 0,
- "legacy_mapping_requires_review": 0,
- "missing_customer": 0,
- "deleted_customer": 0,
- "metadata_mismatch": 0,
- "remote_lookup_failed": 0,
- "created": 0,
- "failed": 0
}Enterprise systems Mandaitor can govern. Each catalog entry lists the
registered tools that act through the connector and the fields a
tenant must configure. The mock adapters once listed with
configurable: false retired in execution roadmap E2.11.
{- "connectors": [
- {
- "type": "servicenow",
- "display_name": "string",
- "vendor": "string",
- "description": "string",
- "maturity": "pilot",
- "configurable": true,
- "tools": [
- {
- "tool": "servicenow.requested_item.approve",
- "effect": "read",
- "description": "string"
}
], - "config_fields": [
- {
- "name": "string",
- "label": "string",
- "type": "string",
- "required": true,
- "secret": true,
- "placeholder": "string"
}
]
}
]
}| id required | string |
{- "connectors": [
- {
- "connector_id": "con_01JX5T9K2M",
- "tenant_id": "string",
- "type": "servicenow",
- "name": "string",
- "config": {
- "property1": "string",
- "property2": "string"
}, - "sandbox_id": "sbx_01JX5T9K2M",
- "environment": "qas",
- "credentials_rotated_at": "2019-08-24T14:15:22Z",
- "credentials_rotated_by": "string",
- "status": "unverified",
- "last_test_at": "2019-08-24T14:15:22Z",
- "last_test_message": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}
]
}Validates the configuration against the catalog entry, rejects
instance URLs the SSRF guard would block, KMS-encrypts secret fields,
and stores the instance with status unverified. Secret fields are
write-only — they are never returned by any connector route.
| id required | string |
| type required | string Catalog entry to configure (must be configurable) |
| name required | string <= 100 characters |
required | object Field values keyed by the catalog entry's config_fields names. Secret fields (e.g. password) are KMS-encrypted at rest and never returned by the API. |
| environment | string <= 32 characters ^[a-z][a-z0-9-]{0,31}$ The environment the system belongs to, |
{- "type": "servicenow",
- "name": "ServiceNow PDI (dev209313)",
- "config": {
- "username": "mandaitor.integration",
- "password": "…"
}, - "environment": "qas"
}{- "connector_id": "con_01JX5T9K2M",
- "tenant_id": "string",
- "type": "servicenow",
- "name": "string",
- "config": {
- "property1": "string",
- "property2": "string"
}, - "sandbox_id": "sbx_01JX5T9K2M",
- "environment": "qas",
- "credentials_rotated_at": "2019-08-24T14:15:22Z",
- "credentials_rotated_by": "string",
- "status": "unverified",
- "last_test_at": "2019-08-24T14:15:22Z",
- "last_test_message": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}Creates a Mandaitor-hosted emulation of the requested enterprise system (ServiceNow Table API or SAP S/4HANA OData), seeds it with the demo records, and configures a connector instance pointing at it — so the full governed loop can be exercised without a customer system.
The result is an ordinary connector: same storage, same KMS-encrypted
credential, same test-connection probe, same governed tool calls. Only
the target differs, and sandbox_id marks it as sandbox-backed.
Sandboxes expire after 30 days and are deleted with their connector.
| id required | string |
| type required | string Enum: "servicenow" "sap-s4hana" Which enterprise system to emulate |
| name | string <= 100 characters Optional display name; defaults to " |
| environment | string <= 32 characters ^[a-z][a-z0-9-]{0,31}$ The environment the sandbox stands in for, |
{- "type": "servicenow",
- "name": "string",
- "environment": "qas"
}{- "connector_id": "con_01JX5T9K2M",
- "tenant_id": "string",
- "type": "servicenow",
- "name": "string",
- "config": {
- "property1": "string",
- "property2": "string"
}, - "sandbox_id": "sbx_01JX5T9K2M",
- "environment": "qas",
- "credentials_rotated_at": "2019-08-24T14:15:22Z",
- "credentials_rotated_by": "string",
- "status": "unverified",
- "last_test_at": "2019-08-24T14:15:22Z",
- "last_test_message": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}Restores the hosted sandbox behind this connector to the records it was provisioned with, so a demo can be re-run from a clean slate. Rejected for connectors that point at a real system.
| id required | string |
| connectorId required | string |
{- "status": "reset",
- "connector": {
- "connector_id": "con_01JX5T9K2M",
- "tenant_id": "string",
- "type": "servicenow",
- "name": "string",
- "config": {
- "property1": "string",
- "property2": "string"
}, - "sandbox_id": "sbx_01JX5T9K2M",
- "environment": "qas",
- "credentials_rotated_at": "2019-08-24T14:15:22Z",
- "credentials_rotated_by": "string",
- "status": "unverified",
- "last_test_at": "2019-08-24T14:15:22Z",
- "last_test_message": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}
}Has the executor, the one function that decrypts a credential, make
one read-only probe against the configured system with the stored
credential (for ServiceNow: an authenticated Table API read of a
single requested item). Updates the instance's status,
last_test_at, and last_test_message with the outcome, and nothing
else.
| id required | string |
| connectorId required | string |
{- "connector": {
- "connector_id": "con_01JX5T9K2M",
- "tenant_id": "string",
- "type": "servicenow",
- "name": "string",
- "config": {
- "property1": "string",
- "property2": "string"
}, - "sandbox_id": "sbx_01JX5T9K2M",
- "environment": "qas",
- "credentials_rotated_at": "2019-08-24T14:15:22Z",
- "credentials_rotated_by": "string",
- "status": "unverified",
- "last_test_at": "2019-08-24T14:15:22Z",
- "last_test_message": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}, - "test": {
- "ok": true,
- "message": "Connected — Table API reachable, requested items visible",
- "http_status": 200
}
}Replaces the connector's credential in place (execution roadmap
E2.10). The executor probes the system with the new credential first;
it is stored only if the system accepts it, and only if the stored
credential is still the one read before the probe. The connector keeps
its id, so the tools enabled on it, approvals waiting on it and
executions not yet dispatched carry on, with the new credential.
Requires tenant:write.
Where the system allows two credentials at once, as an API key often does, add the new one there, replace it here, then remove the old one there: nothing fails in between. Where changing it at the system ends the old one at once, as a password change does, executions dispatched between that change and this call fail.
A sandbox's credential is minted by Mandaitor and never shown: send no body. The sandbox accepts the new secret beside the old one while it is probed, and only the new one once it is stored, so a ServiceNow sandbox credential shown at provisioning stops working.
| id required | string |
| connectorId required | string |
required | object | ||
| |||
{- "credentials": {
- "password": "…"
}
}{- "connector": {
- "connector_id": "con_01JX5T9K2M",
- "tenant_id": "string",
- "type": "servicenow",
- "name": "string",
- "config": {
- "property1": "string",
- "property2": "string"
}, - "sandbox_id": "sbx_01JX5T9K2M",
- "environment": "qas",
- "credentials_rotated_at": "2019-08-24T14:15:22Z",
- "credentials_rotated_by": "string",
- "status": "unverified",
- "last_test_at": "2019-08-24T14:15:22Z",
- "last_test_message": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}, - "test": {
- "ok": true,
- "message": "Connected — Table API reachable, requested items visible",
- "http_status": 200
}
}| mandate_id required | string The mandate the call falls under. |
| agent_id required | string The agent that would make the call. |
| agent_did | string |
required | object |
| reason required | string Why consent is needed, as the approver reads it. |
| amount | number The amount at stake, when there is one. |
| currency | string |
| urgency | string Enum: "LOW" "NORMAL" "HIGH" "CRITICAL" |
| ttl_seconds | integer How long the request stays open. Default 3600. |
{- "mandate_id": "string",
- "agent_id": "string",
- "agent_did": "string",
- "tool_call": {
- "tool_name": "string",
- "arguments": { }
}, - "reason": "string",
- "amount": 0,
- "currency": "string",
- "urgency": "LOW",
- "ttl_seconds": 0
}{- "consent_id": "string",
- "tenant_id": "string",
- "mandate_id": "string",
- "agent_id": "string",
- "agent_did": "string",
- "approver_subject_id": "string",
- "approver_display_name": "string",
- "status": "PENDING",
- "urgency": "LOW",
- "tool_call": {
- "tool_name": "string",
- "arguments": { }
}, - "reason": "string",
- "amount": 0,
- "currency": "string",
- "decision": {
- "decided_by": "string",
- "decided_at": "2019-08-24T14:15:22Z",
- "comment": "string",
- "auto_policy_id": "string"
}, - "execution": {
- "execution_id": "string",
- "approval_digest": "string",
- "tool": {
- "id": "string",
- "version": 0
}, - "scope": {
- "action": "string",
- "resource": "string"
}, - "facts": { },
- "target": {
- "connector_id": "string",
- "record": "string",
- "version": "string"
}, - "require_mfa": true,
- "rules": [
- "string"
], - "purpose": "string"
}, - "notification": {
- "status": "SENDING",
- "reason": "NO_ADDRESS",
- "channel": "email",
- "at": "2019-08-24T14:15:22Z"
}, - "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "expires_at": "2019-08-24T14:15:22Z"
}The pending consent requests of the caller's own tenant that name the caller as approver, in one page of up to limit. An execution's approval past its expires_at is left out: it can no longer be decided.
| limit | integer Default: 50 |
{- "items": [
- {
- "consent_id": "string",
- "tenant_id": "string",
- "mandate_id": "string",
- "agent_id": "string",
- "agent_did": "string",
- "approver_subject_id": "string",
- "approver_display_name": "string",
- "status": "PENDING",
- "urgency": "LOW",
- "tool_call": {
- "tool_name": "string",
- "arguments": { }
}, - "reason": "string",
- "amount": 0,
- "currency": "string",
- "decision": {
- "decided_by": "string",
- "decided_at": "2019-08-24T14:15:22Z",
- "comment": "string",
- "auto_policy_id": "string"
}, - "execution": {
- "execution_id": "string",
- "approval_digest": "string",
- "tool": {
- "id": "string",
- "version": 0
}, - "scope": {
- "action": "string",
- "resource": "string"
}, - "facts": { },
- "target": {
- "connector_id": "string",
- "record": "string",
- "version": "string"
}, - "require_mfa": true,
- "rules": [
- "string"
], - "purpose": "string"
}, - "notification": {
- "status": "SENDING",
- "reason": "NO_ADDRESS",
- "channel": "email",
- "at": "2019-08-24T14:15:22Z"
}, - "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "expires_at": "2019-08-24T14:15:22Z"
}
], - "count": 0
}| id required | string |
{- "consent_id": "string",
- "tenant_id": "string",
- "mandate_id": "string",
- "agent_id": "string",
- "agent_did": "string",
- "approver_subject_id": "string",
- "approver_display_name": "string",
- "status": "PENDING",
- "urgency": "LOW",
- "tool_call": {
- "tool_name": "string",
- "arguments": { }
}, - "reason": "string",
- "amount": 0,
- "currency": "string",
- "decision": {
- "decided_by": "string",
- "decided_at": "2019-08-24T14:15:22Z",
- "comment": "string",
- "auto_policy_id": "string"
}, - "execution": {
- "execution_id": "string",
- "approval_digest": "string",
- "tool": {
- "id": "string",
- "version": 0
}, - "scope": {
- "action": "string",
- "resource": "string"
}, - "facts": { },
- "target": {
- "connector_id": "string",
- "record": "string",
- "version": "string"
}, - "require_mfa": true,
- "rules": [
- "string"
], - "purpose": "string"
}, - "notification": {
- "status": "SENDING",
- "reason": "NO_ADDRESS",
- "channel": "email",
- "at": "2019-08-24T14:15:22Z"
}, - "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "expires_at": "2019-08-24T14:15:22Z"
}| id required | string |
| decision required | string Enum: "APPROVED" "REJECTED" |
| comment | string The approver's comment, kept with the decision. |
{- "decision": "APPROVED",
- "comment": "string"
}{- "consent_id": "string",
- "tenant_id": "string",
- "mandate_id": "string",
- "agent_id": "string",
- "agent_did": "string",
- "approver_subject_id": "string",
- "approver_display_name": "string",
- "status": "PENDING",
- "urgency": "LOW",
- "tool_call": {
- "tool_name": "string",
- "arguments": { }
}, - "reason": "string",
- "amount": 0,
- "currency": "string",
- "decision": {
- "decided_by": "string",
- "decided_at": "2019-08-24T14:15:22Z",
- "comment": "string",
- "auto_policy_id": "string"
}, - "execution": {
- "execution_id": "string",
- "approval_digest": "string",
- "tool": {
- "id": "string",
- "version": 0
}, - "scope": {
- "action": "string",
- "resource": "string"
}, - "facts": { },
- "target": {
- "connector_id": "string",
- "record": "string",
- "version": "string"
}, - "require_mfa": true,
- "rules": [
- "string"
], - "purpose": "string"
}, - "notification": {
- "status": "SENDING",
- "reason": "NO_ADDRESS",
- "channel": "email",
- "at": "2019-08-24T14:15:22Z"
}, - "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "expires_at": "2019-08-24T14:15:22Z"
}| id required | string |
| status | string Enum: "pending" "approved" "rejected" "expired" |
| limit | integer Default: 20 |
| cursor | string |
{- "items": [
- {
- "consent_id": "string",
- "tenant_id": "string",
- "mandate_id": "string",
- "agent_id": "string",
- "agent_did": "string",
- "approver_subject_id": "string",
- "approver_display_name": "string",
- "status": "PENDING",
- "urgency": "LOW",
- "tool_call": {
- "tool_name": "string",
- "arguments": { }
}, - "reason": "string",
- "amount": 0,
- "currency": "string",
- "decision": {
- "decided_by": "string",
- "decided_at": "2019-08-24T14:15:22Z",
- "comment": "string",
- "auto_policy_id": "string"
}, - "execution": {
- "execution_id": "string",
- "approval_digest": "string",
- "tool": {
- "id": "string",
- "version": 0
}, - "scope": {
- "action": "string",
- "resource": "string"
}, - "facts": { },
- "target": {
- "connector_id": "string",
- "record": "string",
- "version": "string"
}, - "require_mfa": true,
- "rules": [
- "string"
], - "purpose": "string"
}, - "notification": {
- "status": "SENDING",
- "reason": "NO_ADDRESS",
- "channel": "email",
- "at": "2019-08-24T14:15:22Z"
}, - "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "expires_at": "2019-08-24T14:15:22Z"
}
], - "count": 0
}| name required | string Human-readable policy name |
| description | string |
required | Array of objects (ConsentPolicyRule) |
| priority | integer Higher priority policies are evaluated first (default 0) |
| enabled | boolean Default: true |
{- "name": "string",
- "description": "string",
- "rules": [
- {
- "effect": "auto_approve",
- "agent_ids": [
- "string"
], - "actions": [
- "string"
], - "resources": [
- "string"
], - "max_amount": 0,
- "time_window": {
- "start": "string",
- "end": "string",
- "days": [
- "mon"
]
}
}
], - "priority": 0,
- "enabled": true
}{- "policy_id": "string",
- "tenant_id": "string",
- "name": "string",
- "description": "string",
- "rules": [
- {
- "effect": "auto_approve",
- "agent_ids": [
- "string"
], - "actions": [
- "string"
], - "resources": [
- "string"
], - "max_amount": 0,
- "time_window": {
- "start": "string",
- "end": "string",
- "days": [
- "mon"
]
}
}
], - "priority": 0,
- "enabled": true,
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}| limit | integer Default: 20 |
| cursor | string |
{- "items": [
- {
- "policy_id": "string",
- "tenant_id": "string",
- "name": "string",
- "description": "string",
- "rules": [
- {
- "effect": "auto_approve",
- "agent_ids": [
- "string"
], - "actions": [
- "string"
], - "resources": [
- "string"
], - "max_amount": 0,
- "time_window": {
- "start": "string",
- "end": "string",
- "days": [
- "mon"
]
}
}
], - "priority": 0,
- "enabled": true,
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}
], - "next_cursor": "string",
- "total_count": 0
}| id required | string |
{- "policy_id": "string",
- "tenant_id": "string",
- "name": "string",
- "description": "string",
- "rules": [
- {
- "effect": "auto_approve",
- "agent_ids": [
- "string"
], - "actions": [
- "string"
], - "resources": [
- "string"
], - "max_amount": 0,
- "time_window": {
- "start": "string",
- "end": "string",
- "days": [
- "mon"
]
}
}
], - "priority": 0,
- "enabled": true,
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}| id required | string |
| name | string |
| description | string |
Array of objects (ConsentPolicyRule) | |
| priority | integer |
| enabled | boolean |
{- "name": "string",
- "description": "string",
- "rules": [
- {
- "effect": "auto_approve",
- "agent_ids": [
- "string"
], - "actions": [
- "string"
], - "resources": [
- "string"
], - "max_amount": 0,
- "time_window": {
- "start": "string",
- "end": "string",
- "days": [
- "mon"
]
}
}
], - "priority": 0,
- "enabled": true
}{- "policy_id": "string",
- "tenant_id": "string",
- "name": "string",
- "description": "string",
- "rules": [
- {
- "effect": "auto_approve",
- "agent_ids": [
- "string"
], - "actions": [
- "string"
], - "resources": [
- "string"
], - "max_amount": 0,
- "time_window": {
- "start": "string",
- "end": "string",
- "days": [
- "mon"
]
}
}
], - "priority": 0,
- "enabled": true,
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}Preview. Request-bound decisions: /verify's successor for an integrator whose enforcement point performs an agent's operation itself
Preview. /verify's successor for an integrator whose own
enforcement point performs an agent's operation. Ask before you act,
with the tenant's API key (the verify scope), never from the agent:
name the agent by its DID, the taxonomy business action, the one
resource it acts on, and the facts you read from your own system.
Mandaitor decides as it decides an execution: every ACTIVE mandate
naming the agent counts, a DENY mandate wins, and an ALLOW
mandate counts only if a person created or approved it and it names
the action exactly. Its time window, max_amount, cumulative limits,
amount_above and require_mfa are checked on your facts; a mandate
that limits amounts needs an amount fact, as money.
ALLOW carries authorization: a JWS (typ
mandaitor-authorization+jwt, PS256) signed with the key the
issuer's DID document lists as #authorization-key-1. It is bound to
the request's digest, to audience and to five minutes at most,
never past the mandate's expiry. Redeem it with
POST /decisions/{id}/redemption immediately before you act; act
only if the redemption succeeds. It counts against the mandate's
cumulative limits when it is given, whether or not it is redeemed.
REQUIRE_APPROVAL and DENY carry no authorization. A decision request raises no approval: when a person would have to approve, the request fails closed.
The request digest is the SHA-256, sha-256: and base64url, of the
RFC 8785 form of {contract, tenant_id, agent, action, resource, facts, audience}; mandate_id and purpose are not part of it.
The SDK computes it as decisionRequestDigest.
Every answer is recorded on the audit chain before it is given. When
it cannot be, nothing is given: 503 AUDIT_UNAVAILABLE. Each answer
counts 2 units against the monthly allowance, an ALLOW or not.
| contract required | string <= 64 characters Value: "mandaitor.decision-request/v1" |
| agent required | string <= 256 characters ^did:[a-z0-9]+:[\x21-\x7E]+$ The agent you act for, by its DID. |
| action required | string <= 128 characters ^[a-z][a-z0-9_-]*(\.[a-z][a-z0-9_-]*)+$ A business action a taxonomy defines. Unknown actions are denied. |
| resource required | string <= 512 characters ^[A-Za-z0-9._~-]+(:[A-Za-z0-9._~-]+)*(/[A-Za-... The one record the operation acts on, in the taxonomies' syntax. No
|
required | object <= 32 properties What you read from your own system of record, never from the
agent. Names are 1 to 64 lower-case letters, digits and |
| audience required | string [ 1 .. 256 ] characters ^[\x21-\x7E]{1,256}$ Your enforcement point, as it names itself. The authorization is for it alone. |
| mandate_id | string <= 68 characters ^mdt_[A-Za-z0-9]{1,64}$ The mandate you believe covers the operation. A hint only. |
| purpose | string <= 500 characters Recorded with the decision. Never used to decide. |
{- "contract": "mandaitor.decision-request/v1",
- "agent": "did:web:agents.mandaitor.io:agt_01JZ8Y3S6N0F4K7Q2W9E5R1T8V",
- "action": "procurement.requisition.release",
- "resource": "procurement:plant:1000/requisition:10004711",
- "facts": {
- "plant": "1000",
- "amount": {
- "currency": "EUR",
- "value": "1250.00"
}
}, - "mandate_id": "string",
- "purpose": "string"
}{- "contract": "mandaitor.decision/v1",
- "decision": "ALLOW",
- "code": "ALLOWED",
- "reason": "string",
- "request_digest": "string",
- "event_id": "string",
- "decided_at": "2019-08-24T14:15:22Z",
- "mandate_id": "string",
- "fact": "string",
- "constraints": [
- "string"
], - "approval_rules": [
- "AMOUNT_ABOVE_THRESHOLD"
], - "decision_id": "string",
- "authorization": "string",
- "expires_at": "2019-08-24T14:15:22Z"
}Preview. Send the digest of the operation you are about to perform, computed by you, never copied from the answer. The redemption succeeds once, and only:
exp;Act only on a 200. Every 409 means do not act, including
ALREADY_REDEEMED after a retry whose first answer was lost: ask for
a new decision. Every redemption, refused or not, is recorded on the
audit chain before it is answered; when it cannot be, the answer is
503 and the authorization is left as it was. Redemptions are not
counted against the allowance.
| id required | string <= 30 characters ^dec_[0-9A-Z]{26}$ The decision's |
| request_digest required | string <= 51 characters ^sha-256:[A-Za-z0-9_-]{43}$ The digest of the operation you are about to perform, computed by you. |
{- "request_digest": "string"
}{- "decision_id": "string",
- "redeemed_at": "2019-08-24T14:15:22Z",
- "event_id": "string"
}@experimental Aggregates drift session data across all mandates to produce per-agent summaries including average/max drift scores, session counts, and last activity timestamps.
[- {
- "delegate_subject_id": "string",
- "display_name": "string",
- "mandate_count": 0,
- "avg_drift_score": 0.1,
- "max_drift_score": 0.1,
- "sessions_with_drift": 0,
- "total_sessions": 0,
- "last_activity": "2019-08-24T14:15:22Z"
}
]@experimental Queries the tenant-wide event timeline for
DRIFT_DETECTED and DRIFT_RESOLVED events, enriched with the drift
score from the event details. Results are newest-first and paginate
via an opaque cursor; follow next_cursor until it is absent to
walk the full drift history.
| limit | integer [ 1 .. 100 ] Default: 20 Maximum number of events to return per page. |
| cursor | string Opaque base64url cursor from a previous response's |
{- "items": [
- {
- "event_id": "string",
- "timestamp": "2019-08-24T14:15:22Z",
- "mandate_id": "string",
- "delegate_subject_id": "string",
- "action": "DRIFT_DETECTED",
- "drift_score": {
- "semantic_distance": 0.1,
- "sequence_deviation": 0.1,
- "frequency_anomaly": 0.1,
- "scope_expansion": 0.1,
- "aggregate": 0.1,
- "drift_detected": true
}
}
], - "next_cursor": "string"
}@experimental Queries the drift sessions table to retrieve all recent session windows for a given delegate, enriched with computed drift scores and mandate context.
| delegateId required | string The delegate subject ID. |
| hours | integer [ 1 .. 168 ] Default: 24 Lookback window in hours. |
[- {
- "mandate_id": "string",
- "delegate_subject_id": "string",
- "window_start": "2019-08-24T14:15:22Z",
- "window_end": "2019-08-24T14:15:22Z",
- "action_count": 0,
- "drift_score": {
- "semantic_distance": 0.1,
- "sequence_deviation": 0.1,
- "frequency_anomaly": 0.1,
- "scope_expansion": 0.1,
- "aggregate": 0.1,
- "drift_detected": true
}, - "intent_purpose": "string"
}
]Creates a new OpenID4VP session for EUDI Wallet identity verification. Returns a QR code URI (cross-device) and deep link URI (same-device) that the user scans/opens with their EUDI Wallet.
| presentation_definition_id | string Default: "mandaitor-pid-standard" Enum: "mandaitor-pid-minimal" "mandaitor-pid-standard" "mandaitor-pid-delegation" ID of the presentation definition to use |
{- "presentation_definition_id": "mandaitor-pid-minimal"
}{- "session_id": "eudi_01HXYZ...",
- "status": "PENDING",
- "qr_code_uri": "string",
- "deep_link_uri": "string",
- "expires_at": "2019-08-24T14:15:22Z"
}Polls the status of an EUDI Wallet verification session. Returns the resolved identity when the session is completed.
| sessionId required | string |
{- "session_id": "string",
- "status": "PENDING",
- "created_at": "2019-08-24T14:15:22Z",
- "presentation_definition_id": "string",
- "resolved_identity": {
- "subject_id": "eudi:DE/1234567890abcdef",
- "subject_type": "NATURAL_PERSON",
- "provider": "EUDI_WALLET",
- "display_name": "string",
- "assurance_level": "HIGH",
- "eidas_attributes": {
- "unique_id": "string",
- "family_name": "string",
- "given_name": "string",
- "birth_date": "2019-08-24",
- "nationality": "string",
- "pid_issuer": "string",
- "issuing_country": "string",
- "assurance_level": "LOW"
}
}, - "verified_at": "2019-08-24T14:15:22Z",
- "errors": [
- "string"
]
}Receives the VP Token from the EUDI Wallet via direct_post response mode. This endpoint is called by the wallet after user consent. No authentication required as the wallet POSTs directly.
| sessionId required | string |
| vp_token required | string The VP Token (SD-JWT VC compact serialization) |
| presentation_submission | object DIF Presentation Submission mapping |
{- "vp_token": "string",
- "presentation_submission": { }
}{- "status": "COMPLETED",
- "session_id": "string"
}Serves the signed JWT Authorization Request Object that the EUDI Wallet fetches after scanning the QR code. Returns the JWT directly with content type application/oauth-authz-req+jwt.
| requestId required | string |
{- "error": "BAD_REQUEST",
- "message": "principal and delegate are required"
}Returns a paginated list of audit events for a specific mandate. Events form an immutable, hash-chained audit trail.
| id required | string Example: mdt_01HXYZ... |
| limit | integer [ 1 .. 200 ] Default: 50 |
| cursor | string Base64url-encoded pagination cursor |
{- "items": [
- {
- "event_id": "string",
- "tenant_id": "string",
- "mandate_id": "string",
- "event_type": "MANDATE_CREATED",
- "timestamp": "2019-08-24T14:15:22Z",
- "actor": {
- "type": "HUMAN",
- "subject_id": "construction:agent:validate-agent-v2",
- "display_name": "string",
- "identity_provider": "string",
- "identity_token_hash": "string"
}, - "details": { },
- "previous_event_hash": "string",
- "event_hash": "string",
- "kms_signature": "string",
- "hash_algorithm": "SHA_256",
- "signing_algorithm": "RSASSA_PSS_SHA_256"
}
], - "next_cursor": "string"
}Queries all audit events for the authenticated tenant, filtered by mandate_id. Supports optional event_type filtering and cursor-based pagination.
| mandate_id required | string Mandate ID to filter events by |
| event_type | string Enum: "MANDATE_CREATED" "MANDATE_SUSPENDED" "MANDATE_REACTIVATED" "MANDATE_REVOKED" "VERIFICATION_ALLOWED" "VERIFICATION_DENIED" "ESCALATION_TRIGGERED" |
| limit | integer [ 1 .. 200 ] Default: 50 |
| cursor | string Base64url-encoded pagination cursor |
{- "items": [
- {
- "event_id": "string",
- "tenant_id": "string",
- "mandate_id": "string",
- "event_type": "MANDATE_CREATED",
- "timestamp": "2019-08-24T14:15:22Z",
- "actor": {
- "type": "HUMAN",
- "subject_id": "construction:agent:validate-agent-v2",
- "display_name": "string",
- "identity_provider": "string",
- "identity_token_hash": "string"
}, - "details": { },
- "previous_event_hash": "string",
- "event_hash": "string",
- "kms_signature": "string",
- "hash_algorithm": "SHA_256",
- "signing_algorithm": "RSASSA_PSS_SHA_256"
}
], - "next_cursor": "string"
}Retrieves a single audit event by its ID. Requires the mandate_id query parameter to locate the event in the partition.
| id required | string Example: evt_01HXYZ... |
| mandate_id required | string Mandate ID the event belongs to |
{- "event_id": "string",
- "tenant_id": "string",
- "mandate_id": "string",
- "event_type": "MANDATE_CREATED",
- "timestamp": "2019-08-24T14:15:22Z",
- "actor": {
- "type": "HUMAN",
- "subject_id": "construction:agent:validate-agent-v2",
- "display_name": "string",
- "identity_provider": "string",
- "identity_token_hash": "string"
}, - "details": { },
- "previous_event_hash": "string",
- "event_hash": "string",
- "kms_signature": "string",
- "hash_algorithm": "SHA_256",
- "signing_algorithm": "RSASSA_PSS_SHA_256"
}Tenant-scoped audit feed used by the dashboard Overview / Recent
Activity. Returns events in descending timestamp order across all
of the tenant's mandates. For a per-mandate timeline use
GET /events?mandate_id=… instead. The tenant path parameter
must match the authenticated caller. Requires Cognito JWT.
| id required | string |
| limit | integer [ 1 .. 200 ] Default: 50 |
| cursor | string Opaque base64url cursor from a previous response's |
| event_type | string Optional filter on event_type (applied after the tenant-scoped query). |
{- "items": [
- {
- "event_id": "string",
- "event_type": "string",
- "mandate_id": "string",
- "tenant_id": "string",
- "timestamp": "2019-08-24T14:15:22Z"
}
], - "next_cursor": "string"
}Exports a tenant-scoped audit event slice in descending timestamp order
for SIEM, GRC, and offline audit tooling. The tenant path parameter must
match the authenticated caller unless the caller is a platform admin.
Requires the events:export permission, which is granted to tenant
administrators and tenant auditors.
The format parameter selects the interchange representation:
json (default) — Mandaitor's native envelope with pagination
metadata in the body.xes — eXtensible Event Stream (IEEE 1849) for process mining
(ProM, Celonis, Apromore, Signavio). One trace per mandate, ordered
oldest-first, with the standard concept, time, org, lifecycle
and identity extensions declared.cloudevents — CNCF CloudEvents 1.0 JSON batch for event meshes
(Knative, Event Grid, Kafka). Attribute names follow the
specification's lowercase-alphanumeric constraint, so Mandaitor's
snake_case fields appear as tenantid, mandateid and eventhash.XES and CloudEvents have no envelope for pagination, so the cursor,
export id and event count are returned as X-Mandaitor-* response
headers instead. These headers are listed in
Access-Control-Expose-Headers so browser clients can read them.
| id required | string |
| format | string Default: "json" Enum: "json" "xes" "cloudevents" Interchange format for the export. Case-insensitive. An unsupported value returns 400 rather than falling back to JSON, so a caller cannot mistake a downgraded payload for a successful export. |
| limit | integer [ 1 .. 500 ] Default: 100 Maximum number of audit events to include in this export page. |
| cursor | string Opaque base64url cursor from a previous response's |
| event_type | string Optional filter on event_type for SIEM-specific routing or replay windows. |
| from_timestamp | string <date-time> Inclusive lower bound for the audit-event timestamp sort key. |
| to_timestamp | string <date-time> Inclusive upper bound for the audit-event timestamp sort key. |
{- "export_id": "audexp_dG50X2FjbWU6MjAyNi0wNS0xOVQxMjozMDowMFowMDBa",
- "tenant_id": "string",
- "generated_at": "2019-08-24T14:15:22Z",
- "event_count": 0,
- "items": [
- {
- "event_id": "string",
- "tenant_id": "string",
- "mandate_id": "string",
- "event_type": "MANDATE_CREATED",
- "timestamp": "2019-08-24T14:15:22Z",
- "actor": {
- "type": "HUMAN",
- "subject_id": "construction:agent:validate-agent-v2",
- "display_name": "string",
- "identity_provider": "string",
- "identity_token_hash": "string"
}, - "details": { },
- "previous_event_hash": "string",
- "event_hash": "string",
- "kms_signature": "string",
- "hash_algorithm": "SHA_256",
- "signing_algorithm": "RSASSA_PSS_SHA_256"
}
], - "next_cursor": "string"
}Exports a comprehensive, court-ready evidence pack for a mandate containing:
EVIDENCE_PACK_EXPORTED audit event recorded for the export operationThe case_log_hash is a deterministic SHA-256 digest computed over the
canonical JSON representation of the event chain, enabling tamper detection.
The export_manifest binds the mandate snapshot, event chain, proof tokens,
and export envelope to recomputable digests so offline reviewers can detect
tampering in the export artifact.
The schema_version field allows forward-compatible evolution of the pack format.
| id required | string Example: mdt_01HXYZ... |
| event_id | string Scope the evidence pack to a specific verification event |
{- "schema_version": "1.2.0",
- "export_timestamp": "2019-08-24T14:15:22Z",
- "tenant_id": "string",
- "mandate_id": "string",
- "mandate_snapshot": { },
- "event_chain": [
- {
- "event_id": "string",
- "tenant_id": "string",
- "mandate_id": "string",
- "event_type": "MANDATE_CREATED",
- "timestamp": "2019-08-24T14:15:22Z",
- "actor": {
- "type": "HUMAN",
- "subject_id": "construction:agent:validate-agent-v2",
- "display_name": "string",
- "identity_provider": "string",
- "identity_token_hash": "string"
}, - "details": { },
- "previous_event_hash": "string",
- "event_hash": "string",
- "kms_signature": "string",
- "hash_algorithm": "SHA_256",
- "signing_algorithm": "RSASSA_PSS_SHA_256"
}
], - "event_count": 0,
- "case_log_hash": "string",
- "chain_integrity": {
- "first_event_hash": "string",
- "last_event_hash": "string",
- "genesis_verified": true
}, - "issuer": {
- "did": "did:web:api.mandaitor.io",
}, - "proof_tokens": [
- "string"
], - "crypto_metadata": {
- "hash_algorithm": "SHA_256",
- "signing_algorithm": "RSASSA_PSS_SHA_256",
- "case_log_hash_algorithm": "SHA_256"
}, - "export_manifest": {
- "export_id": "mandate_m_123:2026-05-19T12:00:00.000Z",
- "generated_at": "2019-08-24T14:15:22Z",
- "generated_by": {
- "subject": "string",
- "tenant_id": "string",
- "auth_method": "string",
- "roles": [
- "string"
], - "permissions": [
- "string"
]
}, - "coverage": {
- "tenant_id": "string",
- "mandate_id": "string",
- "schema_version": "1.2.0",
- "event_count": 0,
- "event_id_filter": "string"
}, - "digests": {
- "mandate_snapshot_hash": "string",
- "event_chain_hash": "string",
- "proof_tokens_hash": "string",
- "manifest_hash": "string"
}, - "hash_algorithm": "SHA_256"
}, - "metadata": {
- "mandate_created_at": "2019-08-24T14:15:22Z",
- "mandate_status": "string",
- "export_requested_by": "string",
- "event_id_filter": "string"
}
}The execution platform — business actions, the tool registry, each tenant's execution policy, and executions
Every taxonomy this deployment loads, with its business actions and
resource patterns. Mandates name these actions, and every tool maps
onto exactly one of them. package is the npm package a taxonomy
comes from; it is not the taxonomy id with a prefix.
{- "taxonomies": [
- {
- "id": "construction",
- "package": "@mandaitor/taxonomy-construction",
- "version": "string",
- "name": "string",
- "description": "string",
- "tags": [
- "string"
], - "actions": [
- {
- "id": "string",
- "label": "string",
- "description": "string",
- "risk_level": "LOW",
- "requires_human_approval": true,
- "tags": [
- "string"
], - "parent_action": "string"
}
], - "resource_patterns": [
- {
- "name": "string",
- "pattern": "string",
- "description": "string"
}
]
}
]
}Every version of every tool definition. A tool is one operation on one
kind of system, mapped to one business action. Definitions are code
and change only through release; tenants enable a version on one of
their connectors with PUT /tenants/{id}/tools/{toolId}.
A tool is available when a loaded taxonomy defines its business
action. An unavailable tool cannot be enabled.
{- "tools": [
- {
- "id": "sap.purchase_requisition.release",
- "version": 1,
- "title": "string",
- "business_action": "procurement.requisition.release",
- "resource_pattern": "procurement:plant:{plant}/requisition:{purchase_requisition}",
- "connector_type": "sap-s4hana",
- "adapter": "string",
- "effect_class": "read",
- "identity_modes": [
- "service_account"
], - "arguments_schema": { },
- "required_facts": {
- "property1": {
- "type": "money",
- "values": [
- "string"
]
}, - "property2": {
- "type": "money",
- "values": [
- "string"
]
}
}, - "preconditions": [
- {
- "fact": "string",
- "equals": "string"
}
], - "returnable_result": [
- "string"
], - "max_approval_window_seconds": 60,
- "available": true,
- "unavailable_reason": "BUSINESS_ACTION_UNKNOWN"
}
]
}Which tool version runs on which of the tenant's connectors, in each
of its environments. version rises by one on every change, in any
environment; an approval's digest records it, so a change to the
policy forces a fresh approval, in every environment. Before the first
enablement, policy_id is null and version is 0.
| id required | string <= 128 characters |
{- "policy_id": "tpol_01J9EXAMPLE",
- "version": 0,
- "updated_at": "2019-08-24T14:15:22Z",
- "updated_by": "string",
- "tools": [
- {
- "tool_id": "string",
- "version": 1,
- "environment": "qas",
- "connector_id": "string",
- "enabled_at": "2019-08-24T14:15:22Z",
- "enabled_by": "string"
}
]
}Enables one version of a tool in one environment, on one of the
tenant's connectors, replacing any version enabled there before, and
raises the policy version. Requires tenant:write. The tool must be
available, and the connector must exist, be of the tool's
connector_type and be in the environment named, default when none
is. An agent's executions use the tool as enabled in the agent's
environment.
| id required | string <= 128 characters |
| toolId required | string <= 128 characters |
| version required | integer >= 1 |
| connector_id required | string <= 68 characters ^con_[A-Za-z0-9]{1,64}$ |
| environment | string <= 32 characters ^[a-z][a-z0-9-]{0,31}$ The environment to enable it in, |
{- "version": 1,
- "connector_id": "string",
- "environment": "qas"
}{- "policy_id": "string",
- "version": 1,
- "tool": {
- "tool_id": "string",
- "version": 1,
- "environment": "qas",
- "connector_id": "string",
- "enabled_at": "2019-08-24T14:15:22Z",
- "enabled_by": "string"
}
}Disables the tool in one environment and raises the policy version.
Requires tenant:write.
| id required | string <= 128 characters |
| toolId required | string <= 128 characters |
| environment | string (Environment) <= 32 characters ^[a-z][a-z0-9-]{0,31}$ Example: environment=qas The environment to disable it in, |
{- "error": "BAD_REQUEST",
- "message": "principal and delegate are required"
}The tenant's executions, newest first, for a person of the tenant: the dashboard's Executions page (roadmap E1.11). Each is the execution as its agent reads it, and what it rested on: the agent, the record and the facts read from it, the approval it needed, and what the write did.
Requires tenant:read in the caller's own tenant, which a dashboard
session has and an API key never does. An agent reads its own
executions with GET /executions/{id} and its session token.
state keeps the executions in that state. Mandaitor filters after
it reads, so a page can hold fewer than limit, even none, with a
next_cursor still to follow; the list ends when there is none.
An execution waiting for an approval that has expired is listed as
stored until it is read or swept, within a minute: its
approval.expires_at is then in the past.
| id required | string <= 128 characters |
| state | string Enum: "AWAITING_APPROVAL" "AUTHORIZED_NOT_EXECUTED" "EXECUTING" "UNKNOWN" "SUCCEEDED" "FAILED" "DENIED" |
| limit | integer [ 1 .. 50 ] Default: 20 |
| cursor | string <= 512 characters The |
{- "items": [
- {
- "contract": "mandaitor.execution/v1",
- "execution_id": "string",
- "state": "DENIED",
- "state_reason": "NO_COVERING_MANDATE",
- "tool": {
- "id": "string",
- "version": 1
}, - "request_digest": "string",
- "decision": {
- "event_id": "string",
- "outcome": "ALLOW",
- "reason": "string",
- "mandate_id": "string",
- "decided_at": "2019-08-24T14:15:22Z"
}, - "approval": {
- "consent_id": "string",
- "digest": "string",
- "expires_at": "2019-08-24T14:15:22Z",
- "approved_at": "2019-08-24T14:15:22Z",
- "approver": "string",
- "require_mfa": true,
- "rules": [
- "AMOUNT_ABOVE_THRESHOLD"
], - "approved_by": "string"
}, - "result": { },
- "receipt": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "agent": {
- "agent_id": "string",
- "did": "string"
}, - "connector_id": "string",
- "arguments": { },
- "purpose": "string",
- "scope": {
- "action": "string",
- "resource": "string"
}, - "facts": { },
- "target": {
- "connector_id": "string",
- "record": "string",
- "version": "string",
- "version_kind": "string"
}, - "authorization": {
- "event_id": "string",
- "mandate_id": "string",
- "pom_digest": "string"
}, - "outcome": {
- "version_after": "string",
- "transaction_ref": "string",
- "target_status": 0,
- "reason": "string",
- "write_acknowledged": true
}, - "reconciliation": {
- "attempts": 0,
- "last_attempt_at": "2019-08-24T14:15:22Z",
- "last_reason": "READ_UNAVAILABLE",
- "next_at": "2019-08-24T14:15:22Z"
}, - "resolution": {
- "resolved_by": "string",
- "resolved_at": "2019-08-24T14:15:22Z",
- "evidence": "string",
- "transaction_ref": "string"
}, - "reservation": {
- "reservation_id": "string",
- "mandate_id": "string",
- "status": "HELD",
- "held_at": "2019-08-24T14:15:22Z",
- "settled_at": "2019-08-24T14:15:22Z",
- "amount": {
- "currency": "string",
- "value": "string"
}, - "counters": [
- {
- "kind": "count",
- "window": "PT1H",
- "window_start": "2019-08-24T14:15:22Z",
- "window_end": "2019-08-24T14:15:22Z",
- "limit": "string",
- "delta": "string"
}
]
}, - "dispatched_at": "2019-08-24T14:15:22Z",
- "completed_at": "2019-08-24T14:15:22Z"
}
], - "next_cursor": "string"
}One execution, for a person of the tenant, authorised as the list
is. Another tenant's execution, or an id that does not exist, is
404. An execution whose approval expired undecided is answered, and
recorded, as DENIED with APPROVAL_EXPIRED, as it is when its
agent reads it.
| id required | string <= 128 characters |
| executionId required | string <= 30 characters ^exe_[0-9A-Z]{26}$ |
{- "contract": "mandaitor.execution/v1",
- "execution_id": "string",
- "state": "DENIED",
- "state_reason": "NO_COVERING_MANDATE",
- "tool": {
- "id": "string",
- "version": 1
}, - "request_digest": "string",
- "decision": {
- "event_id": "string",
- "outcome": "ALLOW",
- "reason": "string",
- "mandate_id": "string",
- "decided_at": "2019-08-24T14:15:22Z"
}, - "approval": {
- "consent_id": "string",
- "digest": "string",
- "expires_at": "2019-08-24T14:15:22Z",
- "approved_at": "2019-08-24T14:15:22Z",
- "approver": "string",
- "require_mfa": true,
- "rules": [
- "AMOUNT_ABOVE_THRESHOLD"
], - "approved_by": "string"
}, - "result": { },
- "receipt": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "agent": {
- "agent_id": "string",
- "did": "string"
}, - "connector_id": "string",
- "arguments": { },
- "purpose": "string",
- "scope": {
- "action": "string",
- "resource": "string"
}, - "facts": { },
- "target": {
- "connector_id": "string",
- "record": "string",
- "version": "string",
- "version_kind": "string"
}, - "authorization": {
- "event_id": "string",
- "mandate_id": "string",
- "pom_digest": "string"
}, - "outcome": {
- "version_after": "string",
- "transaction_ref": "string",
- "target_status": 0,
- "reason": "string",
- "write_acknowledged": true
}, - "reconciliation": {
- "attempts": 0,
- "last_attempt_at": "2019-08-24T14:15:22Z",
- "last_reason": "READ_UNAVAILABLE",
- "next_at": "2019-08-24T14:15:22Z"
}, - "resolution": {
- "resolved_by": "string",
- "resolved_at": "2019-08-24T14:15:22Z",
- "evidence": "string",
- "transaction_ref": "string"
}, - "reservation": {
- "reservation_id": "string",
- "mandate_id": "string",
- "status": "HELD",
- "held_at": "2019-08-24T14:15:22Z",
- "settled_at": "2019-08-24T14:15:22Z",
- "amount": {
- "currency": "string",
- "value": "string"
}, - "counters": [
- {
- "kind": "count",
- "window": "PT1H",
- "window_start": "2019-08-24T14:15:22Z",
- "window_end": "2019-08-24T14:15:22Z",
- "limit": "string",
- "delta": "string"
}
]
}, - "dispatched_at": "2019-08-24T14:15:22Z",
- "completed_at": "2019-08-24T14:15:22Z"
}A person of the tenant records the outcome of an UNKNOWN
execution that no read-back could establish (roadmap E2.1), after
looking at the target system. Requires tenant:write in the
caller's own tenant, and a person's session: an API key or an
agent is refused with 403 NOT_A_PERSON.
The target's own record comes first. Mandaitor reads the record
back once more before it records anything. If that read-back finds
the write applied, the execution is SUCCEEDED; if it proves the
write absent (and the target never acknowledged it), FAILED; either
way with RESOLVED_BY_READ_BACK and a receipt, whatever you sent.
When that differs from your outcome, the answer is 409
OUTCOME_CONTRADICTED, with the execution as it now is.
Otherwise your outcome stands, as SUCCEEDED or FAILED with
RESOLVED_BY_OPERATOR, your evidence in resolution, and no
receipt: Mandaitor signs only what it read back. Your resolution
and evidence go on the audit trail. A FAILED execution tells its
agent it may ask again, and a new request is a new write.
| id required | string <= 128 characters |
| executionId required | string <= 30 characters ^exe_[0-9A-Z]{26}$ |
| outcome required | string Enum: "SUCCEEDED" "FAILED"
|
| evidence required | string [ 1 .. 2000 ] characters What you checked, and what you found. It goes on the audit trail. |
| transaction_ref | string [ 1 .. 256 ] characters The target's own reference for the write, if you found one. |
{- "outcome": "SUCCEEDED",
- "evidence": "ME53N shows 10000124 not released; its change log has no entry after 12:00",
- "transaction_ref": "string"
}{- "contract": "mandaitor.execution/v1",
- "execution_id": "string",
- "state": "DENIED",
- "state_reason": "NO_COVERING_MANDATE",
- "tool": {
- "id": "string",
- "version": 1
}, - "request_digest": "string",
- "decision": {
- "event_id": "string",
- "outcome": "ALLOW",
- "reason": "string",
- "mandate_id": "string",
- "decided_at": "2019-08-24T14:15:22Z"
}, - "approval": {
- "consent_id": "string",
- "digest": "string",
- "expires_at": "2019-08-24T14:15:22Z",
- "approved_at": "2019-08-24T14:15:22Z",
- "approver": "string",
- "require_mfa": true,
- "rules": [
- "AMOUNT_ABOVE_THRESHOLD"
], - "approved_by": "string"
}, - "result": { },
- "receipt": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "agent": {
- "agent_id": "string",
- "did": "string"
}, - "connector_id": "string",
- "arguments": { },
- "purpose": "string",
- "scope": {
- "action": "string",
- "resource": "string"
}, - "facts": { },
- "target": {
- "connector_id": "string",
- "record": "string",
- "version": "string",
- "version_kind": "string"
}, - "authorization": {
- "event_id": "string",
- "mandate_id": "string",
- "pom_digest": "string"
}, - "outcome": {
- "version_after": "string",
- "transaction_ref": "string",
- "target_status": 0,
- "reason": "string",
- "write_acknowledged": true
}, - "reconciliation": {
- "attempts": 0,
- "last_attempt_at": "2019-08-24T14:15:22Z",
- "last_reason": "READ_UNAVAILABLE",
- "next_at": "2019-08-24T14:15:22Z"
}, - "resolution": {
- "resolved_by": "string",
- "resolved_at": "2019-08-24T14:15:22Z",
- "evidence": "string",
- "transaction_ref": "string"
}, - "reservation": {
- "reservation_id": "string",
- "mandate_id": "string",
- "status": "HELD",
- "held_at": "2019-08-24T14:15:22Z",
- "settled_at": "2019-08-24T14:15:22Z",
- "amount": {
- "currency": "string",
- "value": "string"
}, - "counters": [
- {
- "kind": "count",
- "window": "PT1H",
- "window_start": "2019-08-24T14:15:22Z",
- "window_end": "2019-08-24T14:15:22Z",
- "limit": "string",
- "delta": "string"
}
]
}, - "dispatched_at": "2019-08-24T14:15:22Z",
- "completed_at": "2019-08-24T14:15:22Z"
}An agent asks Mandaitor to perform one typed business operation, sent as
a mandaitor.tool-request/v1. The agent names the tool and the record
(arguments, identifiers only). The facts a decision turns on, such as
the amount or the plant, are read from the target system, never taken
from the agent.
Authenticated with the agent's session token from POST /mcp/token,
bound to the agent's key, and nothing else: Authorization: DPoP mcp_…
with a fresh DPoP proof for this request (McpSessionDPoP). A bearer
session, API keys, user tokens, PoMs and consent ids are refused with
401. Each agent may send at most 30 requests a minute (429
RATE_LIMITED).
Idempotency. (tenant, agent, idempotency_key) names at most one
execution, until 24 hours after it reaches a final state.
IDEMPOTENCY_CONFLICT.IDEMPOTENCY_IN_PROGRESS, naming the execution. Retry after
Retry-After.purpose and mandate_id are not part of what makes two requests the
same.
A denial is not an error. It is 201 with the execution in DENIED,
recorded on the audit chain before it is returned. When the audit
event cannot be written, nothing is created and the answer is 503
AUDIT_UNAVAILABLE.
Which mandates count. The decision reads every ACTIVE mandate
naming the agent as its delegate, by its DID or its agent id. An
ALLOW mandate counts only if it names the tool's business action
exactly and was created or approved from a person's session. A
DENY mandate counts whoever made it, and wins. More than 100 such
mandates is DENIED with TOO_MANY_MANDATES: the decision never
rests on part of them. mandate_id is a hint, and a hint at a
mandate that does not count is DENIED with HINT_NOT_COVERING.
The record. The decision reads the record the arguments name from
the target system, and decides on its facts: the mandate's limits,
thresholds and validity, and the tool's preconditions. When the record
cannot be read, nothing is decided: 503 TARGET_UNAVAILABLE.
An ALLOW is answered once it is recorded. The answer is 201
with the execution in AUTHORIZED_NOT_EXECUTED, and nothing is
written yet. Mandaitor's worker then takes it from a queue, usually
within seconds: it rechecks it against the mandates and the record as
they are now, writes it once, and reads it back. Read the outcome
with GET /executions/{id}: SUCCEEDED, FAILED, or UNKNOWN
when the target's answer and the read-back leave it open. DENIED
means the recheck refused it, and decision is then that refusal.
Every step is recorded on the audit chain before it is taken, and a
step that cannot be recorded is not taken: the execution waits in
AUTHORIZED_NOT_EXECUTED, with nothing written, or in EXECUTING,
and the worker takes it up again.
An UNKNOWN execution is read back again, a minute later and
then less and less often, for about 41 hours. Nothing is ever written
again. A read-back that finds the write applied, or proves it absent,
makes it SUCCEEDED or FAILED with a receipt. When none does, it
stays UNKNOWN until a person of the tenant resolves it.
A decision that needs a person's approval waits for it. The
execution is answered in AWAITING_APPROVAL, with nothing written.
approval names the consent in the approver's inbox, the approval
digest the approver must send back, and when the approval expires (24
hours at most, never past the mandate's own expiry). The approver
decides it with POST /executions/{id}/approval, and an approved
execution is then rechecked, written and read back by the worker. An approval that
expires undecided ends the execution in DENIED with
APPROVAL_EXPIRED. An agent may raise 20 approval requests a day;
past that a decision that needs one is DENIED with
APPROVAL_LIMIT_REACHED: the excess is refused, not queued.
Phase 1. Executions run only against Mandaitor's hosted sandboxes:
a tool whose connector points elsewhere is DENIED with
CONNECTOR_NOT_PERMITTED.
| DPoP required | string <= 4096 characters A fresh DPoP proof (RFC 9449) for this request and this session
token, signed by the key the session is bound to ( |
| contract required | string Value: "mandaitor.tool-request/v1" |
| tool required | string [ 1 .. 128 ] characters |
| tool_version | integer >= 1 Pins a definition version. It must be the version the tenant enabled. |
required | object Identifiers only, checked against the tool's |
| idempotency_key required | string [ 8 .. 128 ] characters ^[\x21-\x7E]{8,128}$ 8 to 128 visible ASCII characters, chosen by the agent. |
| mandate_id | string <= 68 characters ^mdt_[A-Za-z0-9]{1,64}$ The mandate the agent believes covers the call. A hint only: the decision considers every mandate that names the agent. |
| purpose | string <= 500 characters Shown to an approver. Never used in the decision. |
{- "contract": "mandaitor.tool-request/v1",
- "tool": "sap.purchase_requisition.release",
- "tool_version": 1,
- "arguments": {
- "purchase_requisition": "10000124"
}, - "idempotency_key": "6f1c2c8e-3b0e-4d5e-9d61-1d4a8f0b7c21",
- "mandate_id": "string",
- "purpose": "string"
}{- "contract": "mandaitor.execution/v1",
- "execution_id": "string",
- "state": "DENIED",
- "state_reason": "NO_COVERING_MANDATE",
- "tool": {
- "id": "string",
- "version": 1
}, - "request_digest": "string",
- "decision": {
- "event_id": "string",
- "outcome": "ALLOW",
- "reason": "string",
- "mandate_id": "string"
}, - "approval": {
- "consent_id": "string",
- "digest": "string",
- "expires_at": "2019-08-24T14:15:22Z",
- "approved_at": "2019-08-24T14:15:22Z"
}, - "result": { },
- "receipt": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}Authenticated like POST /executions. An agent reads only its own
executions; another agent's or another tenant's execution is 404, as is
an id that does not exist. An execution whose approval expired
undecided is answered, and recorded, as DENIED with
APPROVAL_EXPIRED.
This is how an agent learns the outcome of what it asked for: read
it until it is final (DENIED, SUCCEEDED, FAILED) or waits for
an approval. A few seconds between reads is enough; the SDK's
waitForExecution does it.
| id required | string <= 30 characters ^exe_[0-9A-Z]{26}$ |
| DPoP required | string <= 4096 characters A fresh DPoP proof (RFC 9449) for this request and this session
token, signed by the key the session is bound to ( |
{- "contract": "mandaitor.execution/v1",
- "execution_id": "string",
- "state": "DENIED",
- "state_reason": "NO_COVERING_MANDATE",
- "tool": {
- "id": "string",
- "version": 1
}, - "request_digest": "string",
- "decision": {
- "event_id": "string",
- "outcome": "ALLOW",
- "reason": "string",
- "mandate_id": "string"
}, - "approval": {
- "consent_id": "string",
- "digest": "string",
- "expires_at": "2019-08-24T14:15:22Z",
- "approved_at": "2019-08-24T14:15:22Z"
}, - "result": { },
- "receipt": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}The person an execution's approval names decides it. Only a person's
session is accepted: a dashboard session, or one from the tenant's
own identity provider. An API key or an agent is refused with 403
NOT_A_PERSON, and anyone the approval does not name with 403
NOT_THE_APPROVER. When the mandate requires MFA, the session must
have been signed in with it: every dashboard session is, and a
session from the tenant's identity provider is when its token's
amr says mfa (403 MFA_REQUIRED otherwise).
To approve, send the approval_digest you were shown. The
approval is granted only when it equals the digest the approval was
raised with and one computed again from a fresh read of the record,
under the mandates and the execution policy as they are now. The
answer is the execution in AUTHORIZED_NOT_EXECUTED, approved.
Mandaitor's worker then rechecks it, writes it once and reads it
back, as for a decision that needs no approval; the dashboard and
GET /tenants/{id}/executions/{executionId} show the outcome.
When something changed, nothing is written:
DIGEST_MISMATCH carrying the execution with it.DENIED with RECORD_CHANGED, and the agent asks
again (409 DIGEST_MISMATCH).DENIED (409 EXECUTION_DENIED).To reject, send REJECT; no digest is needed. The execution is
DENIED with APPROVAL_REJECTED.
An approval is decided once. A second, concurrent decision is
refused with 409 APPROVAL_IN_PROGRESS before it records anything.
| id required | string <= 30 characters ^exe_[0-9A-Z]{26}$ |
| decision required | string Enum: "APPROVE" "REJECT" |
| approval_digest | string^sha-256:[A-Za-z0-9_-]{43}$ Required to approve. The digest you were shown. |
| consent_id | string The approval you were shown. One a newer approval replaced is refused. |
| comment | string <= 1000 characters |
{- "decision": "APPROVE",
- "approval_digest": "string",
- "consent_id": "string",
- "comment": "string"
}{- "contract": "mandaitor.execution/v1",
- "execution_id": "string",
- "state": "DENIED",
- "state_reason": "NO_COVERING_MANDATE",
- "tool": {
- "id": "string",
- "version": 1
}, - "request_digest": "string",
- "decision": {
- "event_id": "string",
- "outcome": "ALLOW",
- "reason": "string",
- "mandate_id": "string"
}, - "approval": {
- "consent_id": "string",
- "digest": "string",
- "expires_at": "2019-08-24T14:15:22Z",
- "approved_at": "2019-08-24T14:15:22Z"
}, - "result": { },
- "receipt": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}Aggregated oversight indicators for management roles — portfolio posture rather than individual mandates
Aggregated governance indicators over a bounded window, for oversight roles rather than operators. Answers "is the delegation posture acceptable, and where is it worst" — a question the per-mandate surfaces cannot.
Rates carry their denominators. Every rate reports numerator and
denominator, and value is null when the denominator is zero. A
denial rate of zero from four checks and one from no checks are different
statements; a bare 0 would conflate them.
Coverage is explicit. The read is bounded in both window length and
index pages. When either bound truncates the read, coverage.truncated
is true and a WINDOW_TRUNCATED caveat is present. Callers must not
present figures as complete without checking it.
Caveats are part of the answer. They flag conditions that make an indicator misleading — no verifications in the window, a small latency sample, unassigned mandates, unscoreable risk profiles. A dashboard that renders the numbers and drops the caveats will mislead its reader.
| window_days | integer [ 1 .. 90 ] Default: 30 Length of the reporting window in days. Rejected rather than clamped when out of range, so the response always answers the question that was asked. |
{- "tenant_id": "string",
- "generated_at": "2019-08-24T14:15:22Z",
- "coverage": {
- "window_start": "2019-08-24T14:15:22Z",
- "window_end": "2019-08-24T14:15:22Z",
- "events_scanned": 0,
- "pages_scanned": 0,
- "truncated": true,
- "earliest_event": "2019-08-24T14:15:22Z",
- "latest_event": "2019-08-24T14:15:22Z"
}, - "boundary_adherence": {
- "verification_allowed": 0,
- "verification_denied": 0,
- "verification_total": 0,
- "denial_rate": {
- "value": 0.25,
- "numerator": 1,
- "denominator": 4
}, - "mandates_with_denials": 0
}, - "human_oversight": {
- "consent_requested": 0,
- "consent_approved": 0,
- "consent_rejected": 0,
- "consent_auto_approved": 0,
- "consent_expired": 0,
- "escalations_triggered": 0,
- "human_review_rate": {
- "value": 0.25,
- "numerator": 1,
- "denominator": 4
}, - "rejection_rate": {
- "value": 0.25,
- "numerator": 1,
- "denominator": 4
}
}, - "response_latency": {
- "sample_size": 0,
- "denials_without_containment": 0,
- "median_seconds": 0,
- "p90_seconds": 0
}, - "risk_distribution": {
- "low": 0,
- "moderate": 0,
- "high": 0,
- "critical": 0,
- "unclassified": 0,
- "invalid": 0,
- "classification_coverage": {
- "value": 0.25,
- "numerator": 1,
- "denominator": 4
}, - "eu_ai_act_high_risk_declared": 0
}, - "org_breakdown": [
- {
- "unit_id": "string",
- "unit_name": "string",
- "owner_subject_id": "string",
- "mandate_count": 0,
- "active_mandate_count": 0,
- "classified_mandate_count": 0,
- "peak_risk_band": "low",
- "verification_denied": 0,
- "escalations_triggered": 0
}
], - "caveats": [
- {
- "code": "WINDOW_TRUNCATED",
- "message": "string"
}
]
}| id required | string |
{- "tenant_id": "string",
- "identity_providers": {
- "enabled_providers": [
- "API_KEY"
], - "auth0": {
- "domain": "your-tenant.auth0.com",
- "audience": "string",
- "client_id": "string"
}, - "entra": {
- "tenant_id": "34f5c98e-f430-457b-a812-92637d0c6fd0",
- "client_id": "5b3fa7ba-57d3-4017-a65b-d57dcd2db643"
}, - "eudi": {
- "rp_id": "string",
- "presentation_policies": [
- "string"
]
}, - "google": {
- "client_id": "xxxx.apps.googleusercontent.com",
- "hosted_domain": "company.com"
}, - "aws_iam_idc": {
- "audience": "string"
}, - "generic_oidc": {
- "name": "Keycloak",
- "audience": "mandaitor-client",
- "subject_prefix": "keycloak"
}
}
}| id required | string |
| enabled_providers required | Array of strings Items Enum: "API_KEY" "COGNITO" "EUDI_WALLET" "AUTH0" "OKTA" "ENTRA_ID" "GOOGLE" "AWS_IAM_IDC" "GENERIC_OIDC" |
object | |
object | |
object | |
object | |
object | |
object | |
object |
{- "enabled_providers": [
- "API_KEY"
], - "auth0": {
- "domain": "your-tenant.auth0.com",
- "audience": "string",
- "client_id": "string"
}, - "entra": {
- "tenant_id": "34f5c98e-f430-457b-a812-92637d0c6fd0",
- "client_id": "5b3fa7ba-57d3-4017-a65b-d57dcd2db643"
}, - "eudi": {
- "rp_id": "string",
- "presentation_policies": [
- "string"
]
}, - "google": {
- "client_id": "xxxx.apps.googleusercontent.com",
- "hosted_domain": "company.com"
}, - "aws_iam_idc": {
- "audience": "string"
}, - "generic_oidc": {
- "name": "Keycloak",
- "audience": "mandaitor-client",
- "subject_prefix": "keycloak"
}
}{- "tenant_id": "string",
- "identity_providers": {
- "enabled_providers": [
- "API_KEY"
], - "auth0": {
- "domain": "your-tenant.auth0.com",
- "audience": "string",
- "client_id": "string"
}, - "entra": {
- "tenant_id": "34f5c98e-f430-457b-a812-92637d0c6fd0",
- "client_id": "5b3fa7ba-57d3-4017-a65b-d57dcd2db643"
}, - "eudi": {
- "rp_id": "string",
- "presentation_policies": [
- "string"
]
}, - "google": {
- "client_id": "xxxx.apps.googleusercontent.com",
- "hosted_domain": "company.com"
}, - "aws_iam_idc": {
- "audience": "string"
}, - "generic_oidc": {
- "name": "Keycloak",
- "audience": "mandaitor-client",
- "subject_prefix": "keycloak"
}
}
}Returns the persisted role-assignment policy rows for a tenant. Each
assignment binds a canonical subject ID to tenant-scoped roles and
derived effective permissions. The tenant path parameter must match the
authenticated caller unless the caller is a platform administrator.
Requires tenant:read permission.
| id required | string |
{- "tenant_id": "string",
- "assignments": [
- {
- "tenant_id": "string",
- "subject_id": "eudi:DE/1234567890abcdef",
- "subject_type": "NATURAL_PERSON",
- "display_name": "Amina Bauer",
- "email": "amina.bauer@example.com",
- "roles": [
- "platform_admin"
], - "permissions": [
- "*"
], - "status": "ACTIVE",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "assigned_by": "eudi:DE/admin-subject",
- "revoked_at": "2019-08-24T14:15:22Z",
- "revoked_by": "string"
}
]
}Creates or replaces the tenant-scoped role assignment for the canonical
subject ID in the path. platform_admin and platform:* grants are
rejected because tenant policy can only delegate tenant-scoped access.
Role-derived permissions and any explicit tenant permissions are stored
as the assignment's effective permission set. Emits an immutable
TENANT_ROLE_ASSIGNED audit event. Requires tenant:write permission.
| id required | string |
| subjectId required | string [ 3 .. 256 ] characters ^[A-Za-z0-9._:@/-]{3,256}$ Example: eudi:DE/1234567890abcdef URL-encoded canonical subject ID resolved by the authorizer. |
| subject_type | string Default: "NATURAL_PERSON" Enum: "NATURAL_PERSON" "LEGAL_ENTITY" "SERVICE" "AGENT" |
| display_name | string [ 1 .. 200 ] characters |
string <email> <= 320 characters | |
| roles required | Array of strings (RbacRole) [ 1 .. 5 ] items Items Enum: "platform_admin" "tenant_admin" "tenant_operator" "tenant_auditor" "tenant_viewer" "service" Tenant-assignable RBAC roles. |
| permissions | Array of strings (RbacPermission) <= 30 items Items Enum: "*" "platform:admin" "platform:onboarding:read" "platform:onboarding:write" "platform:tenants:read" "platform:tenants:write" "tenant:read" "tenant:write" "tenant:billing:read" "tenant:usage:read" "tenant:audit:read" "tenant:api-keys:read" "tenant:api-keys:write" "mandates:read" "mandates:write" "verify:execute" "events:read" "events:export" "evidence:read" "evidence:write" Optional explicit tenant-scoped permissions merged with role-derived grants. Platform permissions are rejected. |
{- "subject_type": "NATURAL_PERSON",
- "display_name": "Amina Bauer",
- "email": "amina.bauer@example.com",
- "roles": [
- "tenant_auditor",
- "tenant_viewer"
], - "permissions": [
- "events:read",
- "evidence:read"
]
}{- "tenant_id": "string",
- "assignment": {
- "tenant_id": "string",
- "subject_id": "eudi:DE/1234567890abcdef",
- "subject_type": "NATURAL_PERSON",
- "display_name": "Amina Bauer",
- "email": "amina.bauer@example.com",
- "roles": [
- "platform_admin"
], - "permissions": [
- "*"
], - "status": "ACTIVE",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "assigned_by": "eudi:DE/admin-subject",
- "revoked_at": "2019-08-24T14:15:22Z",
- "revoked_by": "string"
}
}Revokes the tenant-scoped role assignment for the canonical subject ID
by deleting the persisted policy row. The next authorizer evaluation no
longer enriches the subject with those tenant roles or permissions.
Emits an immutable TENANT_ROLE_REVOKED audit event. The operation is
idempotent. Requires tenant:write permission.
| id required | string |
| subjectId required | string [ 3 .. 256 ] characters ^[A-Za-z0-9._:@/-]{3,256}$ Example: oidc:okta:00u123456789 URL-encoded canonical subject ID resolved by the authorizer. |
{- "error": "BAD_REQUEST",
- "message": "principal and delegate are required"
}Returns the authenticated subject's workspace access for the current tenant context. If no explicit entitlement row exists, the response is derived from the tenant RBAC context: the Product Workspace is enabled by default, while the Partner & Project Workspace is enabled by default only for tenant administrators and platform administrators. Requires Cognito JWT or another authorizer-supported tenant principal.
{- "tenant_id": "tenant_demo",
- "user_id": "eudi:DE/1234567890abcdef",
- "workspaces": {
- "product_workspace": true,
- "partner_project_workspace": true
}, - "status": "ACTIVE",
- "granted_by": "eudi:DE/admin-subject",
- "granted_at": "2019-08-24T14:15:22Z",
- "updated_by": "eudi:DE/admin-subject",
- "updated_at": "2019-08-24T14:15:22Z",
- "source": "explicit"
}Returns workspace access for the URL-encoded canonical subject ID in the
current tenant. Reading another subject's entitlement requires
tenant:read permission. If no explicit entitlement exists, default
workspace access is resolved using the caller's tenant RBAC context.
| subjectId required | string [ 3 .. 256 ] characters ^[A-Za-z0-9._:@/-]{3,256}$ Example: eudi:DE/1234567890abcdef URL-encoded canonical subject ID resolved by the authorizer. |
{- "tenant_id": "tenant_demo",
- "user_id": "eudi:DE/1234567890abcdef",
- "workspaces": {
- "product_workspace": true,
- "partner_project_workspace": true
}, - "status": "ACTIVE",
- "granted_by": "eudi:DE/admin-subject",
- "granted_at": "2019-08-24T14:15:22Z",
- "updated_by": "eudi:DE/admin-subject",
- "updated_at": "2019-08-24T14:15:22Z",
- "source": "explicit"
}Creates or replaces the explicit workspace entitlement row for the
URL-encoded canonical subject ID in the current tenant. Setting both
workspace flags to false stores the entitlement as REVOKED and causes
both workspaces to be disabled in the response. Emits an immutable
WORKSPACE_ENTITLEMENT_UPDATED audit event. Requires tenant:write
permission.
| subjectId required | string [ 3 .. 256 ] characters ^[A-Za-z0-9._:@/-]{3,256}$ Example: oidc:okta:00u123456789 URL-encoded canonical subject ID resolved by the authorizer. |
| product_workspace required | boolean Grants access to the Product Workspace when the entitlement is active. |
| partner_project_workspace required | boolean Grants access to the Partner & Project Workspace when the entitlement is active. |
{- "product_workspace": true,
- "partner_project_workspace": true
}{- "tenant_id": "tenant_demo",
- "user_id": "eudi:DE/1234567890abcdef",
- "workspaces": {
- "product_workspace": true,
- "partner_project_workspace": true
}, - "status": "ACTIVE",
- "granted_by": "eudi:DE/admin-subject",
- "granted_at": "2019-08-24T14:15:22Z",
- "updated_by": "eudi:DE/admin-subject",
- "updated_at": "2019-08-24T14:15:22Z",
- "source": "explicit"
}Returns workspace access for the URL-encoded canonical subject ID within
the tenant identified by the path parameter. Tenant-scoped callers may
only use their own tenant ID unless the authorizer grants platform-admin
privileges. Reading another subject's entitlement requires tenant:read
permission. If no explicit entitlement exists, default workspace access
is resolved using the caller's tenant RBAC context.
| id required | string [ 3 .. 128 ] characters ^[A-Za-z0-9._:-]{3,128}$ Example: tnt_mandaitor_053cb127 Tenant ID whose user workspace entitlements should be read. |
| subjectId required | string [ 3 .. 256 ] characters ^[A-Za-z0-9._:@/-]{3,256}$ Example: oliver@mandaitor.io URL-encoded canonical subject ID or email address recorded in tenant access assignments. |
{- "tenant_id": "tenant_demo",
- "user_id": "eudi:DE/1234567890abcdef",
- "workspaces": {
- "product_workspace": true,
- "partner_project_workspace": true
}, - "status": "ACTIVE",
- "granted_by": "eudi:DE/admin-subject",
- "granted_at": "2019-08-24T14:15:22Z",
- "updated_by": "eudi:DE/admin-subject",
- "updated_at": "2019-08-24T14:15:22Z",
- "source": "explicit"
}Creates or replaces the explicit workspace entitlement row for the
URL-encoded canonical subject ID within the tenant identified by the path
parameter. Tenant-scoped callers may only use their own tenant ID unless
the authorizer grants platform-admin privileges. Setting both workspace
flags to false stores the entitlement as REVOKED and causes both
workspaces to be disabled in the response. Emits an immutable
WORKSPACE_ENTITLEMENT_UPDATED audit event. Requires tenant:write
permission.
| id required | string [ 3 .. 128 ] characters ^[A-Za-z0-9._:-]{3,128}$ Example: tnt_mandaitor_053cb127 Tenant ID whose user workspace entitlements should be updated. |
| subjectId required | string [ 3 .. 256 ] characters ^[A-Za-z0-9._:@/-]{3,256}$ Example: oliver@mandaitor.io URL-encoded canonical subject ID or email address recorded in tenant access assignments. |
| product_workspace required | boolean Grants access to the Product Workspace when the entitlement is active. |
| partner_project_workspace required | boolean Grants access to the Partner & Project Workspace when the entitlement is active. |
{- "product_workspace": true,
- "partner_project_workspace": true
}{- "tenant_id": "tenant_demo",
- "user_id": "eudi:DE/1234567890abcdef",
- "workspaces": {
- "product_workspace": true,
- "partner_project_workspace": true
}, - "status": "ACTIVE",
- "granted_by": "eudi:DE/admin-subject",
- "granted_at": "2019-08-24T14:15:22Z",
- "updated_by": "eudi:DE/admin-subject",
- "updated_at": "2019-08-24T14:15:22Z",
- "source": "explicit"
}Creates a new delegation mandate between a principal and a delegate. The mandate defines the scope of delegated authority, optional constraints, and an expiration date. A KMS-signed audit event is emitted on success.
required | object (Subject) Represents an entity (human, AI agent, service, or organization) that participates in a mandate as either principal or delegate. |
required | object (Subject) Represents an entity (human, AI agent, service, or organization) that participates in a mandate as either principal or delegate. |
required | object (Scope) Defines the actions, resources, and effect (ALLOW/DENY) that a mandate authorizes, with optional conditions. |
object (Constraints) Optional restrictions on mandate usage. Not every key here is enforced.
These keys are deprecated as of 2026-09-10 and will be rejected at creation after the 90-day deprecation window for Stable endpoints. See the Beta Limitations page. | |
| metadata | object |
| expires_at | string <date-time> When the mandate stops authorizing; must be in the future. Enforced
together with |
| taxonomy_id | string Taxonomy identifier to validate the mandate scope against (e.g., "construction", "realestate", "venture"). |
| taxonomy_version | string^[a-z][a-z0-9-]*(@\d+\.\d+\.\d+(-[a-z0-9.]+)?... Versioned taxonomy reference. Accepts either a plain ID (uses latest version)
or |
| require_approval | boolean Default: false When true, the mandate starts in PENDING_APPROVAL status and requires explicit approval before becoming ACTIVE. |
object (MandateIntent) @experimental Intent declaration for drift detection. Allows the principal to express the intended purpose and expected behavioral clusters for a mandate. Used by the drift detection engine to compute semantic distance scores. | |
object (VUIRequest) @experimental Verifiable User Instruction input. Captures the human's original instruction at mandate creation time. The instruction text will be encrypted at rest and its SHA-256 digest embedded into the Proof-of-Mandate Verifiable Credential. |
{- "principal": {
- "type": "HUMAN",
- "subject_id": "construction:agent:validate-agent-v2",
- "display_name": "string",
- "identity_provider": "string",
- "identity_token_hash": "string"
}, - "delegate": {
- "type": "HUMAN",
- "subject_id": "construction:agent:validate-agent-v2",
- "display_name": "string",
- "identity_provider": "string",
- "identity_token_hash": "string"
}, - "scope": {
- "actions": [
- "construction.validation.approve"
], - "resources": [
- "construction:project:*/zone:*/installation:*"
], - "effect": "ALLOW",
- "conditions": { }
}, - "constraints": {
- "max_uses": 0,
- "time_window": {
- "start": "2019-08-24T14:15:22Z",
- "end": "2019-08-24T14:15:22Z"
}, - "time": {
- "not_before": "2019-08-24T14:15:22Z",
- "expires_at": "2019-08-24T14:15:22Z"
}, - "geo_fence": {
- "allowed_regions": [
- "string"
]
}, - "require_mfa": true,
- "ip_whitelist": [
- "string"
], - "transaction_limits": {
- "max_amount": {
- "currency": "string",
- "value": "string"
}, - "max_total": [
- {
- "amount": {
- "currency": "string",
- "value": "string"
}, - "window": "PT1H"
}
]
}, - "rate_limits": {
- "max_count": [
- {
- "count": 1,
- "window": "PT1H"
}
]
}, - "escalation_rules": {
- "deviation_above_percent": 0,
- "amount_above": {
- "currency": "string",
- "value": "string"
}, - "escalate_to": "string",
- "escalation_method": "string"
}
}, - "metadata": { },
- "expires_at": "2019-08-24T14:15:22Z",
- "taxonomy_id": "construction",
- "taxonomy_version": "construction@2.0.0",
- "require_approval": false,
- "intent": {
- "purpose": "Automated structural validation of Zone EG installations",
- "expected_clusters": [
- "validation",
- "inspection"
], - "drift_threshold": 0.7
}, - "vui": {
- "instruction_text": "Bestelle Büromaterial bis 500€",
- "instruction_channel": "chat",
- "principal_confirmation": {
- "method": "explicit_approval",
- "timestamp": "2019-08-24T14:15:22Z",
- "evidence_ref": "string"
}, - "constraints_derived": {
- "max_amount": 0,
- "allowed_actions": [
- "string"
], - "time_bound": "2019-08-24T14:15:22Z"
}
}
}{- "mandate_id": "mdt_01HXYZ...",
- "tenant_id": "string",
- "version": 0,
- "status": "DRAFT",
- "principal": {
- "type": "HUMAN",
- "subject_id": "construction:agent:validate-agent-v2",
- "display_name": "string",
- "identity_provider": "string",
- "identity_token_hash": "string"
}, - "delegate": {
- "type": "HUMAN",
- "subject_id": "construction:agent:validate-agent-v2",
- "display_name": "string",
- "identity_provider": "string",
- "identity_token_hash": "string"
}, - "scope": {
- "actions": [
- "construction.validation.approve"
], - "resources": [
- "construction:project:*/zone:*/installation:*"
], - "effect": "ALLOW",
- "conditions": { }
}, - "constraints": {
- "max_uses": 0,
- "time_window": {
- "start": "2019-08-24T14:15:22Z",
- "end": "2019-08-24T14:15:22Z"
}, - "time": {
- "not_before": "2019-08-24T14:15:22Z",
- "expires_at": "2019-08-24T14:15:22Z"
}, - "geo_fence": {
- "allowed_regions": [
- "string"
]
}, - "require_mfa": true,
- "ip_whitelist": [
- "string"
], - "transaction_limits": {
- "max_amount": {
- "currency": "string",
- "value": "string"
}, - "max_total": [
- {
- "amount": {
- "currency": "string",
- "value": "string"
}, - "window": "PT1H"
}
]
}, - "rate_limits": {
- "max_count": [
- {
- "count": 1,
- "window": "PT1H"
}
]
}, - "escalation_rules": {
- "deviation_above_percent": 0,
- "amount_above": {
- "currency": "string",
- "value": "string"
}, - "escalate_to": "string",
- "escalation_method": "string"
}
}, - "proof": {
- "creation_method": "API_KEY",
- "issuer": "string",
- "created_by": "string",
- "created_by_type": "NATURAL_PERSON",
- "created_by_auth_method": "string",
- "mandate_hash": "string",
- "signature": "string",
- "eidas_loa": "string"
}, - "metadata": { },
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "expires_at": "2019-08-24T14:15:22Z",
- "vui": {
- "instruction_text": "string",
- "instruction_hash": "a1b2c3d4e5f6...",
- "instruction_timestamp": "2019-08-24T14:15:22Z",
- "instruction_channel": "chat",
- "principal_confirmation": {
- "method": "explicit_approval",
- "timestamp": "2019-08-24T14:15:22Z",
- "evidence_ref": "string"
}, - "constraints_derived": {
- "max_amount": 0,
- "allowed_actions": [
- "string"
], - "time_bound": "2019-08-24T14:15:22Z"
}
}, - "approval": {
- "approved_by": "string",
- "approved_by_type": "NATURAL_PERSON",
- "approved_by_auth_method": "string",
- "approved_at": "2019-08-24T14:15:22Z"
}, - "unsupported_constraints": [
- "string"
], - "unsupported_constraints_message": "string"
}Returns a paginated list of mandates for the authenticated tenant. Supports optional filtering by status and cursor-based pagination.
| status | string Enum: "DRAFT" "ACTIVE" "SUSPENDED" "REVOKED" "EXPIRED" |
| limit | integer [ 1 .. 200 ] Default: 50 |
| cursor | string Base64url-encoded pagination cursor |
{- "items": [
- {
- "mandate_id": "mdt_01HXYZ...",
- "tenant_id": "string",
- "version": 0,
- "status": "DRAFT",
- "principal": {
- "type": "HUMAN",
- "subject_id": "construction:agent:validate-agent-v2",
- "display_name": "string",
- "identity_provider": "string",
- "identity_token_hash": "string"
}, - "delegate": {
- "type": "HUMAN",
- "subject_id": "construction:agent:validate-agent-v2",
- "display_name": "string",
- "identity_provider": "string",
- "identity_token_hash": "string"
}, - "scope": {
- "actions": [
- "construction.validation.approve"
], - "resources": [
- "construction:project:*/zone:*/installation:*"
], - "effect": "ALLOW",
- "conditions": { }
}, - "constraints": {
- "max_uses": 0,
- "time_window": {
- "start": "2019-08-24T14:15:22Z",
- "end": "2019-08-24T14:15:22Z"
}, - "time": {
- "not_before": "2019-08-24T14:15:22Z",
- "expires_at": "2019-08-24T14:15:22Z"
}, - "geo_fence": {
- "allowed_regions": [
- "string"
]
}, - "require_mfa": true,
- "ip_whitelist": [
- "string"
], - "transaction_limits": {
- "max_amount": {
- "currency": "string",
- "value": "string"
}, - "max_total": [
- {
- "amount": {
- "currency": "string",
- "value": "string"
}, - "window": "PT1H"
}
]
}, - "rate_limits": {
- "max_count": [
- {
- "count": 1,
- "window": "PT1H"
}
]
}, - "escalation_rules": {
- "deviation_above_percent": 0,
- "amount_above": {
- "currency": "string",
- "value": "string"
}, - "escalate_to": "string",
- "escalation_method": "string"
}
}, - "proof": {
- "creation_method": "API_KEY",
- "issuer": "string",
- "created_by": "string",
- "created_by_type": "NATURAL_PERSON",
- "created_by_auth_method": "string",
- "mandate_hash": "string",
- "signature": "string",
- "eidas_loa": "string"
}, - "metadata": { },
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "expires_at": "2019-08-24T14:15:22Z",
- "vui": {
- "instruction_text": "string",
- "instruction_hash": "a1b2c3d4e5f6...",
- "instruction_timestamp": "2019-08-24T14:15:22Z",
- "instruction_channel": "chat",
- "principal_confirmation": {
- "method": "explicit_approval",
- "timestamp": "2019-08-24T14:15:22Z",
- "evidence_ref": "string"
}, - "constraints_derived": {
- "max_amount": 0,
- "allowed_actions": [
- "string"
], - "time_bound": "2019-08-24T14:15:22Z"
}
}, - "approval": {
- "approved_by": "string",
- "approved_by_type": "NATURAL_PERSON",
- "approved_by_auth_method": "string",
- "approved_at": "2019-08-24T14:15:22Z"
}
}
], - "next_cursor": "string"
}Retrieves a single mandate by its ID. Returns the full mandate record including principal, delegate, scope, constraints, and proof metadata.
| id required | string Example: mdt_01HXYZ... |
{- "mandate_id": "mdt_01HXYZ...",
- "tenant_id": "string",
- "version": 0,
- "status": "DRAFT",
- "principal": {
- "type": "HUMAN",
- "subject_id": "construction:agent:validate-agent-v2",
- "display_name": "string",
- "identity_provider": "string",
- "identity_token_hash": "string"
}, - "delegate": {
- "type": "HUMAN",
- "subject_id": "construction:agent:validate-agent-v2",
- "display_name": "string",
- "identity_provider": "string",
- "identity_token_hash": "string"
}, - "scope": {
- "actions": [
- "construction.validation.approve"
], - "resources": [
- "construction:project:*/zone:*/installation:*"
], - "effect": "ALLOW",
- "conditions": { }
}, - "constraints": {
- "max_uses": 0,
- "time_window": {
- "start": "2019-08-24T14:15:22Z",
- "end": "2019-08-24T14:15:22Z"
}, - "time": {
- "not_before": "2019-08-24T14:15:22Z",
- "expires_at": "2019-08-24T14:15:22Z"
}, - "geo_fence": {
- "allowed_regions": [
- "string"
]
}, - "require_mfa": true,
- "ip_whitelist": [
- "string"
], - "transaction_limits": {
- "max_amount": {
- "currency": "string",
- "value": "string"
}, - "max_total": [
- {
- "amount": {
- "currency": "string",
- "value": "string"
}, - "window": "PT1H"
}
]
}, - "rate_limits": {
- "max_count": [
- {
- "count": 1,
- "window": "PT1H"
}
]
}, - "escalation_rules": {
- "deviation_above_percent": 0,
- "amount_above": {
- "currency": "string",
- "value": "string"
}, - "escalate_to": "string",
- "escalation_method": "string"
}
}, - "proof": {
- "creation_method": "API_KEY",
- "issuer": "string",
- "created_by": "string",
- "created_by_type": "NATURAL_PERSON",
- "created_by_auth_method": "string",
- "mandate_hash": "string",
- "signature": "string",
- "eidas_loa": "string"
}, - "metadata": { },
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "expires_at": "2019-08-24T14:15:22Z",
- "vui": {
- "instruction_text": "string",
- "instruction_hash": "a1b2c3d4e5f6...",
- "instruction_timestamp": "2019-08-24T14:15:22Z",
- "instruction_channel": "chat",
- "principal_confirmation": {
- "method": "explicit_approval",
- "timestamp": "2019-08-24T14:15:22Z",
- "evidence_ref": "string"
}, - "constraints_derived": {
- "max_amount": 0,
- "allowed_actions": [
- "string"
], - "time_bound": "2019-08-24T14:15:22Z"
}
}, - "approval": {
- "approved_by": "string",
- "approved_by_type": "NATURAL_PERSON",
- "approved_by_auth_method": "string",
- "approved_at": "2019-08-24T14:15:22Z"
}
}Permanently revokes a mandate. Only active or suspended mandates can be revoked. An optional reason can be provided. A KMS-signed audit event is emitted.
| id required | string Example: mdt_01HXYZ... |
| reason | string |
{- "reason": "Contract terminated"
}{- "mandate_id": "string",
- "status": "string",
- "updated_at": "2019-08-24T14:15:22Z"
}Temporarily suspends an active mandate. Suspended mandates can be reactivated later. An optional reason can be provided.
| id required | string Example: mdt_01HXYZ... |
| reason | string |
{- "reason": "Under review"
}{- "mandate_id": "string",
- "status": "string",
- "updated_at": "2019-08-24T14:15:22Z"
}Reactivates a previously suspended mandate, returning it to ACTIVE status. Only mandates in SUSPENDED state can be reactivated.
| id required | string Example: mdt_01HXYZ... |
{- "mandate_id": "string",
- "status": "string",
- "updated_at": "2019-08-24T14:15:22Z"
}Approves a mandate that is in PENDING_APPROVAL state, transitioning it
to ACTIVE. Only mandates created with require_approval: true enter
this state. An audit event (MANDATE_APPROVED) is emitted.
| id required | string Example: mdt_01HXYZ... |
| reason | string Optional reason/notes for the approval |
{- "reason": "string"
}{- "mandate_id": "string",
- "status": "string",
- "updated_at": "2019-08-24T14:15:22Z"
}Rejects a mandate that is in PENDING_APPROVAL state, transitioning it to REVOKED. An audit event (MANDATE_REJECTED) is emitted.
| id required | string Example: mdt_01HXYZ... |
| reason | string Reason for rejection |
{- "reason": "string"
}{- "mandate_id": "string",
- "status": "string",
- "updated_at": "2019-08-24T14:15:22Z"
}Returns the decrypted original user instruction that was provided when the mandate was created. Requires authentication and tenant ownership. An INSTRUCTION_REVEALED audit event is emitted on each access.
Only available for mandates that were created with a Verifiable User Instruction (VUI). Returns 404 if no instruction exists.
| id required | string Example: mdt_01HXYZ... |
{- "instruction_text": "string",
- "instruction_hash": "string",
- "instruction_timestamp": "2019-08-24T14:15:22Z",
- "instruction_channel": "chat",
- "principal_confirmation": {
- "method": "string",
- "timestamp": "2019-08-24T14:15:22Z",
- "evidence_ref": "string"
}, - "mandate_id": "string"
}MCP Authorization Server — OAuth sessions for AI agents, for the MCP server and the execution API
The OAuth 2.0 Authorization Server Metadata (RFC 8414) of
POST /mcp/token, where agents get their sessions. The same document
is served at the domain's root, where RFC 8414 places it for this
issuer and where MCP clients look for it:
https://api.mandaitor.io/.well-known/oauth-authorization-server/v1.
Agents authenticate with the client credentials grant and their
registry key (private_key_jwt). No browser flow exists yet:
response_types_supported is empty, and the authorization_endpoint
it names answers so.
{- "issuer": "string",
- "token_endpoint": "string",
- "authorization_endpoint": "string",
- "grant_types_supported": [
- "string"
], - "token_endpoint_auth_methods_supported": [
- "string"
], - "token_endpoint_auth_signing_alg_values_supported": [
- "ES256",
- "ES384"
], - "dpop_signing_alg_values_supported": [
- "ES256",
- "ES384"
], - "response_types_supported": [
- "string"
], - "service_documentation": "string",
- "scopes_supported": [
- "string"
]
}OAuth 2.0 client_credentials grant for MCP agents. The agent presents a signed JWT assertion and receives a scoped access token bound to its mandates. The parameters may be sent form-encoded, as OAuth clients send them, or as a JSON object.
The assertion (private_key_jwt) is signed with the agent's active
registry key, which kid may name. It must carry iss and sub naming
the agent (its DID), aud naming the authorization server — its
issuer (https://api.mandaitor.io/v1) or this endpoint's URL — a
unique jti of at most 256 characters, and an exp no more than
five minutes ahead (a minute of clock skew is tolerated). Each
assertion is accepted once: presenting the same jti again returns
401, so sign a new assertion for every token request. client_id
may be left out, since the assertion's iss names the agent
(RFC 7521); when both are sent, they must agree.
resource (RFC 8707) names what the token is for. The MCP server's
URL (https://api.mandaitor.io/v1/mcp) gives a session that only
the MCP server accepts. The API's base URL, or no resource, gives
one that only the API's own routes accept. Anything else is 400
invalid_target.
A session bound to the agent's key (DPoP, RFC 9449). A DPoP
header with a proof for this request, signed by a key the client
holds, binds the session to that key: it is issued with
token_type DPoP and lasts an hour, and every request with it must
carry a fresh proof signed by the same key (McpSessionDPoP), so
the token alone is of no use to anyone who takes it. /executions
takes only such a session. Without a proof, the session is a bearer
one (token_type Bearer) and lasts 15 minutes: the MCP server and
GET /mcp/sessions/{id} take it, /executions does not.
| DPoP | string <= 4096 characters A DPoP proof (RFC 9449) for this request, asking for a session
bound to its key: |
| grant_type required | string Value: "client_credentials" |
| client_id | string Agent DID. Optional, as the assertion's |
| client_assertion_type required | string Value: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer" |
| client_assertion required | string Signed JWT assertion, accepted once. Carries a unique |
| scope | string Space-separated mandate scopes |
| resource | string What the token is for (RFC 8707): the MCP server's URL, or the API's base URL. A session is accepted only by the one it names; without a resource, by the API. |
{- "access_token": "string",
- "token_type": "DPoP",
- "expires_in": 3600,
- "scope": "string",
- "session_id": "sess_0f3c9d2e8b7a6c5d4e3f2a1b0c9d8e7f"
}The authorization endpoint the server metadata names, because MCP
clients refuse metadata without one. Mandaitor issues sessions only to
registered agents, with the client credentials grant at
POST /mcp/token. Signing in as a person through an MCP client is not
available yet. Always 400 unsupported_response_type.
{- "error": "invalid_target",
- "error_description": "string"
}Requires the session's own access token (Authorization: Bearer mcp_…,
or DPoP mcp_… with a proof for a session bound to the agent's key);
a token for a different session returns 404. So does a session whose
agent has been suspended or revoked since it was issued.
| id required | string |
| DPoP | string <= 4096 characters Required with a session bound to the agent's key, sent as
|
{- "session_id": "string",
- "tenant_id": "string",
- "agent_id": "string",
- "agent_did": "string",
- "mandate_ids": [
- "string"
], - "created_at": "2019-08-24T14:15:22Z",
- "expires_at": "2019-08-24T14:15:22Z",
- "last_active_at": "2019-08-24T14:15:22Z",
- "call_count": 0,
- "cnf": {
- "jkt": "string"
}
}The MCP server (Streamable HTTP): an agent's MCP client lists the tools its mandates could back and calls them, each call an execution
The MCP server. The body is one JSON-RPC 2.0 message of the Model Context Protocol. The server speaks 2025-11-25, 2025-06-18 and 2025-03-26, and answers every request with one JSON object, never a stream. A batch is refused, and a notification gets 202 and no body.
initialize: the negotiated version, tools as the only
capability, and instructions for the model.ping.tools/list: the tools the tenant enabled that a mandate naming
the agent could back now, then the server's own get_execution. A
tool's name is its id with each dot an underscore
(sap_purchase_requisition_release).tools/call: one execution, requested as POST /executions
requests it, from the tool's arguments and an optional purpose
for the approver. The call waits up to about 20 seconds for the
execution to settle and answers with its outcome. One still
running, or waiting for a person's approval, is answered with its
state and id, for get_execution. While 50 calls are already
waiting, across every agent, a call answers at once instead. A repeat of the same call by the
same agent names the same execution while it runs, and for 10
minutes after it ends. A denial or a failure is a tool error
(isError: true); an unknown or not enabled tool is a JSON-RPC
error (-32602). The result's structuredContent is the execution
as GET /executions/{id} returns it.Authenticated with a session from POST /mcp/token issued for this
server (its resource this URL): a bearer session, as stock MCP
clients hold, or one bound to the agent's key, sent as DPoP with a
proof for each request. Without one, the 401's WWW-Authenticate
names the protected resource metadata (RFC 9728):
https://api.mandaitor.io/.well-known/oauth-protected-resource/v1/mcp.
A browser's request from an origin this API does not serve is
refused with 403.
An agent may send 60 requests a minute, whatever they ask; past that, each is refused with 429 before anything is read. A tool call also counts against the agent's 30 executions a minute, and past those it is a tool error that says when to try again.
| DPoP | string <= 4096 characters Required with a session bound to the agent's key, sent as
|
| MCP-Protocol-Version | string Enum: "2025-11-25" "2025-06-18" "2025-03-26" The version negotiated at |
| jsonrpc required | string Value: "2.0" |
string or integer | |
| method | string |
object |
{- "jsonrpc": "2.0",
- "id": "string",
- "method": "tools/call",
- "params": { }
}{- "jsonrpc": "2.0",
- "id": "string",
- "result": { },
- "error": {
- "code": 0,
- "message": "string",
- "data": null
}
}Submits a new tenant access request. No authentication required. The request enters PENDING state and must be approved by an admin.
| company_name required | string |
| contact_name | string |
| contact_email required | string <email> |
| use_case required | string |
| industry | string Enum: "construction" "real_estate" "venture_capital" "other" |
| website | string <uri> |
| lead_source | string Marketing or referral source associated with the beta request. |
| beta_track | string Closed-beta routing segment used for the request. |
| asset | string Specific public asset or CTA entry point that produced the request. |
{- "company_name": "example GmbH",
- "contact_name": "Max Mustermann",
- "contact_email": "max@example.com",
- "use_case": "AI agent delegation for construction validation",
- "industry": "construction",
- "lead_source": "trust-site",
- "beta_track": "construction",
- "asset": "home-hero"
}{- "request_id": "string",
- "status": "PENDING",
- "message": "string"
}Returns metadata for every API key owned by the tenant. The raw key is
only available at creation time via POST /tenants/{id}/api-keys; this
endpoint never returns the raw key or its hash. The tenant is taken
from the authenticated caller — the path parameter must match, or the
request is rejected with 403. Requires Cognito JWT.
| id required | string |
{- "items": [
- {
- "key_id": "key_9c6d2e4f3a1b0d7e",
- "name": "production-key",
- "environment": "live",
- "created_at": "2019-08-24T14:15:22Z",
- "status": "ACTIVE",
- "last_four": "1dce",
- "scopes": [
- "mandates:read",
- "mandates:write",
- "verify"
]
}
]
}Generates a new API key for a tenant. The raw key is returned only once in the response and cannot be retrieved again. Requires Cognito JWT.
| id required | string |
| name | string |
| environment | string Default: "live" Enum: "live" "test" |
| scopes | Array of strings (ApiScope) Items Enum: "mandates:read" "mandates:write" "verify" Scope list the issued key will be allowed to exercise.
Omitted or null means "all canonical scopes" — equivalent
to passing |
{- "name": "production-key",
- "environment": "live",
- "scopes": [
- "mandates:read",
- "verify"
]
}{- "key_id": "string",
- "api_key": "string",
- "name": "string",
- "environment": "live",
- "scopes": [
- "mandates:read"
], - "created_at": "2019-08-24T14:15:22Z"
}Flips the per-key row to status: "REVOKED". The authorizer reads
per-key rows directly, so the key stops authenticating on the next
request — other ACTIVE keys for the same tenant keep working.
Idempotent for already-revoked keys. The tenant path parameter must
match the authenticated caller. Requires Cognito JWT.
| id required | string |
| keyId required | string |
{- "error": "BAD_REQUEST",
- "message": "principal and delegate are required"
}Organisational accountability structure — units, owners and risk classification for governance reporting
Creates an accountability unit inside the tenant. Every unit names an accountable owner; the hierarchy is bounded to four levels so aggregated reporting stays readable.
The first unit created may omit parent_id and becomes the root. Any
later unit must name an existing parent.
| name required | string |
| kind required | string Enum: "root" "division" "department" "team" |
required | object (OrgUnitOwner) |
| parent_id | string Required for every unit except the root |
| description | string |
object |
{- "name": "string",
- "kind": "root",
- "owner": {
- "subject_id": "string",
- "display_name": "string",
- "email": "user@example.com",
- "role_title": "Head of Digital Operations"
}, - "parent_id": "string",
- "description": "string",
- "tags": {
- "property1": "string",
- "property2": "string"
}
}{- "org_unit_id": "string",
- "tenant_id": "string",
- "parent_id": "string",
- "kind": "root",
- "name": "string",
- "description": "string",
- "owner": {
- "subject_id": "string",
- "display_name": "string",
- "email": "user@example.com",
- "role_title": "Head of Digital Operations"
}, - "status": "ACTIVE",
- "path": [
- "string"
], - "depth": 3,
- "tags": {
- "property1": "string",
- "property2": "string"
}, - "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}Returns every unit of the tenant. The result is not paginated: the hierarchy is bounded by design and a management view needs the whole tree to render it.
| status | string Enum: "ACTIVE" "ARCHIVED" Restrict to active or archived units |
{- "items": [
- {
- "org_unit_id": "string",
- "tenant_id": "string",
- "parent_id": "string",
- "kind": "root",
- "name": "string",
- "description": "string",
- "owner": {
- "subject_id": "string",
- "display_name": "string",
- "email": "user@example.com",
- "role_title": "Head of Digital Operations"
}, - "status": "ACTIVE",
- "path": [
- "string"
], - "depth": 3,
- "tags": {
- "property1": "string",
- "property2": "string"
}, - "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}
], - "total_count": 0
}| id required | string |
{- "org_unit_id": "string",
- "tenant_id": "string",
- "parent_id": "string",
- "kind": "root",
- "name": "string",
- "description": "string",
- "owner": {
- "subject_id": "string",
- "display_name": "string",
- "email": "user@example.com",
- "role_title": "Head of Digital Operations"
}, - "status": "ACTIVE",
- "path": [
- "string"
], - "depth": 3,
- "tags": {
- "property1": "string",
- "property2": "string"
}, - "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}Updates descriptive fields and accountable ownership. kind,
parent_id, path and depth are immutable: moving a unit changes the
meaning of every historical aggregation that referenced it, so a move is
modelled as archive plus create rather than an in-place edit.
| id required | string |
| name | string |
| description | string |
object (OrgUnitOwner) | |
object |
{- "name": "string",
- "description": "string",
- "owner": {
- "subject_id": "string",
- "display_name": "string",
- "email": "user@example.com",
- "role_title": "Head of Digital Operations"
}, - "tags": {
- "property1": "string",
- "property2": "string"
}
}{- "org_unit_id": "string",
- "tenant_id": "string",
- "parent_id": "string",
- "kind": "root",
- "name": "string",
- "description": "string",
- "owner": {
- "subject_id": "string",
- "display_name": "string",
- "email": "user@example.com",
- "role_title": "Head of Digital Operations"
}, - "status": "ACTIVE",
- "path": [
- "string"
], - "depth": 3,
- "tags": {
- "property1": "string",
- "property2": "string"
}, - "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}Archives the unit. This is a soft delete: mandates and audit events keep referencing it, so hard deletion would break the evidence trail the platform exists to preserve.
A unit with active children cannot be archived — archiving a parent would leave its children unreachable in the tree while still active.
| id required | string |
{- "org_unit_id": "string",
- "tenant_id": "string",
- "parent_id": "string",
- "kind": "root",
- "name": "string",
- "description": "string",
- "owner": {
- "subject_id": "string",
- "display_name": "string",
- "email": "user@example.com",
- "role_title": "Head of Digital Operations"
}, - "status": "ACTIVE",
- "path": [
- "string"
], - "depth": 3,
- "tags": {
- "property1": "string",
- "property2": "string"
}, - "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}Returns the unit together with all descendants, resolved from the materialised ancestor path in a single read. This is the aggregation boundary for management reporting: "everything below this division".
| id required | string |
{- "root": {
- "org_unit_id": "string",
- "tenant_id": "string",
- "parent_id": "string",
- "kind": "root",
- "name": "string",
- "description": "string",
- "owner": {
- "subject_id": "string",
- "display_name": "string",
- "email": "user@example.com",
- "role_title": "Head of Digital Operations"
}, - "status": "ACTIVE",
- "path": [
- "string"
], - "depth": 3,
- "tags": {
- "property1": "string",
- "property2": "string"
}, - "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}, - "items": [
- {
- "org_unit_id": "string",
- "tenant_id": "string",
- "parent_id": "string",
- "kind": "root",
- "name": "string",
- "description": "string",
- "owner": {
- "subject_id": "string",
- "display_name": "string",
- "email": "user@example.com",
- "role_title": "Head of Digital Operations"
}, - "status": "ACTIVE",
- "path": [
- "string"
], - "depth": 3,
- "tags": {
- "property1": "string",
- "property2": "string"
}, - "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}
], - "total_count": 0
}Engagement workspace — knowledge catalog (media assets, documents, signed delivery) and per-phase engagement artifacts
| limit | integer [ 1 .. 200 ] Default: 50 |
| cursor | string Base64url-encoded pagination cursor |
| classification | string (MediaClassification) Enum: "public" "partner-confidential" "client-confidential" "internal-restricted" |
| lifecycle_area | string |
| status | string (KnowledgeAssetStatus) Enum: "planned" "draft" "release-candidate" "approved" "uploaded" "superseded" "archived" "withdrawn" |
{- "items": [
- {
- "asset_id": "string",
- "tenant_id": "string",
- "title": "string",
- "status": "planned",
- "classification": "public",
- "lifecycle_area": "string",
- "lifecycle_phases": [
- "string"
], - "primary_audience": [
- "string"
], - "owner": "string",
- "source_references": [
- "string"
], - "current_version": "string",
- "storage_prefix": "string",
- "manifest_path": "string",
- "review": {
- "required_reviewers": [
- "string"
], - "last_reviewed_at": "2019-08-24T14:15:22Z",
- "notes": "string"
}, - "created_by": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}
], - "next_cursor": "string"
}| asset_id | string Omit to create a new asset |
| title required | string |
| classification required | string (MediaClassification) Enum: "public" "partner-confidential" "client-confidential" "internal-restricted" |
| lifecycle_area required | string |
| status | string (KnowledgeAssetStatus) Enum: "planned" "draft" "release-candidate" "approved" "uploaded" "superseded" "archived" "withdrawn" |
| lifecycle_phases | Array of strings |
| primary_audience | Array of strings |
| owner | string |
| source_references | Array of strings |
| manifest_path | string |
| current_version | string |
| storage_prefix | string |
| review_notes | string |
| required_reviewers | Array of strings |
object (KnowledgeAssetReview) |
{- "asset_id": "string",
- "title": "string",
- "classification": "public",
- "lifecycle_area": "string",
- "status": "planned",
- "lifecycle_phases": [
- "string"
], - "primary_audience": [
- "string"
], - "owner": "string",
- "source_references": [
- "string"
], - "manifest_path": "string",
- "current_version": "string",
- "storage_prefix": "string",
- "review_notes": "string",
- "required_reviewers": [
- "string"
], - "review": {
- "required_reviewers": [
- "string"
], - "last_reviewed_at": "2019-08-24T14:15:22Z",
- "notes": "string"
}
}{- "asset": {
- "asset_id": "string",
- "tenant_id": "string",
- "title": "string",
- "status": "planned",
- "classification": "public",
- "lifecycle_area": "string",
- "lifecycle_phases": [
- "string"
], - "primary_audience": [
- "string"
], - "owner": "string",
- "source_references": [
- "string"
], - "current_version": "string",
- "storage_prefix": "string",
- "manifest_path": "string",
- "review": {
- "required_reviewers": [
- "string"
], - "last_reviewed_at": "2019-08-24T14:15:22Z",
- "notes": "string"
}, - "created_by": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}
}Creates a single-file document asset from a title + file metadata,
deriving all catalog fields server-side, and returns a presigned S3
PUT for the bytes. Send the returned upload_headers verbatim with
the PUT — when a sha256 was announced, the checksum header is part
of the signature and S3 rejects non-matching bytes. Finish with
publish-complete.
| title required | string |
| file_name required | string |
| content_type | string Default: "application/octet-stream" |
| size_bytes required | integer <= 536870912 |
| sha256 | string Optional 64-char hex digest; when present, S3 enforces it on upload |
| classification | string (MediaClassification) Enum: "public" "partner-confidential" "client-confidential" "internal-restricted" |
| engagement_id | string Links the document to an engagement via source_references |
| notes | string |
{- "title": "string",
- "file_name": "string",
- "content_type": "application/octet-stream",
- "size_bytes": 536870912,
- "sha256": "string",
- "classification": "public",
- "engagement_id": "string",
- "notes": "string"
}{- "asset": {
- "asset_id": "string",
- "tenant_id": "string",
- "title": "string",
- "status": "planned",
- "classification": "public",
- "lifecycle_area": "string",
- "lifecycle_phases": [
- "string"
], - "primary_audience": [
- "string"
], - "owner": "string",
- "source_references": [
- "string"
], - "current_version": "string",
- "storage_prefix": "string",
- "manifest_path": "string",
- "review": {
- "required_reviewers": [
- "string"
], - "last_reviewed_at": "2019-08-24T14:15:22Z",
- "notes": "string"
}, - "created_by": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}, - "version": {
- "version_id": "string",
- "tenant_id": "string",
- "asset_id": "string",
- "version": "string",
- "status": "draft",
- "classification": "public",
- "storage_bucket_env": "string",
- "storage_bucket": "string",
- "storage_prefix": "string",
- "manifest_s3_key": "string",
- "manifest_path": "string",
- "release_notes": "string",
- "supersedes_version": "string",
- "approved_by": "string",
- "approved_at": "2019-08-24T14:15:22Z",
- "source_commit": "string",
- "created_by": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "files": [
- {
- "file_id": "string",
- "tenant_id": "string",
- "asset_id": "string",
- "version": "string",
- "storage_key": "string",
- "relative_path": "string",
- "file_name": "string",
- "content_type": "string",
- "size_bytes": 0,
- "sha256": "string",
- "role": "primary",
- "language": "string",
- "format": "string",
- "created_at": "2019-08-24T14:15:22Z"
}
]
}, - "file": {
- "file_id": "string",
- "tenant_id": "string",
- "asset_id": "string",
- "version": "string",
- "storage_key": "string",
- "relative_path": "string",
- "file_name": "string",
- "content_type": "string",
- "size_bytes": 0,
- "sha256": "string",
- "role": "primary",
- "language": "string",
- "format": "string",
- "created_at": "2019-08-24T14:15:22Z"
}, - "upload_url": "string",
- "upload_expires_in": 0,
- "upload_headers": {
- "property1": "string",
- "property2": "string"
}
}| assetId required | string |
{- "asset": {
- "asset_id": "string",
- "tenant_id": "string",
- "title": "string",
- "status": "planned",
- "classification": "public",
- "lifecycle_area": "string",
- "lifecycle_phases": [
- "string"
], - "primary_audience": [
- "string"
], - "owner": "string",
- "source_references": [
- "string"
], - "current_version": "string",
- "storage_prefix": "string",
- "manifest_path": "string",
- "review": {
- "required_reviewers": [
- "string"
], - "last_reviewed_at": "2019-08-24T14:15:22Z",
- "notes": "string"
}, - "created_by": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}, - "versions": [
- {
- "version_id": "string",
- "tenant_id": "string",
- "asset_id": "string",
- "version": "string",
- "status": "draft",
- "classification": "public",
- "storage_bucket_env": "string",
- "storage_bucket": "string",
- "storage_prefix": "string",
- "manifest_s3_key": "string",
- "manifest_path": "string",
- "release_notes": "string",
- "supersedes_version": "string",
- "approved_by": "string",
- "approved_at": "2019-08-24T14:15:22Z",
- "source_commit": "string",
- "created_by": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "files": [
- {
- "file_id": "string",
- "tenant_id": "string",
- "asset_id": "string",
- "version": "string",
- "storage_key": "string",
- "relative_path": "string",
- "file_name": "string",
- "content_type": "string",
- "size_bytes": 0,
- "sha256": "string",
- "role": "primary",
- "language": "string",
- "format": "string",
- "created_at": "2019-08-24T14:15:22Z"
}
]
}
]
}Version strings are immutable — re-posting an existing one answers
409. approved_by/approved_at are set server-side when status
is approved and never accepted from the request. The asset's
current_version only advances when the new version is genuinely
newer (numeric dotted versions compare numerically).
| assetId required | string |
| version required | string Immutable — an existing version string answers 409 |
| status | string (MediaReviewStatus) Enum: "draft" "approved" "uploaded" "superseded" "archived" "withdrawn" |
| storage_prefix | string |
| manifest_s3_key | string |
| manifest_path | string |
| release_notes | string |
| supersedes_version | string |
| source_commit | string |
Array of objects |
{- "version": "string",
- "status": "draft",
- "storage_prefix": "string",
- "manifest_s3_key": "string",
- "manifest_path": "string",
- "release_notes": "string",
- "supersedes_version": "string",
- "source_commit": "string",
- "files": [
- {
- "file_id": "string",
- "role": "primary",
- "relative_path": "string",
- "file_name": "string",
- "content_type": "string",
- "size_bytes": 0,
- "sha256": "string",
- "language": "string",
- "format": "string",
- "storage_key": "string"
}
]
}{- "version": {
- "version_id": "string",
- "tenant_id": "string",
- "asset_id": "string",
- "version": "string",
- "status": "draft",
- "classification": "public",
- "storage_bucket_env": "string",
- "storage_bucket": "string",
- "storage_prefix": "string",
- "manifest_s3_key": "string",
- "manifest_path": "string",
- "release_notes": "string",
- "supersedes_version": "string",
- "approved_by": "string",
- "approved_at": "2019-08-24T14:15:22Z",
- "source_commit": "string",
- "created_by": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "files": [
- {
- "file_id": "string",
- "tenant_id": "string",
- "asset_id": "string",
- "version": "string",
- "storage_key": "string",
- "relative_path": "string",
- "file_name": "string",
- "content_type": "string",
- "size_bytes": 0,
- "sha256": "string",
- "role": "primary",
- "language": "string",
- "format": "string",
- "created_at": "2019-08-24T14:15:22Z"
}
]
}
}Verifies the uploaded object exists (and, when a SHA-256 was
announced, that S3's stored checksum matches), records the real
object size, and flips the asset and version to uploaded.
| assetId required | string |
{- "asset": {
- "asset_id": "string",
- "tenant_id": "string",
- "title": "string",
- "status": "planned",
- "classification": "public",
- "lifecycle_area": "string",
- "lifecycle_phases": [
- "string"
], - "primary_audience": [
- "string"
], - "owner": "string",
- "source_references": [
- "string"
], - "current_version": "string",
- "storage_prefix": "string",
- "manifest_path": "string",
- "review": {
- "required_reviewers": [
- "string"
], - "last_reviewed_at": "2019-08-24T14:15:22Z",
- "notes": "string"
}, - "created_by": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}, - "version": {
- "version_id": "string",
- "tenant_id": "string",
- "asset_id": "string",
- "version": "string",
- "status": "draft",
- "classification": "public",
- "storage_bucket_env": "string",
- "storage_bucket": "string",
- "storage_prefix": "string",
- "manifest_s3_key": "string",
- "manifest_path": "string",
- "release_notes": "string",
- "supersedes_version": "string",
- "approved_by": "string",
- "approved_at": "2019-08-24T14:15:22Z",
- "source_commit": "string",
- "created_by": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "files": [
- {
- "file_id": "string",
- "tenant_id": "string",
- "asset_id": "string",
- "version": "string",
- "storage_key": "string",
- "relative_path": "string",
- "file_name": "string",
- "content_type": "string",
- "size_bytes": 0,
- "sha256": "string",
- "role": "primary",
- "language": "string",
- "format": "string",
- "created_at": "2019-08-24T14:15:22Z"
}
]
}, - "file": {
- "file_id": "string",
- "tenant_id": "string",
- "asset_id": "string",
- "version": "string",
- "storage_key": "string",
- "relative_path": "string",
- "file_name": "string",
- "content_type": "string",
- "size_bytes": 0,
- "sha256": "string",
- "role": "primary",
- "language": "string",
- "format": "string",
- "created_at": "2019-08-24T14:15:22Z"
}
}| assetId required | string |
| version | string |
| file_id | string |
| relative_path | string |
| asset_id | string Required on the /partner/media/files/{fileId}/signed-url form |
| project_id | string Required for client-confidential assets — proves engagement scope |
{- "version": "string",
- "file_id": "string",
- "relative_path": "string",
- "asset_id": "string",
- "project_id": "string"
}{- "signed_url": "string",
- "expires_in": 0,
- "expires_at": "2019-08-24T14:15:22Z",
- "file": {
- "file_id": "string",
- "tenant_id": "string",
- "asset_id": "string",
- "version": "string",
- "storage_key": "string",
- "relative_path": "string",
- "file_name": "string",
- "content_type": "string",
- "size_bytes": 0,
- "sha256": "string",
- "role": "primary",
- "language": "string",
- "format": "string",
- "created_at": "2019-08-24T14:15:22Z"
}, - "asset": {
- "asset_id": "string",
- "tenant_id": "string",
- "title": "string",
- "status": "planned",
- "classification": "public",
- "lifecycle_area": "string",
- "lifecycle_phases": [
- "string"
], - "primary_audience": [
- "string"
], - "owner": "string",
- "source_references": [
- "string"
], - "current_version": "string",
- "storage_prefix": "string",
- "manifest_path": "string",
- "review": {
- "required_reviewers": [
- "string"
], - "last_reviewed_at": "2019-08-24T14:15:22Z",
- "notes": "string"
}, - "created_by": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}, - "version": {
- "version_id": "string",
- "tenant_id": "string",
- "asset_id": "string",
- "version": "string",
- "status": "draft",
- "classification": "public",
- "storage_bucket_env": "string",
- "storage_bucket": "string",
- "storage_prefix": "string",
- "manifest_s3_key": "string",
- "manifest_path": "string",
- "release_notes": "string",
- "supersedes_version": "string",
- "approved_by": "string",
- "approved_at": "2019-08-24T14:15:22Z",
- "source_commit": "string",
- "created_by": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "files": [
- {
- "file_id": "string",
- "tenant_id": "string",
- "asset_id": "string",
- "version": "string",
- "storage_key": "string",
- "relative_path": "string",
- "file_name": "string",
- "content_type": "string",
- "size_bytes": 0,
- "sha256": "string",
- "role": "primary",
- "language": "string",
- "format": "string",
- "created_at": "2019-08-24T14:15:22Z"
}
]
}
}Body must carry asset_id and version; the path's file id overrides any body file_id.
| fileId required | string |
| version | string |
| file_id | string |
| relative_path | string |
| asset_id | string Required on the /partner/media/files/{fileId}/signed-url form |
| project_id | string Required for client-confidential assets — proves engagement scope |
{- "version": "string",
- "file_id": "string",
- "relative_path": "string",
- "asset_id": "string",
- "project_id": "string"
}{- "signed_url": "string",
- "expires_in": 0,
- "expires_at": "2019-08-24T14:15:22Z",
- "file": {
- "file_id": "string",
- "tenant_id": "string",
- "asset_id": "string",
- "version": "string",
- "storage_key": "string",
- "relative_path": "string",
- "file_name": "string",
- "content_type": "string",
- "size_bytes": 0,
- "sha256": "string",
- "role": "primary",
- "language": "string",
- "format": "string",
- "created_at": "2019-08-24T14:15:22Z"
}, - "asset": {
- "asset_id": "string",
- "tenant_id": "string",
- "title": "string",
- "status": "planned",
- "classification": "public",
- "lifecycle_area": "string",
- "lifecycle_phases": [
- "string"
], - "primary_audience": [
- "string"
], - "owner": "string",
- "source_references": [
- "string"
], - "current_version": "string",
- "storage_prefix": "string",
- "manifest_path": "string",
- "review": {
- "required_reviewers": [
- "string"
], - "last_reviewed_at": "2019-08-24T14:15:22Z",
- "notes": "string"
}, - "created_by": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z"
}, - "version": {
- "version_id": "string",
- "tenant_id": "string",
- "asset_id": "string",
- "version": "string",
- "status": "draft",
- "classification": "public",
- "storage_bucket_env": "string",
- "storage_bucket": "string",
- "storage_prefix": "string",
- "manifest_s3_key": "string",
- "manifest_path": "string",
- "release_notes": "string",
- "supersedes_version": "string",
- "approved_by": "string",
- "approved_at": "2019-08-24T14:15:22Z",
- "source_commit": "string",
- "created_by": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_at": "2019-08-24T14:15:22Z",
- "files": [
- {
- "file_id": "string",
- "tenant_id": "string",
- "asset_id": "string",
- "version": "string",
- "storage_key": "string",
- "relative_path": "string",
- "file_name": "string",
- "content_type": "string",
- "size_bytes": 0,
- "sha256": "string",
- "role": "primary",
- "language": "string",
- "format": "string",
- "created_at": "2019-08-24T14:15:22Z"
}
]
}
}| projectId required | string |
{- "items": [
- {
- "artifact_id": "string",
- "tenant_id": "string",
- "engagement_id": "string",
- "artifact_type": "PILOT_CHARTER",
- "status": "DRAFT",
- "version": 0,
- "payload": { },
- "review_task_id": "string",
- "approved_by": "string",
- "approved_at": "2019-08-24T14:15:22Z",
- "created_by": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_by": "string",
- "updated_at": "2019-08-24T14:15:22Z"
}
]
}Answers 200 with "artifact": null when the artifact hasn't been
authored yet — an expected state on fresh engagements, not an error.
A missing engagement still answers 404.
| projectId required | string |
| artifactType required | string (EngagementArtifactType) Enum: "PILOT_CHARTER" "MANDATE_DESIGN" "VERIFICATION_PLAN" "EVIDENCE_PACK" "PILOT_GATE_DECISION" "OPERATIONS_HANDOVER" |
{- "artifact": {
- "artifact_id": "string",
- "tenant_id": "string",
- "engagement_id": "string",
- "artifact_type": "PILOT_CHARTER",
- "status": "DRAFT",
- "version": 0,
- "payload": { },
- "review_task_id": "string",
- "approved_by": "string",
- "approved_at": "2019-08-24T14:15:22Z",
- "created_by": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_by": "string",
- "updated_at": "2019-08-24T14:15:22Z"
}
}| projectId required | string |
| artifactType required | string (EngagementArtifactType) Enum: "PILOT_CHARTER" "MANDATE_DESIGN" "VERIFICATION_PLAN" "EVIDENCE_PACK" "PILOT_GATE_DECISION" "OPERATIONS_HANDOVER" |
required | object Type-specific artifact payload (validated per artifact type) | ||
| |||
{- "payload": { }
}{- "artifact": {
- "artifact_id": "string",
- "tenant_id": "string",
- "engagement_id": "string",
- "artifact_type": "PILOT_CHARTER",
- "status": "DRAFT",
- "version": 0,
- "payload": { },
- "review_task_id": "string",
- "approved_by": "string",
- "approved_at": "2019-08-24T14:15:22Z",
- "created_by": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_by": "string",
- "updated_at": "2019-08-24T14:15:22Z"
}
}| projectId required | string |
| artifactType required | string (EngagementArtifactType) Enum: "PILOT_CHARTER" "MANDATE_DESIGN" "VERIFICATION_PLAN" "EVIDENCE_PACK" "PILOT_GATE_DECISION" "OPERATIONS_HANDOVER" |
| reviewer_role | string |
| notes | string |
{- "reviewer_role": "string",
- "notes": "string"
}{- "artifact": {
- "artifact_id": "string",
- "tenant_id": "string",
- "engagement_id": "string",
- "artifact_type": "PILOT_CHARTER",
- "status": "DRAFT",
- "version": 0,
- "payload": { },
- "review_task_id": "string",
- "approved_by": "string",
- "approved_at": "2019-08-24T14:15:22Z",
- "created_by": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "updated_by": "string",
- "updated_at": "2019-08-24T14:15:22Z"
}, - "review_task": {
- "task_id": "string",
- "tenant_id": "string",
- "subject_id": "string",
- "reviewer_role": "string",
- "status": "string",
- "created_at": "2019-08-24T14:15:22Z"
}
}Returns service health status. No sensitive data is exposed. Suitable for monitoring, load balancers, and Trust Center embedding.
{- "status": "ok",
- "timestamp": "2019-08-24T14:15:22Z",
- "version": "1.2.3-beta.1",
- "stage": "prod"
}Returns the W3C DID Document for the Mandaitor issuer DID (did:web:api.mandaitor.io). Contains the public key used to verify Proof-of-Mandate SD-JWT VCs.
{- "@context": [
- "string"
], - "id": "did:web:api.mandaitor.io",
- "verificationMethod": [
- { }
], - "authentication": [
- "string"
], - "assertionMethod": [
- "string"
], - "service": [
- { }
]
}Spec-compliant resolution path for the issuer DID. The issuer DID is a
path DID (did:web:api.mandaitor.io:v1), which per the W3C did:web
specification resolves to https://api.mandaitor.io/v1/did.json — this
endpoint. Returns the same W3C DID Document as /.well-known/did.json,
which is kept as an alias.
{- "@context": [
- "string"
], - "id": "did:web:api.mandaitor.io:v1",
- "verificationMethod": [
- { }
], - "authentication": [
- "string"
], - "assertionMethod": [
- "string"
], - "service": [
- { }
]
}Returns machine-readable trust metadata including region, partition, issuer DID, data residency claims, and supported open standards. Unauthenticated and cache-friendly (5-minute client, 10-minute CDN).
{- "schema_version": "1.0.0",
- "region": "eusc-de-east-1",
- "partition": "aws-eusc",
- "issuer_did": "did:web:api.mandaitor.io",
- "data_residency": {
- "primary_region": "string",
- "partition": "string",
- "jurisdiction": "EU (European Sovereign Cloud)"
}, - "open_standards": [
- "string"
], - "build_version": "string",
- "stage": "string",
- "timestamp": "2019-08-24T14:15:22Z"
}Submits a new tenant access request. No authentication required. The request enters PENDING state and must be approved by an admin.
| company_name required | string |
| contact_name | string |
| contact_email required | string <email> |
| use_case required | string |
| industry | string Enum: "construction" "real_estate" "venture_capital" "other" |
| website | string <uri> |
| lead_source | string Marketing or referral source associated with the beta request. |
| beta_track | string Closed-beta routing segment used for the request. |
| asset | string Specific public asset or CTA entry point that produced the request. |
{- "company_name": "example GmbH",
- "contact_name": "Max Mustermann",
- "contact_email": "max@example.com",
- "use_case": "AI agent delegation for construction validation",
- "industry": "construction",
- "lead_source": "trust-site",
- "beta_track": "construction",
- "asset": "home-hero"
}{- "request_id": "string",
- "status": "PENDING",
- "message": "string"
}Returns the public-safe widget configuration for embedding. No authentication required. Sensitive fields (secrets, internal IDs) are stripped from the response.
| widgetId required | string |
{- "widget_id": "string",
- "tenant_name": "string",
- "branding": { },
- "enabled_idps": [
- "string"
], - "taxonomy_libraries": [
- "string"
]
}| userId required | string |
{ }{- "error": "BAD_REQUEST",
- "message": "principal and delegate are required"
}| userId required | string |
{ }{- "error": "BAD_REQUEST",
- "message": "principal and delegate are required"
}Returns the current dashboard onboarding tour status for the authenticated tenant. Used by the guided tour overlay to determine whether to show the onboarding flow.
| id required | string |
| workspace | string Enum: "product_workspace" "partner_project_workspace" Workspace onboarding context. Defaults to product_workspace for backward compatibility. |
{- "tenant_id": "string",
- "onboarding": {
- "completed": true,
- "skipped": true,
- "completed_steps": [
- "string"
], - "current_step": "string",
- "completed_at": "string",
- "skipped_at": "string",
- "started_at": "string"
}
}Updates the dashboard onboarding tour progress for the authenticated tenant. Supports marking steps as completed, advancing the current step, and completing or skipping the entire tour.
| id required | string |
| workspace | string Enum: "product_workspace" "partner_project_workspace" Workspace onboarding context. Defaults to product_workspace for backward compatibility. |
| completed | boolean |
| skipped | boolean |
| completed_steps | Array of strings |
| current_step | string |
{- "completed": true,
- "skipped": true,
- "completed_steps": [
- "string"
], - "current_step": "string"
}{- "tenant_id": "string",
- "onboarding": {
- "completed": true,
- "skipped": true,
- "completed_steps": [
- "string"
], - "current_step": "string",
- "completed_at": "string",
- "skipped_at": "string",
- "started_at": "string"
}
}Performance-critical endpoint. Target: < 50ms p99 latency (without PoM), < 200ms p99 (with PoM). Returns ALLOW or DENY with optional escalation metadata and an optional Proof-of-Mandate Verifiable Credential.
| pom | string Value: "sd-jwt-vc" Request a Proof-of-Mandate Verifiable Credential in the response. The VC is an SD-JWT signed by the Mandaitor issuer DID. |
| drift | boolean Default: false @experimental Request drift detection signals in the response.
When |
| delegate_subject_id | string [ 1 .. 512 ] characters Canonical field. Subject ID of the delegate to verify. |
| agent_id | string [ 1 .. 512 ] characters Deprecated Deprecated legacy alias for |
| action required | string [ 1 .. 256 ] characters |
| resource required | string [ 1 .. 256 ] characters |
| context | object Additional context for constraint evaluation. When a mandate has
|
{- "delegate_subject_id": "construction:agent:validate-agent-v2",
- "agent_id": "construction:agent:validate-agent-v2",
- "action": "construction.validation.approve",
- "resource": "construction:project:proj_ABC123/zone:EG/installation:stk_42",
- "context": { }
}{- "decision": "ALLOW",
- "mandate_id": "string",
- "event_id": "string",
- "reason_codes": [
- "NO_MATCHING_MANDATE"
], - "constraints_remaining": { },
- "evaluated_constraints": [
- "string"
], - "unevaluated_constraints": [
- "string"
], - "proof_of_mandate": {
- "compact": "eyJhbGciOiJQUzI1NiIsInR5cCI6InZjK3NkLWp3dCJ9.eyJ2Y3QiOiJQcm9vZk9mTWFuZGF0ZSJ9.sig~disc1~disc2~",
- "payload": {
- "vct": "ProofOfMandate",
- "decision": "ALLOW",
- "mandate_id": "string",
- "verification_event_id": "string",
- "verification_timestamp": "2019-08-24T14:15:22Z",
- "requested_action": "string",
- "requested_resource": "string",
- "delegate_subject_id": "string",
- "principal_subject_id": "string",
- "tenant_id": "string",
- "reason_codes": [
- "string"
], - "constraints_snapshot": { },
- "latency_ms": 0,
- "instruction_digest": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2",
- "iss": "did:web:api.mandaitor.io",
- "sub": "string",
- "iat": 0,
- "exp": 0,
- "_sd_alg": "sha-256"
}
}, - "proof_token": "string",
- "semantic_signals": {
- "drift_score": {
- "semantic_distance": 0.1,
- "sequence_deviation": 0.1,
- "frequency_anomaly": 0.1,
- "scope_expansion": 0.1,
- "aggregate": 0.1,
- "drift_detected": true
}, - "conflicts": [
- {
- "action_a": "string",
- "action_b": "string",
- "weight": 0.1,
- "rationale": "string"
}
], - "sequence_violations": [
- {
- "action": "string",
- "violation": "string",
- "expected": "string"
}
], - "agent_drift_score": 0.1
}
}Dashboard-only dry-run verify endpoint. Authenticated via Cognito JWT (dashboard session). The caller selects an API key by its key_id from a dropdown; the handler loads the key's metadata (scopes, status) and simulates the verify flow as if the request had come through that key. No raw API key is ever needed. Metering is intentionally skipped.
| id required | string |
| key_id required | string API key ID to simulate (from the dropdown) |
| action required | string The action being attempted |
| resource required | string The resource being accessed |
| delegate_subject_id | string The delegate attempting the action |
| agent_id | string Alternative to delegate_subject_id |
object Additional context for constraint evaluation | |
| request_pom | boolean Whether to include a Proof-of-Mandate VC |
{- "key_id": "string",
- "action": "string",
- "resource": "string",
- "delegate_subject_id": "string",
- "agent_id": "string",
- "context": { },
- "request_pom": true
}{- "decision": "ALLOW",
- "mandate_id": "string",
- "event_id": "string",
- "reason_codes": [
- "string"
], - "constraints_remaining": { },
- "proof_of_mandate": { },
- "proof_token": "string",
- "_playground": {
- "simulated_key": {
- "key_id": "string",
- "key_name": "string",
- "last_four": "string",
- "scopes": [
- "string"
], - "has_verify_scope": true
}, - "dry_run": true
}
}Generates a VI-spec compatible credential chain (L1 + L2) from an existing active mandate. The chain can be presented to external verifiers that implement the Verifiable Intent specification.
| id required | string Example: mdt_01HXYZ... |
| audience required | string Target verifier audience URI |
| nonce | string Optional nonce for replay protection |
| agent_public_key | object Agent's JWK public key for L2 credential |
| principal_public_key | object Principal's JWK public key for L1 credential |
| principal_key_id | string KMS key ID for principal signing |
{- "audience": "string",
- "nonce": "string",
- "agent_public_key": { },
- "principal_public_key": { },
- "principal_key_id": "string"
}{- "credential_chain": {
- "l1_credential": "string",
- "l2_credential": "string",
- "chain_id": "string",
- "spec_version": "1.0"
}, - "format": "vi-sd-jwt",
- "spec_version": "1.0"
}Retrieves the widget configuration for a tenant. Returns the latest version by default, or a specific version if the version query parameter is provided.
| id required | string |
{- "tenant_id": "string",
- "widget_id": "string",
- "identity_providers": [
- {
- "provider": "eidas_eudi",
- "enabled": true,
- "config": { }
}
], - "taxonomy_libraries": [
- "@mandaitor/taxonomy-construction"
], - "mandate_templates": [
- { }
], - "branding": {
- "primary_color": "string",
- "logo_url": "string",
- "company_name": "string"
}, - "approval_workflow": {
- "require_principal_approval": true,
- "require_admin_approval": true,
- "auto_approve_trusted_idps": true
}, - "updated_at": "2019-08-24T14:15:22Z"
}Updates the widget configuration for a tenant. Creates a new versioned record. IdP credentials are stored in AWS Secrets Manager.
| id required | string |
| identity_providers | Array of objects |
| taxonomy_libraries | Array of strings |
| mandate_templates | Array of objects |
| branding | object |
| approval_workflow | object |
| webhook_url | string <uri> |
{- "identity_providers": [
- { }
], - "taxonomy_libraries": [
- "string"
], - "mandate_templates": [
- { }
], - "branding": { },
- "approval_workflow": { },
}{- "tenant_id": "string",
- "widget_id": "string",
- "identity_providers": [
- {
- "provider": "eidas_eudi",
- "enabled": true,
- "config": { }
}
], - "taxonomy_libraries": [
- "@mandaitor/taxonomy-construction"
], - "mandate_templates": [
- { }
], - "branding": {
- "primary_color": "string",
- "logo_url": "string",
- "company_name": "string"
}, - "approval_workflow": {
- "require_principal_approval": true,
- "require_admin_approval": true,
- "auto_approve_trusted_idps": true
}, - "updated_at": "2019-08-24T14:15:22Z"
}Validates an Identity Provider configuration by attempting a client credentials flow against the specified provider (Entra ID, Auth0, Okta, or eIDAS).
Alias support: Accepts both provider (canonical) and idpType (legacy).
If both are present, provider takes precedence.
| id required | string |
| provider | string Enum: "eidas_eudi" "entra_id" "auth0" "okta" Canonical field. The IdP type to validate. |
| idpType | string Deprecated Deprecated legacy alias for |
| config required | object |
{- "provider": "eidas_eudi",
- "idpType": "string",
- "config": { }
}{- "results": {
- "property1": {
- "valid": true,
- "message": "string"
}, - "property2": {
- "valid": true,
- "message": "string"
}
}
}Returns a paginated list of all configuration versions for the tenant, sorted by version number descending (newest first). Each entry contains version metadata (not the full configuration body).
| id required | string |
| limit | integer <= 100 Default: 20 |
| cursor | string |
{- "versions": [
- {
- "configVersion": 0,
- "updatedAt": "2019-08-24T14:15:22Z",
- "createdAt": "2019-08-24T14:15:22Z",
- "status": "string",
- "widgetId": "string",
- "rollbackFrom": 0
}
], - "next_cursor": "string"
}Rolls back the widget configuration to a previous version by creating a new version that is a copy of the target version. This preserves the full version history for audit purposes — no versions are deleted.
The new version includes a rollbackFrom field indicating which version
it was copied from.
| id required | string |
| version required | integer >= 1 The version number to roll back to |
{- "version": 1
}{- "message": "string",
- "version": 0,
- "rollbackFrom": 0,
- "widgetId": "string"
}