Requests and envelopes
One request document in, one envelope out. --json is the machine surface; the same shapes are what an agent or a script branches on, and every request is validated against the protocol before anything runs.
The envelope
{
"protocolVersion": 1,
"operation": "publish",
"ok": true,
"result": {},
"error": null
}{
"protocolVersion": 1,
"operation": "publish",
"ok": false,
"result": null,
"error": { "code": "INPUT_INVALID", "message": "The request document is not valid." }
}operation is one of connect, publish and status. A message is static text chosen by the code, never built from a stack, a path, a response body or an argument, so a diagnostic cannot carry a secret.
connect
Four request shapes. start begins a connection, resume completes a pending step, and update and disconnect maintain a stored one.
{
"type": "start",
"provider": "bluesky",
"label": "work",
"connectionId": "conn_existing",
"options": {}
}{
"type": "resume",
"connectSessionId": "cs_...",
"stepRevision": 0,
"input": { "type": "credentials", "credentials": { "identifier": "you.bsky.social", "password": "..." } }
}{
"type": "update",
"connectionId": "conn_...",
"changes": { "label": "writing", "isDefault": true }
}A resume input is either credentials with the provider's credential object, or callback_complete for a session whose authorization callback was delivered out of band. stepRevision must match the session, so a stale step is refused rather than applied twice.
{
"status": "action_required",
"connectSessionId": "cs_...",
"stepRevision": 1,
"expiresAt": "2026-10-08T00:15:00.000Z",
"action": { "type": "credential_input", "fields": [{ "name": "password", "label": "Bluesky app password", "secret": true }] }
}An action is credential_input, open_url or wait_for_callback. A finished step answers "status": "done" with the stored connection.
publish
Three request shapes: prepare freezes the content, execute sends it, and retry re-sends only the eligible targets of an earlier operation. A document without a type is an ordinary prepare request.
{
"type": "prepare",
"content": { "text": "One document, chosen targets." },
"targets": [
{ "provider": "bluesky" },
{ "provider": "devto", "connection": "conn_...", "options": { "title": "Hello", "body_markdown": "Body" } }
]
}{ "type": "execute", "approvalToken": "<token>" }{
"type": "retry",
"retryOf": "op_...",
"targets": [{ "provider": "bluesky", "connection": "conn_..." }]
}A target names its provider, optionally a connection and optional provider options. A document carries one to twenty targets. When a target names no connection, the provider's default connection is used, and an ambiguous choice is refused rather than guessed.
{
"status": "confirmation_required",
"operationId": "op_...",
"approvalToken": "...",
"expiresAt": "2026-10-08T00:15:00.000Z",
"preview": [
{ "deliveryId": "dl_...", "connectionId": "conn_...", "account": {}, "provider": "bluesky", "preview": { "content": {}, "fields": [] } }
]
}{
"phase": "execution",
"operationId": "op_...",
"status": "succeeded",
"deliveries": [
{ "deliveryId": "dl_...", "connectionId": "conn_...", "account": {}, "attempts": 1, "outcome": { "status": "succeeded", "remoteId": "...", "url": "https://example.com/post" } }
]
}The execution status is one of pending, running, succeeded, partial, failed or unknown. Each delivery outcome is succeeded, failed with disposition not_applied, or unknown; an eligible failed outcome may carry retryable, a reason and a retryAfter time. Failed means the write is known not to have been applied, and unknown is never retryable.
status
Five query shapes and no query language. With no selector the overview is returned.
| Request | Result |
|---|---|
{ "type": "overview" } | Whether the state is initialized, the connection count, each provider's availability and provenance, the most recent operations and the state health. |
{ "type": "provider", "provider": "bluesky" } | The provider's manifest, implementation fingerprints and observations. |
{ "type": "connections", "provider": "bluesky" } | The stored connections, optionally filtered to one provider. |
{ "type": "operation", "operationId": "op_..." } | One operation: either a prepared operation with its confirmation state and preview, or the execution result. |
{ "type": "operations", "limit": 20, "cursor": "..." } | Operation summaries, with an opaque cursor for the next page. |
Provider availability is available, untrusted, unavailable or stale, and provenance is official or third_party. Status reads stored observations; it does not refresh them by contacting a platform.
Execution status and the exit code
A publish result maps onto the process exit code: unknown exits 4, failed and partial exit 6, and every other execution status exits 0. A preflight or usage refusal exits 2, and an explicit decline at the confirmation prompt exits 5.