ACP Engine Enterprise API Documentation
ACP Engine provides public runtime APIs for realm resources and a Catalog API for independent merchant/store commerce data. Customer REST clients normally call the Engine base URL. External MCP clients call the public JSON-RPC endpoint exposed by the unified MCP service.
Base URLs
| Surface | Example | Purpose |
|---|---|---|
| ACP Engine REST API | https://acp.example.com/api/v1 | Configuration, runtime, tools, sessions, and usage. |
| Catalog REST API | https://acp.example.com/api/v1/catalog | Merchant/store Catalog operations through the normal Engine boundary. A dedicated Catalog hostname is deployment-optional. |
| ACP MCP service | https://mcp.example.com/ or https://mcp.example.com/mcp | MCP JSON-RPC access to approved Engine and Catalog operations. |
Use the environment URLs supplied during onboarding. Internal service addresses are not part of the customer contract.
Authentication
ACP Engine uses a long-lived access-key and secret-key pair only to obtain a short-lived bearer token.
Token Exchange
POST /api/v1/auth/token
Content-Type: application/json
{
"access_key": "{{access_key}}",
"secret_key": "{{secret_key}}"
}
Successful response:
{
"access_token": "eyJ...",
"expires_in": 900,
"token_type": "Bearer",
"user_id": "user_uuid",
"realm_id": "realm_uuid",
"user_type": "service"
}
Use the returned token for protected REST calls:
Authorization: Bearer {{token}}
Store access keys and secret keys in a server-side secret manager. Do not send them to a browser, mobile application, analytics platform, or log sink. Refresh the bearer token after expiration or a 401 response.
Request Conventions
- Send JSON bodies with
Content-Type: application/json. - Use IDs returned by the target environment. Resource IDs cannot be copied across realms.
- Include
realm_idwhen the request contract requires it, even when the token is already realm-bound. - Keep a stable
session_idonly for messages that belong to the same journey, and retain itsresume_tokenin protected server-side state. - Propagate
trace_idinto support and diagnostic records. - Treat provider keys, MCP keys, access keys, and secret keys as server-side credentials.
SDK, Observability, and Governance
The versioned TypeScript client contract is discovered through GET /api/v1/sdk/config. It exposes realm-scoped endpoint templates, supported transports, normalized runtime actions, and bounded request/action schemas. The SDK is a transport and rendering client; orchestration, policy, and downstream credentials remain in ACP Engine. The TypeScript ADK authors and simulates agents, flows, prompts, MCP bindings, providers, and routing rules, then diffs or deploys a reviewed configuration bundle through POST /api/v1/runtime/configuration/deploy. Bundle deployment never copies raw provider or MCP secrets.
| Method | Path | Purpose |
|---|---|---|
GET | /api/v1/sdk/config | Versioned client contract and render/action discovery. |
GET | /api/v1/observability/logs | Realm-scoped structured operational events. |
GET | /api/v1/observability/traces/{trace_id} | Correlated execution timeline. |
GET | /api/v1/observability/metrics | Request, error, latency, queue, provider, MCP, and autoscaling metrics plus fired alerts. |
GET, POST | /api/v1/observability/alerts | List or create realm alert rules. |
GET, POST | /api/v1/integrations/clients | List clients or create a one-time client secret. |
POST | /api/v1/integrations/clients/{id}/rotate-secret | Rotate with a bounded overlap window. |
GET | /api/v1/governance | Policies, allowlists, quotas, datasets, deployments, and audit snapshot. |
POST | /api/v1/governance/policies | Create a draft policy version. |
POST | /api/v1/governance/policies/{id}/activate | Atomically activate a policy version. |
POST | /api/v1/governance/allowlist | Create a scoped maker-checker allowlist request. |
POST | /api/v1/governance/allowlist/{id}/decision | Approve or reject a maker-checker allowlist request. |
PUT | /api/v1/governance/quotas | Create or replace the realm runtime quota policy. |
POST | /api/v1/governance/evaluation-datasets | Create a synthetic or approved-redacted dataset. |
POST | /api/v1/governance/evaluation-runs | Record a side-effect-free offline, shadow, or adversarial run. |
POST | /api/v1/governance/deployment-profiles | Record deployment ownership and data-handling controls. |
POST | /api/v1/governance/support-access | Record customer-approved, time-bound support access. |
POST | /api/v1/governance/lawful-requests | Record lawful-request/disclosure metadata. |
POST | /api/v1/runtime/webhooks | Create a signed HTTPS runtime webhook. |
GET | /api/v1/runtime/configuration/schema | Read the versioned portable configuration schema. |
GET | /api/v1/runtime/configuration/export | Export a secret-free, name-referenced realm bundle. |
POST | /api/v1/runtime/configuration/deploy | Dry-run/diff or transactionally deploy an ADK bundle. |
GET | /api/v1/usages/tools/summary | Aggregate realm tool usage and cost. |
POST | /api/v1/usages/export | Export realm usage as CSV or JSON. |
All routes above are realm-scoped. Unknown servers, undiscovered tools, disabled contracts, unknown arguments, cross-realm IDs, and direct high-impact tool calls fail closed. Active policy versions are pinned to executions and rechecked before side effects.
ACP chat rejects card data, CVV/CVC, payment authentication secrets, raw tokens, passwords, and full-address collection. CHECKOUT_HANDOFF and OPEN_WIDGET carry only opaque checkout and customer-controlled surface metadata; address, email, phone, and payment fields are excluded from their contract.
Health and Capabilities
| Method | Path | Authentication | Purpose |
|---|---|---|---|
GET | /api/v1/health | No | Process health for monitoring. |
GET | /api/v1/ready | No | Dependency readiness for traffic routing. |
GET | /api/v1/runtime/status | Bearer token | Realm runtime status. |
GET | /api/v1/runtime/capabilities | Bearer token | Capabilities exposed by the running Engine. |
Health proves that a process is alive. Readiness proves that the instance can receive traffic. Neither proves that a provider, flow, or MCP customer journey is correctly configured.
Authentication and Identity Endpoints
| Method | Path | Purpose |
|---|---|---|
POST | /api/v1/auth/register | Create an initial identity and optional realm when registration is enabled. |
POST | /api/v1/auth/token | Exchange access and secret keys for a bearer token. |
GET | /api/v1/auth/is-authenticated | Validate the current token and return identity context. |
POST | /api/v1/auth/keys | Create a new credential pair for the authenticated identity. |
GET, POST, PUT, PATCH, DELETE | /api/v1/users/{id} | Read or manage an allowed identity. |
Registration
POST /api/v1/auth/register
Content-Type: application/json
{
"username": "customer-admin",
"user_type": "user",
"realm_name": "Customer Production Realm"
}
The returned secret is available at creation time and must be stored immediately. Production registration availability is deployment-controlled.
Realm Endpoints
A realm is the tenant and resource-isolation boundary.
| Method | Path | Purpose |
|---|---|---|
POST | /api/v1/realms | Create a realm for the authenticated identity. |
GET | /api/v1/realms/{id}/members | List realm members. |
POST | /api/v1/realms/{id}/members | Add a realm member and role. |
POST | /api/v1/realms/{id}/agents | Create a realm agent identity. |
POST | /api/v1/realms/{id}/services | Create a realm service identity. |
POST | /api/v1/realms/{id}/identities/services | Create a backend service identity. |
GET, PUT | /api/v1/realms/{id}/theme | Read or update realm presentation configuration. |
Create a Service Identity
POST /api/v1/realms/REALM_ID/identities/services
Authorization: Bearer {{token}}
Content-Type: application/json
{
"username": "integration-service"
}
Use a service identity for backend-to-backend integrations. Assign it only the realm access required by that application.
AI Provider Endpoints
Providers define the model endpoint and secret used by runtime agents.
| Method | Path | Purpose |
|---|---|---|
GET | /api/v1/runtime/providers/templates | List supported provider configuration templates. |
GET | /api/v1/runtime/providers/templates/{type} | Read one provider template. |
GET | /api/v1/runtime/providers | List realm providers. |
POST | /api/v1/runtime/providers | Create a provider. |
GET | /api/v1/runtime/providers/{id} | Read provider metadata without exposing its secret. |
PUT | /api/v1/runtime/providers/{id} | Update provider configuration. |
PATCH | /api/v1/runtime/providers/{id}/toggle | Activate or deactivate a provider. |
DELETE | /api/v1/runtime/providers/{id} | Delete an unused provider. |
Create a Provider
POST /api/v1/runtime/providers
Authorization: Bearer {{token}}
Content-Type: application/json
{
"realm_id": "{{realm_id}}",
"type": "openai",
"name": "Production Model Provider",
"description": "Approved text and image provider for realm runtime journeys.",
"api_key": "provider-secret",
"base_url": "https://models.example.com/v1",
"supports_text": true,
"supports_image": true,
"text_model": "approved-text-model",
"image_model": "approved-image-model",
"input_price_per_million": 0,
"output_price_per_million": 0,
"image_price": 0,
"currency": "USD",
"is_default": true,
"is_active": true,
"settings": {
"temperature": 0.2,
"max_tokens": 2000
}
}
Use the provider template endpoint to discover supported types and fields. A provider can support text, image generation, or both. At least one capability must be enabled; text_model is required when supports_text is true and image_model is required when supports_image is true. The provider secret must not be returned by later read operations. Thyris-managed internal providers are not part of the customer-managed provider list.
Realm providers are not used by merchant Enrichment. Enrichment has a separate merchant-scoped provider registry and store-specific usage accounting.
Catalog Authentication and Endpoints
Catalog operations are scoped to an independent merchant and its stores. Create the key from Merchant Dashboard > Developers and send it as Authorization: Bearer {{merchant_api_key}}, x-api-key: {{merchant_api_key}}, or X-Catalog-API-Key: {{merchant_api_key}}.
Merchant keys support merchant scope for every merchant store, store scope for one store, merchant_network scope for the merchant and its direct sub-merchants, and custom scope for selected stores. Auth validates the key through /api/v1/auth/verify and /api/v1/auth/introspect; Catalog enforces the returned merchant and store scope on every operation, including calls originating from MCP.
The normal public boundary is the Engine route shown below. A dedicated Catalog ingress can be enabled for approved merchant integrations, but is not public by default and requires TLS, network controls, rate limits, and the same Auth service integration.
| Method | Path | Purpose |
|---|---|---|
GET | /api/v1/catalog/stores | List stores allowed by the authenticated merchant key. |
GET | /api/v1/catalog/products | List products using Merchant Services-compatible storeId and q filters. |
POST | /api/v1/catalog/products | Create or idempotently update a product using sku or externalId. |
GET | /api/v1/catalog/products/{productId} | Get one product by UUID. |
GET | /api/v1/catalog/product-details?catalogId={catalogId} | Read complete authorized product details without a Flow. Also supports productId, sku, or externalId. |
PATCH | /api/v1/catalog/products/{productId} | Partially update one product. |
DELETE | /api/v1/catalog/products/{productId} | Delete one product. |
GET | /api/v1/catalog/carts | List non-archived carts by default; use status=archived or includeArchived=true for history. |
POST | /api/v1/catalog/carts | Create a cart from Catalog product identifiers. |
POST, PATCH, DELETE | /api/v1/catalog/carts/items | Add, update, or remove one or more open-cart items; bundle payloads are atomic. Requires Idempotency-Key. |
POST | /api/v1/catalog/carts/clear?cartId={id} | Clear a cart that does not yet have a checkout ID. |
POST | /api/v1/catalog/carts/archive?cartId={id} | Permanently archive a cart. |
GET | /api/v1/catalog/orders | List orders, optionally filtered by storeId. |
POST | /api/v1/catalog/orders | Complete an order from a checkout ID and deduct inventory. |
GET | /api/v1/catalog/orders/{orderId} | Read an order by order UUID, public order ID, or checkout ID. |
PATCH | /api/v1/catalog/orders/{orderId} | Update allowed order status and detail fields. |
The older ACP /catalog/search, singular /catalog/product, and /catalog/orders/complete routes remain as compatibility aliases. Procurement endpoints are not part of ACP.
Upsert a Product
POST /api/v1/catalog/products
Authorization: Bearer {{merchant_api_key}}
Content-Type: application/json
{
"storeId": "{{store_id}}",
"sku": "SHOE-BLK-42",
"externalId": "erp-product-1842",
"name": "Black Running Shoe",
"description": "Lightweight road running shoe.",
"price": 149.90,
"currency": "USD",
"status": "active",
"inStock": true,
"inventoryQuantity": 40,
"imageUrls": [
"https://cdn.example.com/products/shoe-black-front.jpg",
"https://cdn.example.com/products/shoe-black-side.jpg"
],
"productUrl": "https://shop.example.com/products/shoe-black",
"metadata": {
"category": "running"
},
"variants": []
}
storeId, name, and price are required. Provide at least one stable sku or externalId so repeated synchronization requests update the same product. imageUrls accepts an ordered gallery of up to 20 URLs; the first item is treated as the primary image.
Create a Cart
POST /api/v1/catalog/carts
Authorization: Bearer {{merchant_api_key}}
Content-Type: application/json
{
"storeId": "{{store_id}}",
"items": [
{
"catalogId": "1234567890",
"quantity": 2
}
]
}
Cart items use the product's 10-digit catalogId, not the product UUID. A successful response includes a checkoutId used to complete the order.
Complete an Order
POST /api/v1/catalog/orders
Authorization: Bearer {{merchant_api_key}}
Content-Type: application/json
{
"checkoutId": "{{checkout_id}}",
"customer": {
"name": "Example Customer",
"email": "customer@example.com"
},
"shippingAddress": {
"line1": "Example Street 1",
"city": "Istanbul",
"country": "TR"
},
"paymentDetails": {
"provider": "customer-payment-service",
"reference": "payment-reference"
}
}
paymentDetails is optional. When supplied, send only payment-provider references or approved metadata; Catalog accepts an existing provider payment ID or generates an ACP payment ID when it is omitted. Never send raw card numbers, card verification values, or other sensitive authentication data to Catalog.
Catalog Webhook Ingress
Send Merchant Services-compatible inbound Catalog events to POST /api/webhooks/catalog with the same merchant Catalog key headers and a stable X-Webhook-Event-ID header of at most 255 characters. A missing event ID returns 400; replaying the same event ID for the same key returns 200 with duplicate: true. Outbound deliveries preserve the Catalog event source (api for REST and mcp for MCP).
Behavior Prompt Endpoints
Behavior prompts contain managed instructions and runtime constraints. The public route name is prompts.
| Method | Path | Purpose |
|---|---|---|
GET | /api/v1/runtime/prompts | List prompts in a realm. |
POST | /api/v1/runtime/prompts | Create a prompt version. |
GET | /api/v1/runtime/prompts/{id} | Read one prompt. |
PUT | /api/v1/runtime/prompts/{id} | Update a prompt. |
POST | /api/v1/runtime/prompts/{id}/activate | Activate a reviewed prompt. |
DELETE | /api/v1/runtime/prompts/{id} | Delete an unused prompt. |
Create a Prompt
{
"realm_id": "{{realm_id}}",
"name": "Commerce Assistant Prompt",
"key": "commerce_assistant_v1",
"content": "Understand customer intent, use only approved tools, and return concise customer-facing responses.",
"variables": ["locale", "channel", "customer_segment"],
"is_active": false
}
Create and test a candidate prompt before activation. Tool authorization must be enforced through agent and MCP configuration, not only through prompt text.
MCP Server Endpoints
An MCP server registration describes an approved downstream tool provider. Automatic discovery calls tools/list and stores the returned contracts.
| Method | Path | Purpose |
|---|---|---|
GET | /api/v1/runtime/mcp/servers | List registered servers. |
POST | /api/v1/runtime/mcp/servers | Register a server and optionally discover tools. |
GET | /api/v1/runtime/mcp/servers/{id} | Read server metadata. |
PUT | /api/v1/runtime/mcp/servers/{id} | Update URL, credential, or metadata. |
PATCH | /api/v1/runtime/mcp/servers/{id}/toggle | Enable or disable a server. |
POST | /api/v1/runtime/mcp/servers/{id}/test | Test connectivity and authentication. |
POST | /api/v1/runtime/mcp/servers/{id}/probe | Negotiate protocol capabilities and record health, latency, and authentication failures. |
PUT | /api/v1/runtime/mcp/servers/{id}/profile | Configure transport, authentication profile, credential reference, and egress policy. |
GET | /api/v1/runtime/mcp/servers/{id}/credentials | List secret-free credential version metadata and connection-test timestamps. |
POST | /api/v1/runtime/mcp/servers/{id}/credentials/{version}/rollback | Re-test and atomically reactivate a prior local credential version. |
POST | /api/v1/runtime/mcp/servers/{id}/contract-test | Refresh and validate discovered contracts. |
POST | /api/v1/runtime/mcp/servers/{id}/discover | Refresh the discovered tool registry. |
GET | /api/v1/runtime/mcp/servers/{id}/tools | List discovered tools. |
PUT | /api/v1/runtime/mcp/tools/{toolId}/review | Approve, reject, or quarantine a discovered tool. |
GET | /api/v1/runtime/mcp/servers/{id}/resources | List resources with pagination. |
GET | /api/v1/runtime/mcp/servers/{id}/resource-templates | List resource templates. |
POST | /api/v1/runtime/mcp/servers/{id}/resources/read | Read an approved resource. |
GET | /api/v1/runtime/mcp/tool-proposals | List AI-assisted capability proposals. |
POST | /api/v1/runtime/mcp/tool-proposals/generate | Generate bounded capability proposals without enabling tools. |
POST | /api/v1/runtime/mcp/tool-proposals/{proposalId}/review | Approve or reject a proposal without auto-enabling the tool. |
DELETE | /api/v1/runtime/mcp/servers/{id} | Delete an unused registration. |
POST | /api/v1/runtime/mcp/proxy | Call a specific registered server through the Engine. |
Register an MCP Server
POST /api/v1/runtime/mcp/servers
Authorization: Bearer {{token}}
Content-Type: application/json
{
"name": "Merchant Services MCP",
"url": "https://merchant.example.com/mcp",
"type": "http",
"description": "Approved product, cart, checkout, and order tools.",
"api_key": "scoped-downstream-key",
"is_active": true,
"capabilities": ["search", "cart", "checkout", "orders"],
"auto_discover": true
}
After creation, probe and contract-test the server. Streamable HTTP and SSE are supported directly; stdio requires a managed sidecar. API key, bearer, OAuth client credentials, mTLS, and customer-managed credential references are supported. Local credential rotation performs a live initialize check before atomic activation, keeps the previous version in a short overlap window, records secret-free audit history, and supports connection-tested rollback. Outbound hosts remain subject to allowlists, DNS rebinding protection, and private-network policy. Newly discovered tools stay disabled until their contract passes; write, destructive, financial, external-message, and sensitive tools also require explicit review. Sampling and elicitation require explicit realm policy, user presence, a bounded budget, and an audit record.
Routing Endpoints
Routing rules control how an intent or tool request resolves to approved MCP servers.
After tool eligibility is established, candidates are filtered and scored by server health, observed latency and error rate, estimated tool cost, region, and data-handling policy. Explicit routes are exclusive; registry and first-healthy routes use deterministic approved fallback order. Parallel aggregate routes return successful per-server results and bounded failure metadata. Rule timeout and retry settings are enforced; write retries require an idempotency key.
| Method | Path | Purpose |
|---|---|---|
GET, POST | /api/v1/runtime/mcp/routing/rules | List or create rules. |
GET, PUT, DELETE | /api/v1/runtime/mcp/routing/rules/{id} | Read, update, or delete a rule. |
POST | /api/v1/runtime/mcp/routing/preview | Resolve a route without executing the tool. |
POST | /api/v1/runtime/mcp/routing/reload | Reload the active rule set. |
GET | /api/v1/runtime/mcp/routing/trace/{traceId} | Read a routing decision trace. |
Preview a Route
POST /api/v1/runtime/mcp/routing/preview
Authorization: Bearer {{token}}
Content-Type: application/json
{
"realm_id": "{{realm_id}}",
"agent_id": "{{agent_id}}",
"flow_id": "{{flow_id}}",
"session_id": "{{session_id}}",
"intent": "product_search",
"tool_name": "search_products",
"messages": [
{
"role": "user",
"content": "Find black running shoes under 150 USD."
}
],
"context": {
"locale": "en-US",
"channel": "web"
}
}
Preview validates selection without producing the business side effect of a tool call.
Tool Selection and Execution
| Method | Path | Purpose |
|---|---|---|
POST | /api/v1/runtime/mcp/tools/route | Select a route for a requested tool or intent. |
POST | /api/v1/runtime/mcp/tools/execute | Route and execute one approved tool. |
POST | /api/v1/runtime/mcp/tools/execute-parallel | Execute an approved tool set in parallel. |
POST | /api/v1/runtime/mcp/tools/aggregate | Aggregate compatible tool results. |
GET, PUT | /api/v1/runtime/mcp/sessions/{sessionId}/context | Read or update MCP session context. |
Execute a Routed Tool
POST /api/v1/runtime/mcp/tools/execute
Authorization: Bearer {{token}}
Content-Type: application/json
{
"session_id": "{{session_id}}",
"tool_name": "catalog_get_product_details",
"arguments": {
"catalogId": "1234567890"
},
"strategy": "first_healthy"
}
This endpoint requires a known tool_name. It can select an eligible MCP server for that tool, but it does not classify customer intent, select a Flow, or return a runtime action. A protected BFF may use a fixed operation-to-tool mapping for a deterministic widget operation; the browser/mobile client must never choose tool_name or MCP server IDs. The response is a raw routed-tool envelope containing mcp_server_id, tool_name, and result. Send natural-language conversation to /runtime/ai/chat; use /runtime/execute when the caller requires a governed Flow and action envelope. Use parallel execution only for read operations or tools whose side effects are explicitly designed for concurrency. Do not automatically retry non-idempotent tools.
Flow Endpoints
A flow is a versioned customer journey that connects prompts, providers, agents, MCP servers, and execution steps.
| Method | Path | Purpose |
|---|---|---|
GET, POST | /api/v1/runtime/flows | List or create flows. |
GET, PUT, DELETE | /api/v1/runtime/flows/{id} | Read, update, or delete a flow. |
POST | /api/v1/runtime/flows/draft | Generate a bounded, reviewable flow draft from a natural-language goal. |
POST | /api/v1/runtime/flows/{id}/activate | Activate a reviewed flow. |
POST | /api/v1/runtime/flows/{id}/preview | Resolve and validate a flow without activation. |
POST | /api/v1/runtime/flows/{id}/execute | Execute a configured flow. |
GET | /api/v1/runtime/flows/{id}/versions | List immutable flow versions. |
POST | /api/v1/runtime/flows/{id}/publish | Compile and publish a compatible tested draft. |
POST | /api/v1/runtime/flows/{id}/archive | Archive a flow. |
POST | /api/v1/runtime/flows/{id}/rollback | Reactivate a pinned prior version. |
GET, POST | /api/v1/runtime/flows/{id}/fixtures | List or create deterministic fixtures. |
POST | /api/v1/runtime/flows/{id}/test | Replay fixtures with mocked external capabilities. |
POST | /api/v1/runtime/flows/{id}/promote | Promote a version through development, QA, UAT, or production bindings. |
GET, POST | /api/v1/runtime/flows/{id}/triggers | List or create event and schedule triggers. |
POST | /api/v1/runtime/flows/{id}/triggers/{triggerId}/fire | Fire an authenticated event trigger with a stable event ID. |
DELETE | /api/v1/runtime/flows/{id}/triggers/{triggerId} | Delete a flow trigger. |
GET | /api/v1/runtime/flow-routing-profiles | List realm Flow routing profiles. |
GET, PUT | /api/v1/runtime/flows/{id}/routing-profile | Read or replace one Flow's routing profile. |
GET, PUT | /api/v1/runtime/flow-routing-policy | Read or change realm mode, compatibility fallback, and canary percentage. |
POST | /api/v1/runtime/flow-routing-preview | Preview deterministic candidate filtering and routing without creating an execution. |
POST | /api/v1/governance/flow-routing-evaluations | Evaluate an approved labeled dataset without side effects. |
Create a Flow
{
"name": "Incident Triage",
"description": "Investigates service incidents and proposes safe next actions.",
"config": {
"schema_version": "2026-09-25",
"orchestration_mode": "hybrid",
"routing": {
"enabled": true,
"when_to_use": "Investigate service incidents and operational failures.",
"when_not_to_use": "Do not approve access requests.",
"capabilities": ["incident.triage", "logs.search"],
"allowed_handoffs": ["access.request", "human.escalation"],
"minimum_confidence": 0.75
},
"behavior": {
"instructions": "Act as an incident specialist and separate evidence from inference.",
"completion_criteria": ["Likely cause identified", "Safe next action proposed"]
},
"permissions": {
"allowed_actions": ["RESPOND", "CLARIFY", "ESCALATE"],
"risk_tier": "elevated"
},
"runtime": {"max_tool_calls": 3},
"nodes": [
{"id": "input", "type": "input"},
{
"id": "decide",
"type": "ai_decision",
"instructions": "Choose whether to investigate or ask for missing incident context.",
"minimum_confidence": 0.7,
"fallback_choice": "clarify",
"choices": [
{"key": "investigate", "description": "Enough context exists to investigate."},
{"key": "clarify", "description": "Required incident context is missing."}
]
},
{"id": "result", "type": "output", "action": "RESPOND"}
]
},
"is_active": false
}
The authenticated realm is taken from the bearer token. orchestration_mode accepts deterministic, adaptive, or hybrid. routing is the Flow's compact semantic selection manifest; behavior is the system-instruction fragment composed only after selection; permissions.allowed_actions restricts graph and AI-normalized outputs. A dedicated routing profile overrides the manifest when both exist.
Supported orchestration nodes include input, AI, bounded AI decision, MCP tool, MCP resource, condition, transform, parallel, bounded loop, approval, delay, event wait, pinned subflow, adaptive or deterministic supervisor, specialist agent, compensation, and output nodes. An ai_decision must declare two to twenty choices. Published graphs are compiled to immutable plans; unknown choices, undeclared output actions, unbounded cycles, and incompatible schema changes are rejected or fail safely at runtime.
Merchant Commerce MCP Reference Contract
The Merchant Commerce reference contract includes catalog_search, catalog_get_product, catalog_get_product_details, cart_create, cart_get, cart_add_item, cart_update_item, cart_remove_item, cart_add_bundle, cart_update_bundle, cart_remove_bundle, cart_archive, cart_clear, cart_close, checkout_prepare, checkout_get, and checkout_cancel. Merchant and accessible stores are derived from the authenticated key. Cart mutations and checkout preparation require idempotency keys. ACP session IDs, cart IDs, checkout IDs, and downstream MCP session handles are separate namespaces.
checkout_prepare returns an authoritative summary and an awaiting-payment handoff reference. ACP does not accept or process card data, CVV, OTP, payment tokens, full address, or payment-authentication state. A future Payment MCP consumes only the checkout handoff reference.
Changing config increments the flow version. Activation marks the flow as published and makes it the active flow for the realm. Preview the flow with representative user journeys before activation.
Generate a Flow Draft
POST /api/v1/runtime/flows/draft
Authorization: Bearer {{token}}
Content-Type: application/json
{
"goal": "Search approved catalog tools and return product cards.",
"channel": "web",
"agent_id": "{{optional_agent_id}}",
"name": "Product Discovery"
}
The result contains validated config, tool bindings, test fixtures, generated_by, and status: pending_approval. When an eligible realm agent and provider are available, ACP can generate the candidate semantically and then apply deterministic validation. Otherwise it returns a bounded deterministic fallback. Generation never publishes the draft. Review and approve it in Manager before activating the resulting flow.
Agent Runtime Configuration
| Method | Path | Purpose |
|---|---|---|
GET, PUT | /api/v1/runtime/agents/{agentId}/config | Read or update the provider, prompt, flow, and metadata. |
POST | /api/v1/runtime/agents/{agentId}/mcp-servers | Attach an allowed MCP server. |
DELETE | /api/v1/runtime/agents/{agentId}/mcp-servers/{serverId} | Detach an MCP server. |
POST | /api/v1/runtime/agents/{agentId}/flows/{flowId}/select | Select the agent's active flow. |
{
"realm_id": "{{realm_id}}",
"system_prompt_id": "{{prompt_id}}",
"ai_provider_id": "{{provider_id}}",
"default_flow_id": "{{flow_id}}",
"allowed_mcp_servers": ["{{mcp_server_id}}"],
"metadata": {
"owner": "commerce-team"
},
"settings": {
"max_tool_calls": 3,
"max_latency_ms": 30000,
"max_concurrency": 4,
"max_dependency_concurrency": 8,
"node_timeout_ms": 15000,
"max_node_retries": 2,
"retry_base_ms": 250,
"max_execution_cost": 1,
"max_orchestration_depth": 8,
"quality_tier": "standard",
"provider_region": "global",
"data_handling": "standard"
}
}
An attached server defines the maximum available tool set. Prompts do not grant access to a detached or disabled server.
Manager also supports realm-scoped agent profile rules. When a runtime request omits agent_id, enabled rules are evaluated by descending priority against channel, client_capabilities, metadata.user_segment, and metadata.deployment. If no rule matches, ACP selects the realm default agent. The resolved rule is recorded in safe execution metadata.
Sessions and Context
| Method | Path | Purpose |
|---|---|---|
GET, POST | /api/v1/runtime/sessions | List or create sessions. |
GET, PUT, PATCH, DELETE | /api/v1/runtime/sessions/{sessionId} | Read or manage session state. |
GET, POST | /api/v1/runtime/sessions/{sessionId}/messages | List or append messages. |
POST | /api/v1/runtime/sessions/{sessionId}/complete | Complete an active subject-bound session. |
POST | /api/v1/runtime/sessions/{sessionId}/cancel | Cancel an active subject-bound session. |
POST | /api/v1/runtime/sessions/{sessionId}/reset | Clear the pinned Flow for a deliberate new routing decision. |
POST | /api/v1/runtime/sessions/{sessionId}/resume-token/refresh | Rotate a valid resume token and optionally update chat label or metadata. |
POST | /api/v1/runtime/sessions/{sessionId}/resume-token/recover | Authorized service recovery of an active or expired session. |
GET | /api/v1/runtime/sessions/{sessionId}/status | Read effective session state without a resume token. |
GET, PUT | /api/v1/runtime/users/{userId}/context | Read or update allowed user context. |
GET, PUT | /api/v1/runtime/sessions/{sessionId}/state | Read or upsert typed, realm-scoped session state. |
DELETE | /api/v1/runtime/sessions/{sessionId}/state/{key} | Forget one typed state value without deleting audit history. |
POST | /api/v1/runtime/sessions/{sessionId}/summarize | Create a bounded conversation summary. |
GET, POST | /api/v1/runtime/knowledge | List or create provenance-aware realm knowledge. |
POST | /api/v1/runtime/knowledge/search | Search allowed realm knowledge. |
DELETE | /api/v1/runtime/knowledge/{knowledgeId} | Forget a knowledge item without deleting audit evidence. |
For session creation, bounded and non-expiring TTLs, chat labels, token rotation, recovery capability, status codes, and BFF storage, see Runtime Sessions, Chat IDs, and Recovery.
Session IDs, typed state, user preferences, MCP context, summaries, and knowledge are separate stores. A session or object identifier is never an authorization grant; every operation remains bound to the authenticated realm.
Anonymous Data Endpoints
The data service accepts only realm-scoped anonymous events after server-side PII removal and identifier pseudonymization. It stores searchable event data in the configured OpenSearch deployment.
| Method | Path | Purpose |
|---|---|---|
POST | /api/v1/data/events | Record one anonymous commerce, search, or conversation event. |
POST | /api/v1/data/events/batch | Record a bounded batch of anonymous events. |
GET | /api/v1/data/query | Query realm-scoped anonymous event data. |
GET | /api/v1/data/summary | Read realm-scoped event aggregations. |
Catalog and Runtime also record anonymous Activity events automatically: product listing/view, nonempty product search, cart creation, completed order/payment, and session user/assistant events. Raw chat text, customer details, and payment details are excluded. Events appear for actions after the producer services are deployed; historical actions are not backfilled. The optional idempotency_key field on POST /api/v1/data/events keeps retries on the same indexed event.
Create a Session
{
"agent_id": "{{agent_id}}",
"subject_type": "external",
"subject_id": "customer-reference-42",
"channel": "web",
"ttl_seconds": 86400,
"metadata": {
"locale": "en-US"
},
"transcript_retention": true
}
agent_id is required. flow_id is optional and should normally be omitted when the first customer message must choose the Flow automatically. subject_id is required for external and user subjects; ACP can generate it for the default anonymous subject. The response returns session_id, resume_token, and expires_at. Do not place credentials, raw payment data, or unnecessary personal information in session metadata.
Unified Runtime Execution
POST /api/v1/runtime/execute is the primary synchronous orchestration contract. It applies the same policy, agent resolution, AI/tool loop, reliability controls, approvals, normalized actions, and trace recording used by public MCP execution.
POST /api/v1/runtime/execute
Authorization: Bearer {{token}}
Content-Type: application/json
{
"version": "2026-08-22",
"flow_id": "{{optional_flow_id}}",
"session_id": "{{optional_session_id}}",
"resume_token": "{{required_when_resuming_a_new_session}}",
"channel": "web",
"locale": "en-US",
"input": {"message": "Find black running shoes under 150 USD."},
"client_capabilities": {
"vision": false,
"actions": [
"RESPOND",
"CLARIFY",
"RENDER_PRODUCTS",
"OFFER_PRODUCT_ALTERNATIVES",
"RENDER_PRODUCT_ALTERNATIVES",
"RENDER_PRODUCT_DETAILS",
"DATA_RESULT",
"APPROVAL_REQUIRED",
"ERROR"
]
},
"metadata": {
"user_segment": "returning",
"deployment": "production"
},
"idempotency_key": "journey-123-step-1",
"mode": "sync"
}
input is required. agent_id is optional when the realm has a matching profile rule or default agent. flow_id is optional: omit it for automatic selection or include it to force one validated Flow. resume_token is required whenever a newly created subject-bound session_id is resumed. version defaults to the current contract when omitted; clients that pin it must send 2026-08-22. mode accepts sync or async.
Durable execution endpoints are:
| Method | Path | Purpose |
|---|---|---|
POST | /api/v1/runtime/executions | Queue an asynchronous execution. |
GET | /api/v1/runtime/executions | List recent realm executions. |
GET | /api/v1/runtime/executions/{id} | Read execution state and result. |
POST | /api/v1/runtime/executions/{id}/cancel | Cancel an eligible execution. |
POST | /api/v1/runtime/executions/{id}/retry | Retry a retryable execution within its limits. |
POST | /api/v1/runtime/executions/{id}/resume | Resume an execution waiting on an allowed continuation. |
GET | /api/v1/runtime/executions/{id}/events | Stream execution events. |
GET | /api/v1/runtime/executions/{id}/actions | Replay normalized actions. |
POST | /api/v1/runtime/executions/{id}/approvals/{approvalId}/approve | Approve a waiting tool action. |
POST | /api/v1/runtime/executions/{id}/approvals/{approvalId}/deny | Deny a waiting tool action. |
The runtime distinguishes queued, running, waiting-for-approval, succeeded, retryable failure, terminal failure, cancelled, and compensated states. Retry only idempotent operations unless the tool contract and idempotency key make the write safe.
Runtime Conversational Chat
POST /api/v1/runtime/ai/chat is the primary message-oriented integration for conversational clients and BFFs. It uses the same Flow resolver as /runtime/execute; use /runtime/execute for structured sync/async controls.
POST /api/v1/runtime/ai/chat
Authorization: Bearer {{token}}
Content-Type: application/json
{
"agent_id": "{{agent_id}}",
"session_id": "{{session_id}}",
"resume_token": "{{resume_token}}",
"messages": [
{
"role": "user",
"content": "Find black running shoes under 150 USD."
}
]
}
agent_id and messages are required. session_id is optional but recommended for continuity; its matching resume_token is required when resuming a newly created subject-bound session. flow_id is optional. Omit it for automatic intent routing or include it to bypass classification and execute only that validated Flow. Caller-supplied provider, MCP server, or tool identifiers cannot override ACP policy.
The response can contain assistant content, a normalized action, structured data, execution/session identifiers, a trace ID, and safe routing diagnostics. Clients should switch on the action rather than infer behavior from assistant prose.
Common actions include:
| Action | Client behavior |
|---|---|
RESPOND | Render the assistant message. |
CLARIFY | Ask the customer for missing information. |
RENDER_PRODUCTS | Render structured products using the supported UI. |
OFFER_PRODUCT_ALTERNATIVES | Explain that the exact constraints were unavailable and ask permission before a broader search. Do not render product cards yet. |
RENDER_PRODUCT_ALTERNATIVES | Render verified broader products and retain requested/applied query plus relaxed-constraint provenance. |
RENDER_PRODUCT_DETAILS | Render the authorized detail view for one exactly resolved catalog product. |
ORDER_SUMMARY | Render authoritative existing order data in a summary or history view. |
ACTION_REQUIRED | Ask for explicit customer input before continuing. |
Flows can configure unavailable-result behavior with offer_first, show_immediately, or disabled. Under the recommended offer_first behavior, the first response is OFFER_PRODUCT_ALTERNATIVES; only an accepted same-session continuation executes the bounded broader query and returns RENDER_PRODUCT_ALTERNATIVES. The response preserves the original requested query, the applied query, and the relaxed constraints so a client never presents alternatives as exact matches.
For text product-detail requests, continue the same session and omit flow_id. ACP resolves an exact recent product ordinal, full name, or catalog identifier and returns RENDER_PRODUCT_DETAILS; missing or ambiguous references return CLARIFY without a detail lookup. A known widget selection may instead use the direct routed-tool endpoint above. That raw tool result is not a RENDER_PRODUCT_DETAILS action and must be validated and normalized by the BFF.
Clients should declare OFFER_PRODUCT_ALTERNATIVES, RENDER_PRODUCT_ALTERNATIVES, and RENDER_PRODUCT_DETAILS in client_capabilities.actions. Unsupported offers downgrade to RESPOND; unsupported structured alternatives/details downgrade to DATA_RESULT, with the intended action retained as metadata.original_type in structured runtime envelopes.
See the API Examples for explained request and response fixtures. For routing profiles, realm modes, session ownership, and endpoint comparisons, see Automatic Flow Routing.
Usage Endpoints
| Method | Path | Purpose |
|---|---|---|
POST | /api/v1/runtime/ai/usage | Record supported runtime AI usage. |
GET | /api/v1/runtime/ai/usage/stats | Read runtime provider and agent statistics. |
GET, POST | /api/v1/usages | List or record allowed usage entries. |
GET | /api/v1/usages/summary | Read realm and agent usage totals. |
Filter usage by realm, agent, session, or transaction type where supported. Usage data supports operational and cost analysis; it is not a payment settlement record.
Public MCP Service
The unified mcp-service exposes both internal MCP management routes and the public MCP JSON-RPC facade. External clients call POST / or POST /mcp and use initialize, tools/list, and tools/call. There is no separate acp-mcp workload.
Authentication Headers
Use a merchant API key for built-in Catalog tools:
Authorization: Bearer {{merchant_api_key}}
The equivalent x-api-key header is also accepted. Use the key's merchant, store, or custom access scope; Catalog rejects stores outside that scope.
Use these legacy realm service headers for realm-bound Engine tools:
X-ACP-Realm-ID: {{realm_id}}
X-ACP-Access-Key: {{mcp_service_access_key}}
X-ACP-Secret-Key: {{mcp_service_secret_key}}
Realm service identities and merchant API keys are separate credentials. A realm ID is not a merchant or store ID.
Initialize
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {"tools": {}},
"clientInfo": {
"name": "customer-mcp-client",
"version": "1.0.0"
}
}
}
Core Engine tools include:
acp_api_requestacp_mcp_authenticateacp_auth_registeracp_runtime_ai_chatacp_runtime_list_providersacp_runtime_mcp_execute_toolacp_usage_summary
Each active published flow is also exposed by tools/list as a versioned tool named acp_flow_<normalized_flow_name>_v<version>. Its business input and output schemas come from the stored flow contract; agentId, sessionId, and idempotencyKey are added as execution controls. Calling the tool executes the flow through the authenticated realm runtime and returns the normal MCP result envelope. Deactivating the flow removes it from subsequent tool listings.
Catalog tools include:
catalog_list_storescatalog_search_productscatalog_get_productcatalog_get_product_detailscatalog_upsert_productcatalog_delete_productcatalog_create_cartcatalog_mutate_cart_itemscatalog_archive_cartcatalog_clear_cartcatalog_complete_order
Call tools/list after initialization to obtain the active schemas. Catalog tools enforce the merchant key's allowed store scope. Write tools can modify products, carts, inventory, and orders and may emit configured outbound events.
Error Handling
| Status | Meaning | Client response |
|---|---|---|
400 | Invalid JSON, missing field, or invalid state. | Correct the request. Do not retry unchanged. |
401 | Missing, invalid, or expired credential. | Refresh the token or rotate the rejected key. |
403 | Authenticated identity lacks realm, merchant, store, or resource access. | Stop and correct authorization. |
404 | Resource is not present in the authenticated realm, merchant, or store scope. | Verify the environment and ID. |
409 | Resource or lifecycle conflict. | Read current state before deciding whether to retry. |
429 | Rate or capacity limit exceeded. | Retry with bounded exponential backoff. |
500, 502, 503, 504 | Engine or dependency failure. | Retry safe reads and idempotent operations only. |
Capture the response trace ID, timestamp, realm ID, agent ID, flow ID, session ID, endpoint, and status when escalating a problem. Do not include secrets or unredacted customer content.
Recommended Integration Sequence
- Exchange credentials for a bearer token.
- Validate the runtime token and target realm.
- Create or confirm a provider and prompt.
- Create a merchant-scoped developer key and synchronize representative products to an allowed store when the journey uses ACP Catalog.
- Register downstream MCP servers, test them, and discover tools.
- Configure the agent and create a flow.
- Preview routing and the flow.
- Create a test session and call runtime chat.
- Verify Catalog operations, structured actions, usage records, and trace data.
- Complete UAT before enabling production traffic.
Postman Companion Collection
This API reference is the integration contract. The Postman collection is retained as an optional development and UAT runner.
Download the ACP Engine Postman collection
Set base_url, mcp_base_url, runtime access_key and secret_key, merchant_api_key, and the target realm, merchant, and store resource IDs after import. Treat the collection as environment-specific test configuration and do not store production secrets in a shared workspace.