Endpoints

The control plane and harness use separate sockets for turns, queries, operations, and execution. Each route requires the credentials listed below.

The control plane serves the turn, read, and operations routes. It owns the public API, reconciler, and approval checks, and commits turn records through the state plane. The state plane alone writes the durable event log. A harness runs the agent loop in an isolated pod and serves the execution route. config.rs sets the default addresses. An environment variable overrides each address.

The four sockets

Edges call the turn socket, and the web app calls the read socket. Cluster probes call the operations socket; the control plane calls the harness. The cluster does not expose the harness to external callers. A mobile client's backend acts as its edge, holding credentials and translating requests to the public API.

Four network sockets and their callers. A chat edge, an agent-to-agent edge, and a mobile app's backend call the turn socket on port 8080. The web app calls the read socket on port 8090. Cluster probes call the operations socket on port 8081. The control plane streams to a harness pod on port 50053. No caller outside the cluster reaches the harness.cluster networkcontrol planechat edgethread to turnagent-to-agent edgesigned agent cardmobile app edgeapp backend to turnweb appserver-side proxycluster probesreadiness, metrics:8080 turnConnect RPC + /v1/chat/completionsedge credential, signed envelope:8090 readreads over the event logbrowser session, three tiers:8081 operationshealth, readiness, metrics, drainno credential, cluster-only:50053 harnessone pod per conversationcontrol plane connectsturnturnturnreadsprobesstream
unary callstream
SocketDefault addressSet byBound when
Turn[::]:8080POLYCHROME_GRPC_ADDRAlways
Operations[::]:8081POLYCHROME_SIDE_ADDRAlways
ReadUnset.
The manifests set [::]:8090.
POLYCHROME_FORENSICS_ADDROnly when you set the address
Harness:50053The reconciler, per conversationOne socket per running conversation

The WhatsApp edge receives Meta's GET verification and signed POST deliveries at /whatsapp/webhook on its own listener (default :8102). It then calls the control plane's turn socket using edge credentials. Its health and metrics listener defaults to :8101. See WhatsApp for authentication and delivery limits.

The turn socket

