Skip to main content

Frontend and SDK Integration Guide

This guide explains how customer web, mobile, or backend clients should connect to ACP Engine. It is written for frontend and application teams that need to send user intent, manage sessions, render AI responses, and work with SDK-style runtime configuration.

Frontend Integration Model​

The frontend should act as a thin client:

  • Initialize using public runtime configuration.
  • Obtain or receive an authenticated token through the approved customer auth flow.
  • Create or reuse a session ID.
  • Send user messages to ACP Engine.
  • Render ACP Engine responses.
  • Avoid direct calls to downstream MCP servers.

ACP Engine handles configured assistant behavior, approved tool selection, tool execution, usage recording, and trace correlation.

For web applications, use a server-side frontend adapter or backend-for-frontend route between the browser and ACP Engine. This adapter can safely exchange credentials for a short-lived ACP Engine token, call runtime APIs, and normalize responses for the browser.

This pattern keeps secret keys out of browser code and gives the customer application one place to handle token exchange, session management, response normalization, and support logging.

  1. Load SDK/runtime configuration.
  2. Establish user or service authentication.
  3. Resolve realm_id and agent_id; normally omit flow_id so ACP can route the customer's first intent.
  4. Create or reuse a session_id.
  5. Send the versioned input to the runtime execution API.
  6. Render response content and any structured data returned by the runtime.

Runtime and Theme Configuration​

Frontend backends can read the authenticated runtime capability surface and realm theme through supported Engine routes:

GET /api/v1/sdk/config
Authorization: Bearer {{token}}
GET /api/v1/runtime/capabilities
Authorization: Bearer {{token}}
GET /api/v1/realms/{{realm_id}}/theme
Authorization: Bearer {{token}}

These responses can be used to configure:

  • Versioned endpoint, transport, request, and normalized-action contracts.
  • Enabled runtime features.
  • Public theme metadata.
  • Supported Engine capabilities.

Resolve agent and flow IDs through approved backend configuration or Manager. Do not invent or copy IDs from another realm or environment.

Theme and Public Configuration Loading​

Frontend applications can load customer-specific theme or public configuration during server-side rendering or application startup. If the theme request fails, the frontend should use a safe local visual default and continue rendering a controlled experience. A runtime-capability failure should stop protected runtime actions until the backend can verify Engine state.

Recommended behavior:

  • Request configuration with a server-side ACP Engine token.
  • Merge API-provided configuration over local defaults.
  • Avoid exposing private provider, MCP, or credential data to the browser.
  • Cache only public configuration and only for an agreed duration.

Session Creation​

Create a session when a new customer conversation starts:

POST /api/v1/runtime/sessions
Content-Type: application/json
Authorization: Bearer {{token}}

{
"agent_id": "{{agent_id}}",
"subject_type": "external",
"subject_id": "customer-reference-42",
"channel": "web",
"ttl_seconds": 86400,
"metadata": {
"locale": "en-US"
}
}

Keep the returned session_id, resume_token, and expires_at in protected BFF state for the duration of the conversation. Rotate a valid token with the refresh endpoint; a separately authorized service identity may recover an expired session when continuity is required. Send the same session ID and resume token in chat and structured execution requests. The browser may hold an opaque HttpOnly cookie but must not read or log the resume token.

Executing a Customer Journey​

New integrations should use the versioned runtime execution contract:

POST /api/v1/runtime/execute
Content-Type: application/json
Authorization: Bearer {{token}}

{
"version": "2026-08-22",
"agent_id": "{{agent_id}}",
"session_id": "{{session_id}}",
"resume_token": "{{resume_token}}",
"channel": "web",
"input": {
"message": "I need a waterproof jacket for hiking."
},
"client_capabilities": {
"actions": [
"RESPOND",
"CLARIFY",
"RENDER_PRODUCTS",
"OFFER_PRODUCT_ALTERNATIVES",
"RENDER_PRODUCT_ALTERNATIVES",
"RENDER_PRODUCT_DETAILS",
"APPROVAL_REQUIRED",
"ERROR"
]
},
"idempotency_key": "journey-123-step-1",
"mode": "sync"
}

The example intentionally omits flow_id, so the shared resolver selects an eligible Flow. Supplying a protected server-configured flow_id forces one exact validated Flow.

