Skip to content

Relay Protocol

This page documents the wire protocol used between the cinch CLI and the relay server. It is stable across patch versions; breaking changes are versioned.

If the relay is configured with AUTH_TOKEN, every request must include:

Authorization: Bearer <token>

Requests without a valid token receive 401 Unauthorized.

Push a new clip to the relay.

Request

POST /push HTTP/1.1
Content-Type: text/plain (or application/octet-stream for binary)
Content-Length: <bytes>
Authorization: Bearer <token> (if relay requires auth)
<clip payload>

Response

{
"id": 42,
"size": 1024,
"expires_at": 1714000000
}
StatusMeaning
200 OKClip stored
400 Bad RequestMissing or malformed body
401 UnauthorizedAuth token missing or invalid
413 Content Too LargeClip exceeds MAX_BODY_MB

Pull the most recent clip and return it in the HTTP response body. This is the non-streaming fallback; prefer the WebSocket endpoint for real-time delivery.

GET /pull HTTP/1.1
Authorization: Bearer <token>

Response

Returns the raw payload bytes with the original Content-Type. Returns 404 Not Found if no clip is available.

Returns 200 OK with {"status":"ok"}. No auth required.

Upgrade to WebSocket for real-time clip delivery. The relay pushes a message to all connected clients immediately when a new clip arrives via POST /push.

Upgrade request

GET /ws HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Authorization: Bearer <token>

Server-sent message (JSON)

{
"id": 42,
"payload": "<base64-encoded bytes>",
"mime_type": "text/plain",
"size": 1024,
"created_at": 1714000000
}

The payload field is always base64-encoded regardless of the original MIME type. Clients decode it and write the raw bytes to the local clipboard.

Keepalive

The relay sends a WebSocket ping every 30 seconds. Clients that do not respond within 10 seconds are disconnected. cinchd and the CLI reconnect automatically with exponential back-off (initial 1s, max 60s).

ContentContent-Type
Plain texttext/plain
Rich text (RTF)text/rtf
PNG imageimage/png
JPEG imageimage/jpeg
Arbitrary binaryapplication/octet-stream

The CLI auto-detects the content type from stdin using the first 512 bytes. You can override with --mime:

Terminal window
cat file.pdf | cinch push --mime application/pdf