Yoke.sh
Reference

HTTP API

Complete HTTP endpoint reference — executor portal, control plane on 8090, and metrics.

Yoke exposes HTTP on two logical servers in multi-tenant deployments:

ServerDefault portPurpose
Executor portal8080User portal routes, /health, /metrics
Control plane8090Conversations, actors, schedules, tenant ingress

Executor — system routes

GET  /health     → ok
GET  /metrics    → Prometheus text format

Executor — portal routes

User-defined in definePortal().routes:

{ method: "POST", path: "/webhooks/slack", handler: async (req, ctx) => { ... } }

Path parameters parsed from req.path (e.g. /agents/:agentId/join).

Agent bootstrap routes

Register these on an executor portal when exposing agent creation from HTTP:

POST /agents
POST /agents/:agentId/join

Not /rooms — forums are conversations created via Chat SDK or control plane. See Agent bootstrap.

Control plane — base path

/v1/tenants/:tenant_id

Start with:

yoke control-plane --port 8090

Tenants

Register and inspect tenants; append events to wake cold executors.

POST /v1/tenants
GET  /v1/tenants/:tenant_id
POST /v1/tenants/:tenant_id/events

Create tenant

curl -X POST http://localhost:8090/v1/tenants \
  -H 'content-type: application/json' \
  -d '{"id":"acme","packageRef":"./your-package"}'

Response:

{
  "id": "acme",
  "packageRef": "./your-package",
  "runtimeStatus": "cold"
}

Get tenant

curl http://localhost:8090/v1/tenants/acme

Returns packageRef and runtimeStatus (cold, starting, hot, …).

Append event

curl -X POST http://localhost:8090/v1/tenants/acme/events \
  -H 'content-type: application/json' \
  -d '{"type":"slack.message.received","payload":{"channel":"#general","text":"hello"}}'

Response:

{ "seq": 1, "id": "<uuid>" }

Appends to the tenant stream and signals the scheduler (may wake a cold executor).

Actors

POST   /actors
GET    /actors/:actor_id

Conversations

POST   /conversations
GET    /conversations/:conversation_id

Participants

POST   /conversations/:conversation_id/participants
POST   /conversations/:conversation_id/participants/:participant_id/leave
GET    /conversations/:conversation_id/participants

Messages

POST   /conversations/:conversation_id/messages
GET    /conversations/:conversation_id/messages

Query params: latest, limit, before, after, branchId.

Branches

POST   /conversations/:conversation_id/branches
GET    /conversations/:conversation_id/branches

Blobs

POST   /blobs
GET    /blobs/:blob_id
GET    /blobs/:blob_id/content

Requires YOKE_STORAGE=s3 and YOKE_S3_BUCKET.

Schedules

POST   /schedules
GET    /schedules
DELETE /schedules/:key

Tenant ingress (agent bootstrap proxy)

POST /v1/tenants/:tenant_id/ingress/*

Proxies to tenant executor for createAgent / joinConversation when executor is hot.

SDK HTTP clients

import { createChatHttpClient, createAgentBootstrapHttpClient } from "@yoke/sdk";

const chat = createChatHttpClient({ baseUrl: "http://localhost:8090", tenantId: "default" });
const agents = createAgentBootstrapHttpClient({
  baseUrl: "http://localhost:8090/v1/tenants/default/ingress",
});

Response formats

  • JSON bodies for CRUD endpoints
  • Raw bytes for blob content (GET .../blobs/:id/content)
  • Prometheus text for /metrics

Authentication

Authentication is deployment-specific — not enforced by core runtime. Place API gateways, mTLS, or JWT validation in front of control plane ingress in production.

On this page