POST /api/v1/runtime/ai/chat is the primary conversational/BFF endpoint. Its body requires agent_id and ordered messages; session_id, its conditional resume_token, and flow_id are optional or conditional. Use /runtime/execute for structured sync/async controls. Caller-supplied provider, MCP server, or tool identifiers do not override authenticated realm, Agent, Flow, discovered-tool, or routing policy. See Automatic Flow Routing.

Response Handling​

Runtime execution responses use a versioned envelope with execution, session, trace, status, normalized actions, output, error, and usage metadata. Clients should branch on normalized action types instead of inferring UI behavior from free-form text.

  • action: response action or tool-driven rendering hint.
  • content: text response for the customer.
  • session_id: current session ID.
  • provider: provider metadata.
  • token_usage: token usage summary.
  • cost: estimated cost metadata.
  • data: structured result data, such as product results or tool output.

Frontend clients should support both plain text responses and structured data rendering. For example, a commerce frontend may render products when data contains product results.

Common Rendering Actions​

The frontend should support a small action contract:

  • RESPOND: render conversational text.
  • CLARIFY: render a follow-up question.
  • RENDER_PRODUCTS: render product cards, product lists, or product carousels.
  • OFFER_PRODUCT_ALTERNATIVES: explain that the exact constraints were unavailable and ask permission before running a broader search.
  • RENDER_PRODUCT_ALTERNATIVES: render verified broader results and preserve the requested query, applied query, and relaxed constraints.
  • RENDER_PRODUCT_DETAILS: render the authorized detail view for one catalog-backed product.
  • RENDER_ORDER_CONFIRMATION: render the completed order only after the merchant order operation succeeds.
  • ORDER_SUMMARY: render authoritative existing order data in a summary or history view.
  • CART_UPDATED: render authoritative cart state.
  • DATA_RESULT and OPERATION_RESULT: render authoritative structured results.
  • CHECKOUT_HANDOFF and OPEN_WIDGET: open a customer-controlled checkout or widget using opaque handoff metadata only.
  • ACTION_REQUIRED: render a modal or form for customer input.
  • APPROVAL_REQUIRED: render a pending approval state without replaying the write.
  • PROGRESS: update a durable execution progress view.
  • HANDOFF: transfer the user to an approved human or customer-owned surface.
  • ERROR: display only the safe userMessage; use errorCode and boolean retryable for controlled recovery.

A conversational Flow can respond directly without forcing an MCP call when its configured policy permits it. Product cards and detail views must use catalog-backed IDs and fields; do not invent products, prices, inventory, merchant profiles, or image URLs. A product Flow can configure unavailable-result behavior as offer_first, show_immediately, or disabled. offer_first preserves the customer's exact constraints and waits for consent before executing the bounded broader query.

Product details have three integration paths:

  1. For a known card or widget selection, a protected BFF may call /api/v1/runtime/mcp/tools/execute with a fixed allowlisted catalog_get_product_details mapping and the exact retained catalogId. The endpoint returns a raw routed-tool result, not a runtime action.
  2. When the caller requires the ACP execution and action envelope, it can call a protected product-details Flow through /api/v1/runtime/execute; the successful Flow returns RENDER_PRODUCT_DETAILS.
  3. For a natural-language request such as “show the third product's details,” call /api/v1/runtime/ai/chat without flow_id. ACP resolves only an exact recent product reference and returns RENDER_PRODUCT_DETAILS, or CLARIFY without a lookup when the reference is unresolved.

The browser or mobile client may send the selected product identifier to its BFF, but it must never choose tool_name, MCP server IDs, or flow_id. A direct Merchant integration can alternatively use the authenticated Catalog product-details endpoint or Merchant MCP tool.

Declare OFFER_PRODUCT_ALTERNATIVES, RENDER_PRODUCT_ALTERNATIVES, and RENDER_PRODUCT_DETAILS in client_capabilities.actions. If a client does not declare support, ACP safely downgrades an offer to RESPOND and structured alternative/detail actions to DATA_RESULT; structured action metadata retains original_type.

