HTTP API

AgentInbox exposes a local control-plane HTTP API over either:

The HTTP surface is now resource-oriented and is intended to remain stable going forward.

Meta

Hosts

POST /hosts accepts the shared provider/runtime host configuration:

{
  "hostType": "github",
  "hostKey": "uxcAuth:github-default",
  "config": {
    "uxcAuth": "github-default"
  }
}

Streams / Sources

The canonical registration shape is host+stream:

{
  "hostId": "hst_...",
  "streamKind": "repo_events",
  "streamKey": "holon-run/agentinbox",
  "config": {
    "owner": "holon-run",
    "repo": "agentinbox"
  }
}

POST /sources is the stream-oriented creation endpoint. GET /sources/{sourceId} and related routes continue to operate on stream/source instances after registration.

Agents

Activation Targets

Timers

POST /timers accepts a narrow reminder body:

{
  "agentId": "agt_...",
  "at": "2026-04-15T08:00:00+08:00",
  "message": "Analyze the agentinbox project and prepare today's task plan.",
  "sender": "timer"
}

Use exactly one of at, every, or cron. every is an interval in milliseconds. timezone is optional and defaults to the daemon host timezone.

Subscriptions

POST /subscriptions accepts:

{
  "agentId": "agt_...",
  "sourceId": "src_...",
  "filter": {},
  "trackedResourceRef": "pr:373",
  "cleanupPolicy": {
    "mode": "on_terminal_or_at",
    "at": "2026-05-01T00:00:00.000Z",
    "gracePeriodSecs": 300
  }
}

cleanupPolicy defaults to {"mode":"manual"} when omitted.

POST /subscriptions always returns an envelope:

{
  "subscriptions": [
    {
      "subscriptionId": "sub_...",
      "agentId": "agt_...",
      "sourceId": "src_..."
    }
  ]
}

Non-shortcut creation returns one element. A shortcut may expand into multiple subscriptions, so callers should always read subscriptions[].

Inbox

POST /agents/{agentId}/inbox/items accepts a narrow direct-text ingress body:

{
  "message": "Review PR #51 CI failure and push a fix.",
  "sender": "local-script"
}

message is required. sender is optional.

POST /agents/{agentId}/inbox/ack accepts exactly one of:

{ "throughEntryId": "ent_..." }
{ "entryIds": ["ent_..."] }
{ "all": true }

Notes