Ark API
The ark-api service exposes a REST interface for executing queries and managing resources. This page covers the base URL, authentication, conventions, the query workflow, and a reference of every endpoint group. Messages, chunks, traces, events, and sessions are served separately by the broker — see the Broker Service.
The authoritative, always-current reference is the built-in OpenAPI spec (/openapi.json) and its Swagger UI (/docs). Use this page for orientation and the endpoint index; use Swagger for full request/response schemas.
Base URL and interactive explorer
The API is served by the ark-api service. To reach it:
- In-cluster:
http://ark-api.<namespace>.svc.cluster.local(default port 80). - Local dev:
kubectl port-forward svc/ark-api 8000:80, then usehttp://localhost:8000. Or runark routes/devspace run routesto get a gateway URL such asark-api.default.127.0.0.1.nip.io:8000.
Open the Swagger UI at /docs to browse and try every endpoint:

Authentication
Ark APIs support multiple authentication methods depending on the AUTH_MODE configuration:
- OIDC/JWT — for dashboard users (
AUTH_MODE=ssoorhybrid). - API keys — for service-to-service communication (
AUTH_MODE=basicorhybrid). - No authentication — for development (
AUTH_MODE=open).
For programmatic access, create an API key and use HTTP Basic auth:
# Create a key
curl -X POST http://localhost:8000/v1/api-keys \
-H "Content-Type: application/json" \
-d '{"name": "My Service Key"}'
# Use it
curl -u "pk-ark-xxxxx:sk-ark-xxxxx" http://localhost:8000/v1/agentsJWT bearer tokens are also accepted: -H "Authorization: Bearer <token>". See the Authentication Guide for full configuration.
Conventions
A few conventions apply across the API:
- Namespace is a query parameter, not a path segment. Pass
?namespace=<name>to scope a request; it defaults to the API’s current context namespace. For exampleGET /v1/agents?namespace=team-a— there is no/v1/namespaces/{namespace}/agentspath. - Two response shapes. The typed resource endpoints (
/v1/agents,/v1/queries, …) return simplified JSON objects (flat fields likename,namespace,status), not raw Kubernetes manifests. The generic Resources API returns raw Kubernetes objects (apiVersion,kind,metadata,spec,status). - List responses wrap results in
{ "items": [ ... ] }. - Content negotiation — the generic Resources API returns JSON by default or YAML with
Accept: application/yaml.
Queries
Queries are the primary way to interact with Ark: POST /v1/queries sends input to any agent, team, model, or tool.
List available targets
curl http://localhost:8000/v1/agents
curl http://localhost:8000/v1/models
curl http://localhost:8000/v1/teams
curl http://localhost:8000/v1/toolsRun a query
POST /v1/queries is asynchronous — it creates the query and returns immediately, before execution finishes. Poll GET /v1/queries/{name} until status.phase is done (or error/canceled), then read status.response.content. (For token-by-token output, stream instead — see Streaming Responses.)
Python
import requests, time
base = "http://localhost:8000"
# 1. Create the query (returns immediately)
requests.post(f"{base}/v1/queries", json={
"name": "my-query",
"input": "Hello, how can you help me?",
"target": {"type": "agent", "name": "my-agent"},
}).raise_for_status()
# 2. Poll until it finishes
while True:
q = requests.get(f"{base}/v1/queries/my-query").json()
phase = q["status"].get("phase")
if phase in ("done", "error", "canceled"):
break
time.sleep(1)
print(q["status"]["response"]["content"])The completed query looks like this (fields are flat, not nested under spec/metadata):
{
"name": "my-query",
"namespace": "default",
"input": "Hello, how can you help me?",
"target": {"type": "agent", "name": "my-agent"},
"conversationId": "conv-abc123",
"status": {
"phase": "done",
"response": {"content": "Hello! How can I help you today?"},
"conversationId": "conv-abc123",
"tokenUsage": {"promptTokens": 1317, "completionTokens": 43, "totalTokens": 1360}
}
}Query fields
| Field | Required | Description |
|---|---|---|
name | Yes | Unique query name |
input | Yes | The user message text |
target | Yes* | Target with type (agent/team/model/tool) and name. Omit to use selector |
selector | No | Label selector to match a target instead of naming one |
type | No | Input type, defaults to "user" |
conversationId | No | Continue a previous conversation |
sessionId | No | Group queries for telemetry tracking |
parameters | No | Values used in the input or passed to agent parameters via queryParameterRef |
memory | No | A Memory resource for conversation context |
timeout | No | Query timeout, e.g. "5m" |
metadata.annotations | No | Custom Kubernetes annotations on the query |
Conversations
Pass the conversationId returned in status.conversationId to a later query to continue the thread — the memory service manages history automatically.
CONV=$(curl -s http://localhost:8000/v1/queries/my-query | jq -r .status.conversationId)
curl -X POST http://localhost:8000/v1/queries \
-H "Content-Type: application/json" \
-d "{
\"name\": \"followup\",
\"input\": \"And its population?\",
\"target\": {\"type\": \"agent\", \"name\": \"my-agent\"},
\"conversationId\": \"$CONV\"
}"Query different targets
The same request works for agents, teams, models, and tools — only target.type changes:
Agent
{"name": "q", "input": "Weather in NYC?", "target": {"type": "agent", "name": "weather-agent"}}Cancel a query
curl -X PATCH http://localhost:8000/v1/queries/my-query/cancelEndpoint reference
All endpoints are under /v1 and accept ?namespace=. This is a map of the surface — see /docs for full schemas.
Resources
Standard CRUD (GET/POST on the collection, GET/PUT/DELETE on the item):
| Resource | Endpoints |
|---|---|
| Agents | /v1/agents, /v1/agents/{name} |
| Teams | /v1/teams, /v1/teams/{name} |
| Models | /v1/models, /v1/models/{name} |
| Memories | /v1/memories, /v1/memories/{name} |
| Secrets | /v1/secrets, /v1/secrets/{name} |
| MCP servers | /v1/mcp-servers, /v1/mcp-servers/{name} (no PUT) |
| Tools | /v1/tools, /v1/tools/{name} (read/delete only — tools are created from MCP servers) |
| A2A servers | /v1/a2a-servers, /v1/a2a-servers/{name} (read/delete only) |
| A2A tasks | /v1/a2a-tasks, /v1/a2a-tasks/{name} (read/delete only) |
| Events | /v1/events, /v1/events/{name} (read only — Kubernetes events) |
| ArkConfig | /v1/arkconfig (GET/PUT/DELETE) |
| Namespaces | /v1/namespaces (GET/POST) |
Queries and conversations
| Purpose | Endpoints |
|---|---|
| Queries | GET/POST /v1/queries, GET/PUT/DELETE /v1/queries/{name}, PATCH /v1/queries/{name}/cancel |
| Conversations | GET/DELETE /v1/conversations, DELETE /v1/conversations/{id}, DELETE /v1/conversations/{id}/queries/{query_id}/messages |
| Memory messages | GET /v1/memory-messages, GET /v1/memories/{name}/conversations/{id}/messages |
Broker data
Telemetry the broker captures for a namespace. (The broker’s own HTTP API, including OTLP trace ingestion, is documented under the Broker Service.)
| Data | Endpoints |
|---|---|
| Chunks | GET/DELETE /v1/broker/chunks |
| Events | GET/DELETE /v1/broker/events, GET /v1/broker/events/{query_id} |
| Messages | GET/DELETE /v1/broker/messages |
| Sessions | GET/DELETE /v1/broker/sessions, GET /v1/broker/sessions/{id} |
| Traces | GET/DELETE /v1/broker/traces, GET /v1/broker/traces/{id} |
MCP authorization
| Purpose | Endpoints |
|---|---|
| OAuth flow | POST /v1/mcp-servers/{name}/auth/start, GET /v1/mcp-servers/{name}/auth/status, POST /v1/mcp-servers/{name}/auth/logout |
| Callback | GET /v1/mcp/auth/callback |
Marketplace and services
| Purpose | Endpoints |
|---|---|
| Ark services | GET /v1/ark-services, GET /v1/ark-services/{name}, GET /v1/ark-services/marketplace-items |
| Marketplace sources | GET/POST /v1/namespaces/{ns}/marketplace-sources, GET/PATCH/DELETE /v1/namespaces/{ns}/marketplace-sources/{name}, GET /v1/namespaces/{ns}/marketplace-sources/permissions |
| Marketplace items | GET /v1/namespaces/{ns}/marketplace-items |
| Service proxy | GET/POST /v1/proxy/{resource}/{server_name} (and /{path}), GET /v1/proxy/services, PATCH/DELETE /v1/proxy/services/{service_name}/{api_path} |
System and utilities
| Purpose | Endpoints |
|---|---|
| Context | GET /v1/context — current namespace and permissions |
| System info | GET /v1/system-info |
| Export | POST /v1/export/resources, GET /v1/export/last-export-time |
| File preview | POST /v1/file-preview/spreadsheet |
| A2A gateway | GET /a2a/agents — discover agents over A2A |
| Health | GET /health, GET /ready |
| API keys | GET/POST /v1/api-keys, DELETE /v1/api-keys/{public_key} |
Generic Resources API
Beyond the typed endpoints, the Ark API exposes a generic endpoint for reading any Kubernetes resource — core resources (Pods, Services, ConfigMaps) and grouped resources (Deployments, WorkflowTemplates, custom resources) — without a resource-specific endpoint. Unlike the typed endpoints, these return the raw Kubernetes object.
Endpoints
Core resources (API version v1):
GET|POST /v1/resources/api/{version}/{kind}
GET|DELETE /v1/resources/api/{version}/{kind}/{resource_name}Grouped resources (resources in API groups — apps, batch, custom groups):
GET|POST /v1/resources/apis/{group}/{version}/{kind}
GET|DELETE /v1/resources/apis/{group}/{version}/{kind}/{resource_name}Examples:
# Core: a Pod, and all Services
curl http://ark-api:8000/v1/resources/api/v1/Pod/my-pod
curl http://ark-api:8000/v1/resources/api/v1/Service
# Grouped: a Deployment, an Argo WorkflowTemplate, all Jobs
curl http://ark-api:8000/v1/resources/apis/apps/v1/Deployment/my-deployment
curl http://ark-api:8000/v1/resources/apis/argoproj.io/v1alpha1/WorkflowTemplate/my-workflow
curl http://ark-api:8000/v1/resources/apis/batch/v1/JobThere are also convenience log endpoints: GET /v1/resources/api/v1/namespaces/{namespace}/pods/{pod_name}/log and the Argo workflow node log endpoint.
Parameters
| Parameter | Description | Default |
|---|---|---|
namespace | Kubernetes namespace | Current context namespace |
curl "http://ark-api:8000/v1/resources/api/v1/Pod?namespace=production"Response format
Responses return the raw Kubernetes resource. Content negotiation via the Accept header returns JSON (default) or YAML:
curl -H "Accept: application/yaml" \
http://ark-api:8000/v1/resources/api/v1/Pod/my-podScope handling
The endpoint handles namespaced and cluster-scoped resources automatically: it tries namespaced access first, falls back to cluster-scoped, and errors only if both fail. This works transparently for resources like Nodes (cluster-scoped) and Pods (namespaced).
RBAC
The endpoint uses the service account configured for the Ark API pod. Ensure that service account has RBAC permissions for the resources you want to access.