A handled Flow failure can return HTTP 200 with an ERROR action. A runtime failure may return HTTP 502 with the same normalized action under action, data, and actions; parse the body on that status and display only userMessage. Diagnostic error.message belongs in protected support logs.

Use the action list returned by /api/v1/sdk/config. If a client receives an action outside the negotiated contract, fail closed to a safe generic state and record the trace ID; do not infer or execute a side effect from an unknown action.

Flow Selection​

When the frontend needs a specific journey, it can select a flow:

POST /api/v1/runtime/agents/{{agent_id}}/flows/{{flow_id}}/select
Content-Type: application/json
Authorization: Bearer {{token}}

{
"session_id": "{{session_id}}",
"persist_for_agent": false
}

Use session-level flow selection for temporary journeys, campaigns, or special support experiences. Use agent-level defaults for stable production behavior.

User Context​

User context stores durable preferences and customer-specific metadata:

PUT /api/v1/runtime/users/{{user_id}}/context
Content-Type: application/json
Authorization: Bearer {{token}}

{
"preferences": {
"currency": "USD",
"locale": "en-US"
},
"commerce": {
"preferred_categories": ["shoes", "electronics"]
},
"metadata": {
"consent": true
}
}

Do not store secrets, payment credentials, private tokens, or unnecessary sensitive data in user context.

Frontend Responsibilities​

The frontend should:

  • Keep the access token in a secure client-appropriate storage model.
  • Refresh or reacquire tokens when they expire.
  • Preserve session ID during a conversation.
  • Render content and structured data returned by ACP Engine.
  • Display friendly error messages.
  • Forward trace IDs to support teams when reporting issues.

The frontend should not:

  • Store secret keys in browser-accessible code.
  • Call downstream MCP servers directly.
  • Hardcode provider credentials.
  • Reimplement routing logic on the client.
  • Expose platform IDs in user-visible UI unless needed for support.

TypeScript SDK and ADK​

@thyris/acp-client is the typed, realm-scoped consumer package. It discovers the versioned contract, provides HTTP, SSE, and polling transports, and renders normalized actions. Keep authentication and all service credentials in the frontend backend.

@thyris/acp-adk is an authoring and deployment package, not a browser runtime. It validates and simulates flows with explicit AI/MCP mocks, exports and diffs secret-free name-referenced bundles, and deploys through /api/v1/runtime/configuration/deploy. Service identities need configuration:read for schema/export and configuration:write for plan/apply. Non-dry-run ADK deployment additionally requires the explicit ACP_APPLY=true operator gate.

Configuration bundles contain agents, flows, prompts, providers, MCP servers, and routing rules. They never contain raw provider or MCP secret values; provision secrets separately in the target realm.

Tool Execution from Frontend Backend​

When the customer application needs to run an explicit business action, send it through the versioned runtime contract so agent permissions, routing, policy, approval, idempotency, usage, and trace recording stay active.

Recommended endpoint:

POST /api/v1/runtime/execute
Authorization: Bearer {{token}}
Content-Type: application/json

{
"version": "2026-08-22",
"agent_id": "{{agent_id}}",
"session_id": "{{session_id}}",
"input": {
"intent": "catalog_search",
"query": "black shoes",
"limit": 25
},
"idempotency_key": "catalog-search-123",
"mode": "sync"
}

Use direct /api/v1/runtime/mcp/proxy calls only for controlled diagnostics where the server ID and tool are intentionally fixed. A browser must never call a downstream MCP server directly.

Suggested Error Handling​

401 Unauthorized : Re-run token exchange or redirect the user through the approved authentication path.

403 Forbidden : The authenticated identity does not have access to the requested realm, agent, or resource.

404 Not Found : Verify IDs such as realm_id, agent_id, flow_id, mcp_server_id, or session_id.

429 Too Many Requests : Apply client-side backoff and retry after the recommended delay.

5xx : Show a friendly fallback message and include trace information in support logs.

Frontend QA Checklist​

  • SDK configuration loads successfully.
  • Token exchange or token handoff works.
  • Session creation works.
  • Runtime execute works with a plain text response.
  • Runtime execute works with structured data and approval-required responses.
  • Flow selection works.
  • User context update works.
  • Token expiration is handled gracefully.
  • Trace ID is captured for failed requests.