Sockudo
Server

HTTP API

Publish events, query channels, read history, mutate messages, manage annotations, and operate push notifications.

Sockudo's HTTP API is a trusted server interface. Every production request must be signed with app credentials. Use a server SDK unless you are writing a custom integration.

Signing model

Signed requests include:

ParameterPurpose
auth_keyApp key.
auth_timestampUnix timestamp used to reject stale requests.
auth_versionSigning protocol version.
body_md5MD5 of the JSON body for body-bearing requests.
auth_signatureHMAC SHA-256 signature over method, path, and sorted query.

Publish an event

POST /apps/{app_id}/events
Content-Type: application/json
{
  "name": "order.created",
  "channel": "orders",
  "data": {
    "id": "ord_123"
  },
  "idempotency_key": "order-created-ord_123"
}

Use socket_id to suppress echo back to the originating connection.

When ai_transport and versioned messages are enabled for the target channel, AI events and publishes with message_id return serial acknowledgements under the channel entry. Retries with the same message_id or X-Idempotency-Key return the original serials without publishing a duplicate event.

{
  "channels": {
    "ai:session-1": {
      "message_serial": "00000000000000000001:test:00000000000000000001",
      "history_serial": 1,
      "delivery_serial": 1,
      "version_serial": "00000000000000000001:test:00000000000000000001"
    }
  }
}

Batch publish

POST /apps/{app_id}/batch_events
Content-Type: application/json
{
  "batch": [
    {
      "channel": "orders",
      "name": "order.created",
      "data": { "id": "ord_123" }
    },
    {
      "channel": "orders",
      "name": "order.paid",
      "data": { "id": "ord_123" }
    }
  ]
}

Batching reduces HTTP overhead, but do not use it to hide unbounded payloads. Keep per-event data compact.

Channel state

GET /apps/{app_id}/channels
GET /apps/{app_id}/channels/{channel_name}
GET /apps/{app_id}/channels/{channel_name}/users

Use state APIs for dashboards and admin tooling. Do not poll them as a substitute for realtime subscription events.

For channels matched by [ai_transport], GET /apps/{app_id}/channels/{channel_name} also includes:

{
  "ai": {
    "active_streams": 1,
    "last_history_serial": 42,
    "message_count": 7
  }
}

History

GET /apps/{app_id}/channels/{channel_name}/history?limit=50&direction=newest_first

History responses use opaque cursors. Store and replay cursors as strings; do not parse them.

Versioned messages

Protocol V2 mutable messages expose latest visible state and preserved versions:

GET /apps/{app_id}/channels/{channel_name}/messages/{message_serial}
GET /apps/{app_id}/channels/{channel_name}/messages/{message_serial}/versions
POST /apps/{app_id}/channels/{channel_name}/messages/{message_serial}/update
POST /apps/{app_id}/channels/{channel_name}/messages/{message_serial}/delete
POST /apps/{app_id}/channels/{channel_name}/messages/{message_serial}/append
{
  "data": {
    "body": "edited message"
  },
  "description": "user edit",
  "op_id": "edit-msg-1-v2"
}

Mutation responses preserve the existing fields and include serials for SDK ordering and retries:

{
  "channel": "ai:session-1",
  "message_serial": "msg_123",
  "action": "append",
  "accepted": true,
  "version_serial": "ver_456",
  "history_serial": 12,
  "delivery_serial": 34,
  "status": "applied"
}

Annotations

Annotations attach secondary state to a message without rewriting the message itself.

POST /apps/{app_id}/channels/{channel_name}/messages/{message_serial}/annotations
GET /apps/{app_id}/channels/{channel_name}/messages/{message_serial}/annotations
DELETE /apps/{app_id}/channels/{channel_name}/messages/{message_serial}/annotations/{annotation_serial}
{
  "type": "reactions:distinct.v1",
  "name": "like",
  "client_id": "user-1",
  "count": 1
}

Use annotations for reactions, read receipts, moderation signals, and summary projections.

Push notifications

Push APIs are first-class HTTP APIs, not separate infrastructure. They cover device registration, channel subscriptions, credential management, publish admission, status inspection, scheduling, cancellation, and provider callbacks.

Register a device

POST /apps/{app_id}/push/deviceRegistrations
Content-Type: application/json
{
  "device_id": "ios-device-1",
  "client_id": "user-42",
  "platform": "apns",
  "provider_token": "provider-token",
  "metadata": {
    "app_version": "4.5.0"
  }
}

Subscribe a device to a channel

POST /apps/{app_id}/push/channelSubscriptions
Content-Type: application/json
{
  "device_id": "ios-device-1",
  "channel": "orders",
  "client_id": "user-42"
}

Publish push

POST /apps/{app_id}/push/publish
Content-Type: application/json
{
  "recipients": [
    { "type": "channel", "channel": "orders" }
  ],
  "payload": {
    "title": "Order updated",
    "body": "Order ord_123 moved to packing",
    "data": { "order_id": "ord_123" }
  },
  "sync": false,
  "idempotency_key": "push-order-ord_123-packing"
}

Async push returns 202 Accepted with a publish_id.

Inspect publish status

GET /apps/{app_id}/push/publish/{publish_id}/status

Use this endpoint for operator tools, not user-facing busy loops.

Complete endpoint reference

This page explains the common server workflows. The complete route matrix, including health probes, stats, metrics, all push credential/template/device/subscription endpoints, presence history state, durable history repair, and annotation filters, is in the HTTP endpoint reference.

Error handling

Treat HTTP status codes as authoritative:

StatusMeaning
202Async work accepted, usually push delivery.
400Invalid request shape or unsupported option.
401Signature or key failure.
403App or feature disabled.
404Resource does not exist.
413Payload too large.
429Rate limited.
5xxServer or backend dependency failure.

On this page