The turn socket runs every turn. It speaks gRPC and the HTTP/JSON Connect protocol from one registration. A generated client and a curl command reach the same handler. The chat-completions route is a translation in front of that same handler. An edge presents an edge credential and a signed envelope. The signature binds each turn to the edge that sends it.

  • RPCstream
    /polychrome.agent.v1.AgentService/ConnectEdge credential

    Runs one turn. Streams the outputs until the turn ends or pauses.

  • RPC
    /polychrome.agent.v1.AgentService/ClassifyEdge credential

    Decides whether a message needs a turn.

  • RPC
    /polychrome.agent.v1.AgentService/InterruptEdge credential

    Cancels a turn that already runs.

  • RPC
    /polychrome.approval.v1.ApprovalService/RespondEdge credentialResolve token

    Answers a paused approval. Signs the answer and records the approver.

  • RPC
    /polychrome.question.v1.QuestionService/RespondEdge credential

    Answers a question that the agent stops to ask.

  • RPC
    /polychrome.persona.v1.PersonaService/*Edge credential

    Links, describes, and administers personas. Admin RPCs also need an admin persona.

  • RPC
    /polychrome.credential.v1.CredentialService/*Admin credential

    Enrolls, rotates, and revokes edge credentials while the process runs.

  • RPCstream
    /polychrome.ops.v1.NotificationService/SubscribeEdge credential

    Streams pending decisions to an edge. The edge shows each one to a person.

  • POSTstream
    /v1/chat/completionsEdge credential

    Runs a turn under the chat-completions schema. Streams the reply as SSE.

  • RPC
    /grpc.health.v1.Health/CheckNo credential

    Reports the serving state of the process and of AgentService.

An unmounted route returns 404. The control plane omits a service when a required authorization dependency is absent, such as persona hosting or credential storage.

The compatibility route

Compatible clients can send turns to this route with an edge credential and the required headers. The control plane stores conversation history and reconstructs it from the event log. The route forwards only messages after the last assistant reply as the new turn.

Put the conversation id in the X-Polychrome-Conversation header. You can use the conversation body field instead. Omit the id, and the server creates a web:{owner}.{random} id scoped to your credential. The server returns that id in the same response header.

Shell
curl -N http://polychrome-control-plane:8080/v1/chat/completions \
  -H 'authorization: Bearer pc_<edge-id>_<secret>' \
  -H 'content-type: application/json' \
  -H 'idempotency-key: <at least 8 bytes, unique per attempt>' \
  -d '{"model":"polychrome","stream":true,
       "messages":[{"role":"user","content":"summarize today's incidents"}]}'

The response schema includes two extensions. A turn that stops for a person ends with finish_reason: "tool_calls". It also carries a polychrome object that names the pending approval. A handoff to another agent appears in that same object. A client that ignores the object sees an ordinary completion. The module docs state the full subset that the route reads.

The read socket

The read socket serves transcripts and usage totals derived from signed event-log entries. The control plane binds this socket only when you set its address. Its browser routes require a session credential.

The routes enforce administrator, participant, or self access. Query scope remains limited by the caller's permissions.

  1. AdminEvery conversation, every persona, and deployment-wide usage totalsA session whose persona is an admin
  2. ParticipantOne conversation's transcript, approvals, and traceA session named on that conversation. An admin also qualifies.
  3. SelfYour own conversations and your own profileAny valid session
  • RPC
    /polychrome.web_auth.v1.WebAuthService/ExplorerAuthChallengeOpen ceremony

    Starts passkey authentication.

  • RPC
    /polychrome.web_auth.v1.WebAuthService/WalletAuthVerifyOpen ceremony

    Verifies wallet authentication and sets the session cookie.

  • GET
    /api/me/conversationsSelf

    Lists every conversation that the caller takes part in.

  • GET
    /api/conversations/{id}/transcriptParticipant

    Replays one conversation's messages from the event log.

  • GET
    /api/conversations/{id}/approvalsParticipant

    Lists every approval the conversation asks for. Shows the answer to each one.

  • RPCstream
    /polychrome.forensics.v1.ForensicsService/GetTraceStreamParticipant

    Follows a running conversation. Sends an event each time the trace changes.

  • POST
    /api/querySelf

    Runs one bounded query. The caller's permissions limit which records it reads.

  • POST
    /api/chat/turnSession with turn scope

    Dispatches a turn from the browser into one of the caller's conversations.

  • GET
    /api/conversationsAdmin

    Lists conversations across the deployment.

  • GET
    /api/usageAdmin

    Totals token usage across the deployment. Filters by persona and by time.

  • POST
    /admin/modelAdmin credential

    Changes the live model selection.

An unmatched path on this socket returns 401 rather than 404. This avoids confirming whether a guessed route exists. Protected responses carry no-store whether the request succeeds or fails authorization. The route table shows each route's authorization check.

The operations socket

The operations socket exposes process health and metrics without conversation data or credentials. A separate port lets the cluster's network policy restrict access to probes.

  • GET
    /healthzNo credential

    Answers 200 after the process starts.

  • GET
    /livezNo credential

    Answers 200 while the process runs.

  • GET
    /readyzNo credential

    Answers 200 only after every bound socket serves.

  • GET
    /metricsNo credential

    Publishes the process's counters and histograms for a scraper.

  • POST
    /drainNo credential

    Fails readiness. Traffic drains before shutdown.

Kubernetes probes readiness on the turn socket, not here. The operations socket can start serving before the turn socket is available. Kubernetes therefore uses the native gRPC health check on :8080. /drain flips that check to NOT_SERVING. See health.rs.

The harness socket

In per-conversation mode, each running conversation has a harness pod. The control plane connects after the reconciler attaches the sandbox. Network policy limits access to the control plane. The harness has no Kubernetes token and cannot call the Kubernetes API.

  • RPCstream
    /polychrome.harness.v1.HarnessService/ConnectThe control plane only

    Receives turn inputs from the control plane and streams outputs and tool calls back.

What you can reach from outside

The supplied cluster deployment keeps these sockets private. External turn requests pass through an edge that authenticates its callers before dispatch.

HostWhat answersHow it reaches a turn
polychrome.shThe web appIt proxies to the read socket and the turn socket. A browser session authorizes each call.
mcp.polychrome.sh/mcpThe repository MCP serverProvides repository tools; it does not dispatch conversation turns.
docs.polychrome.shThis siteStatic documentation; no turn dispatch.

See Edges for the adapter contract and Trust for approval requirements.