Converse API — ADK
API reference for ADK conversation, streaming, skill generation, async execution, and direct LLM call endpoints
Updated 2026-11-03
Verified 2026-11-03
API reference for running agent turns on ADK. For architecture and configuration, see ADK.
All paths are relative to the ADK service root (port 8103 locally) under the base path /api/v1/adk. Base URLs, the Authorization and X-Org-Id headers, and the error envelope are described in API conventions, Authentication, Required headers, and Errors.
ADK also accepts these optional headers on authenticated routes:
| Header | Purpose |
|---|---|
X-Project-Id | Runs the request in a project scope; ADK authorizes the project and forwards it to MCP |
X-On-Behalf-Of-User-Id | Delegated user for service tokens |
For normal user tokens, every user_id in a body or query must equal the authenticated user (the token sub or user_id claim); otherwise ADK returns 403. A denied organization or project returns 403, and an unavailable authorization service returns 503.
Endpoints
| Method | Path | Description |
|---|---|---|
| POST | /converse/ | Synchronous turn |
| POST | /add-event/ | Inject an event into the caller's session |
| POST | /call_llm/ | Direct LLM call |
| WS | /converse_stream/ | V1 streaming |
| WS | /converse/v2 | V2 streaming |
| POST | /skills/generate | Skill proposals |
| POST | /async/requests/ | Submit an async request |
| GET | /async/requests/ | List async requests |
| GET | /async/requests/{request_id}/status/ | Async status and result |
| GET | /health/ (service root) | Health check, no auth |
Session endpoints are documented in the Sessions API.
Sync Converse
POST /api/v1/adk/converse/
Runs one turn against an agent or app and returns when the response is complete. Requires adk.agent.execute.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
agent_id, agent_version | string | conditional | — | Agent to run. Provide these or app_id/app_version. |
app_id, app_version | string | conditional | — | App to run; ADK uses the app's orchestrator agent. |
user_id | string | yes | — | Authenticated user ID. |
query | string | yes | — | User message. |
images | string[] | no | — | Base64 images or URLs. |
user_data | object | no | — | Values merged into session state. |
channel | string | no | chat | Channel identifier. |
language | string | no | no_language | Language hint. |
reasoning_event | boolean | no | true | Include reasoning events. |
sequenceNumber | integer | no | — | Echoed in the response. |
observability_metadata | object | no | — | Extra string dimensions recorded with the turn. |
{
"session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"sequenceNumber": 1,
"events": [],
"response": {"content": "Hello! How can I help?"}
}
If the agent or app version does not exist, ADK returns 404 with {"session_id": null, "response": "No agent with agent id: ... exists."}.
curl -X POST http://localhost:8103/api/v1/adk/converse/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Org-Id: YOUR_ORG_ID" \
-H "Content-Type: application/json" \
-d '{"agent_id": "AGENT_ID", "agent_version": "1.0", "user_id": "YOUR_USER_ID", "query": "What is the weather in London?"}'
Add Event
POST /api/v1/adk/add-event/
Appends an event to an existing session. Chat and Voice use it to complete the caller's own session. Requires authentication.
| Field | Type | Required | Description |
|---|---|---|---|
app_name | string | yes | App code. agent-<uuid> is normalized to agent_<uuid_with_underscores>. |
user_id | string | yes | Session owner. Must match the token unless the caller is a service or superuser. |
session_id | string | yes | Session ID. |
content | string | yes | Event text. |
state_delta | object | no | Values merged into session state. |
Returns 404 when the session is not in the caller's organization or belongs to a different app, and 422 when state_delta contains keys callers cannot set.
Direct LLM Call
POST /api/v1/adk/call_llm/
Calls a model directly through LiteLLM with the organization's BYOT credentials, without an agent.
| Field | Type | Required | Description |
|---|---|---|---|
provider | string | yes | google_ai, vertex_ai, azure_openai, azure_claude, aws_claude, azure_ai, smallest_ai, or inhouse |
model | string | yes | Model ID registered for the provider |
messages | array | yes | Chat messages (role, content) |
temperature, top_p | number | no | Sampling parameters |
max_tokens, max_completion_tokens | integer | no | Output limits |
stop | string or array | no | Stop sequences |
tools, tool_choice, parallel_tool_calls | — | no | Function calling |
response_format | object | no | Structured output |
stream, stream_options | — | no | When stream is true, the response is a JSON list of LiteLLM chunks |
The response is the LiteLLM chat completion object. For azure_ai models, ADK adapts the request to the Azure AI Foundry serverless API (for example, it renames max_tokens where needed and drops stream_options.include_usage).
WebSocket V1
WS /api/v1/adk/converse_stream/
The V1 stream remains for Chat. New clients should use V2.
The handshake requires Authorization: Bearer <token>. A missing or invalid token, or a token without a resolvable user, closes the socket with code 4401. X-Project-Id on the handshake is a fallback; browser clients send project_id in the start body.
start event
| Field | Type | Required | Description |
|---|---|---|---|
event | string | yes | "start" |
org_id | string | yes | Organization ID; the token must be authorized for it (otherwise close code 4403) |
agent_id/agent_version or app_id/app_version | string | yes | Target agent or app |
user_id | string | yes | Authenticated user ID |
project_id, project_name | string | no | Project scope and its display label |
user_data, channel, language, reasoning_event, sequenceNumber | — | no | Same meaning as in Sync Converse |
first_message | string | no | Greeting from the app configuration |
observability_metadata | object | no | Extra dimensions |
ADK resumes the user's latest non-completed session for the same app code, or creates a new one, and replies before agent setup finishes:
{"session_id": "SESSION_ID", "app_code": "agent_AGENT_ID", "user_id": "YOUR_USER_ID", "response": "Conversation Stream Setup"}
query event: {"event": "query", "query": "...", "images": [], "language": "en", "sequenceNumber": 2}. The server streams {"session_id": "...", "response": {"content": "...", "is_final": false}} frames and ends with is_final: true. Errors and cost notices arrive as {"response": "<message>"}. When a session or period cost limit is reached, the socket closes with code 4000.
WebSocket V2
WS /api/v1/adk/converse/v2
The recommended streaming endpoint. It supports client-defined tools, tool approvals, per-request prompt and model overrides, skills, extra knowledge base collections, test sessions, and negotiated voice turns. The handshake requires Authorization and X-Org-Id; X-Project-Id is optional.
Client events
start creates or resumes a session and may carry the first query.
| Field | Type | Default | Description |
|---|---|---|---|
user_id | string | required | Authenticated user ID |
query, images, image_attachments | — | — | First turn; image_attachments items are {name, mime_type, data_base64} |
agent_id, agent_version | string | "1.0" version | Agent to run |
app_id, app_version | string | "1.0" version | App to run |
session_id | string | null | null creates a session; an ID resumes it |
session_state | object | — | Initial state |
test_session | object | — | AI Testing Workspace selection: {schema_version: 1, name, tool_refs: [{id, type, version}], graph_ids} |
system_prompt | string | — | Prompt-only mode or prompt override |
additional_instructions | string | — | Appended to the prompt; never replaces it |
additional_collection_ids | string[] | — | Extra knowledge base collections |
tools | array | — | Client tools: {name, description, input_schema, display_name, tool_kind} |
exclude_tools | string[] | — | Tool names to drop |
provider_id, model_id, temperature, max_output_tokens | — | — | Model overrides |
thinking_mode | string | — | enabled, adaptive, or disabled |
reasoning_effort | string | — | low, medium, high, xhigh, or max |
skill_ids, skills | array | — | Skills; skills items are {id, version, allow_draft} |
guardrails, use_org_default_guardrails | — | false | Prompt-only guardrails |
client_tool_timeout_seconds | number | 120 | Client tool timeout, greater than 0 and at most 3600 |
org_id, project_id | string | — | Organization and project scope |
channel | string | chat | voice requires voice_protocol |
voice_protocol | string | — | "cosmos.voice.v2" for negotiated voice turns |
app_name | string | — | Observability label override |
language, reasoning_event, sequenceNumber, first_message | — | — | Same meaning as V1 |
observability_metadata | object | — | String dimensions for Observer |
session_profile | string | — | Session profile, such as coding or chat |
execution_context | object | — | {app_id, scope: {type, id}, manifest_hash, resources} for manifest-scoped runs |
execution_access_manifest_hash, execution_access_resources | — | — | Execution access manifest |
Context window and compaction settings are not client fields; ADK ignores them if sent.
{
"event": "start",
"user_id": "YOUR_USER_ID",
"org_id": "YOUR_ORG_ID",
"agent_id": "AGENT_ID",
"agent_version": "1.0",
"query": "What is the price of AAPL?",
"tools": [{
"name": "get_stock_price",
"description": "Get the current stock price",
"input_schema": {"type": "object", "properties": {"ticker": {"type": "string"}}, "required": ["ticker"]}
}]
}
Other client events
| Event | Fields | Description |
|---|---|---|
query | query, turn_id (1 to 128 characters), images, image_attachments, language, tools_add, tools_remove, sequenceNumber | Next turn. A query sent while a turn is running returns TURN_BUSY. |
tool_result | call_id, name, result or error | Result of a client tool call |
approval_decision | schema_version: 1, session_id, call_id, name, decision (approve or deny) | Answer to approval_required |
cancel | turn_id | Cancel the running turn |
pong | — | Reply to ping |
Server events
| Event | Fields | Description |
|---|---|---|
session | session_id, voice_protocol | Session ready |
chunk | content, turn_id, is_final | Response text |
tool_call | call_id, name, arguments (object), display_name, tool_kind | Run a client tool |
tool_call_args_delta | json_path, delta | Partial arguments while the model generates them |
tool_start, tool_complete | tool_complete adds result_preview, ok, is_error, duration_ms | Server-side tool progress |
approval_required | schema_version, session_id, call_id, name, argument_count, expires_in_seconds (300) | A tool needs approval; no answer denies it |
reasoning | reasoning_type, files | Agent, tool, file, skill, or knowledge base progress |
custom_event | — | Service-defined extension |
usage | prompt, completion, and cumulative tokens, token_threshold, context_limit | Token usage; clients use token_threshold for context gauges |
cost_warning | content, severity, session_id | Cost limit warning |
visible_turn | user_message_id, assistant_message_id | Message IDs for visible history and feedback |
turn_complete | session_id, turn_id, status (completed, cancelled, failed), end_conversation, usage, workflow | Exactly one per accepted turn |
error | code, turn_id, message, fatal | Fatal errors close the socket |
cancel_ack | — | Cancel received; a stale cancel does not close the session |
ping | — | Keep-alive |
Error codes: INVALID_REQUEST, FORBIDDEN, UNAVAILABLE, MANIFEST_MISMATCH, INVALID_APPROVAL, SESSION_NOT_FOUND, NO_SESSION, SESSION_SCOPE_MISMATCH, SESSION_INIT_FAILED, TURN_BUSY, AGENT_NOT_FOUND, AGENT_ERROR, UNSUPPORTED_TEST_AGENT, NO_LLM_CONFIG, MODEL_UNAVAILABLE, MODEL_TIMEOUT, RATE_LIMITED, CONTEXT_WINDOW_EXCEEDED, PROVIDER_HISTORY_INVALID, HISTORY_UNAVAILABLE, GUARDRAILS_UNAVAILABLE, CONFIGURATION_DRIFT, RESOURCE_UNAVAILABLE, TOOL_APPROVAL_TIMEOUT, PERIOD_COST_LIMIT, SESSION_COST_LIMIT, INTERNAL_ERROR.
Skill Generation
POST /api/v1/adk/skills/generate
Proposes skills from a conversation, an agent prompt, or a description. Requires the skill-generation permission.
| Field | Type | Default | Description |
|---|---|---|---|
source | string | required | conversation, agent_prompt, or description |
session_id or messages | — | — | For conversation: a session to read, or [{role, content}] messages |
agent_prompt or agent_id + agent_version | — | version "1.0" | For agent_prompt: prompt text, or an agent whose prompt (and sub-agents) ADK loads |
description | string | — | For description |
provider_id, model_id | string | organization default | Model override |
max_skills | integer | 5 | 1 to 10 |
max_tokens | integer | 16384 | 1024 to 65536 |
The response is {"proposals": [...], "summary": "..."}. Each proposal has name, description, instructions, allowed_tools, resources (references, assets, and scripts maps of file name to content), metadata (cosmos_knowledge_base_ids, category), and rationale.
Async Requests
Async requests run on a Celery worker. All three routes require authentication; non-superusers only see their own requests.
Submit
POST /api/v1/adk/async/requests/ returns 201 with {request_id, status, created_at}. The body takes the Sync Converse fields plus session_id, callback_url, callback_method (GET, POST, PUT, or PATCH; default POST), and callback_headers. ADK returns 400 when neither an agent nor an app is given and 404 when the version does not exist.
Status
GET /api/v1/adk/async/requests/{request_id}/status/
| Field | Description |
|---|---|
status | queued, processing, completed, or failed |
status_history, created_at, started_at, completed_at | Lifecycle |
session_id, sequence_number, response | Set when completed |
error_code, error_message | Set when failed |
callback_status | pending, in_progress, success, failed, retrying, or not_required |
callback_status_history, callback_last_attempt_time, callback_error_message | Callback delivery details |
List
GET /api/v1/adk/async/requests/?status=completed&limit=20&offset=0
Query parameters: user_id (must be the caller unless superuser), status, limit (1 to 100, default 20), offset (default 0). The response is {total, limit, offset, requests}, newest first; each item has request_id, status, query, created_at, started_at, completed_at, and session_id.
Health Check
GET /health/ on the service root returns {"status": "ok"} without authentication.