Sockudo
Reference

HTTP endpoints

Complete Sockudo endpoint matrix for WebSocket upgrades, HTTP APIs, push notifications, health checks, stats, and metrics.

Sockudo exposes three endpoint groups:

  • the main server port, usually 6001, for WebSocket upgrades and the signed app HTTP API
  • optional operational endpoints on the main server port
  • the metrics server port, usually 9601, for Prometheus scraping

Every route under /apps/{appId} requires Pusher-compatible signed query authentication. Push routes also evaluate the push capability headers described below.

WebSocket

MethodPathAuthPurpose
GET/app/{appKey}App key and channel-level protocol auth after connectWebSocket upgrade for Protocol V1 and Protocol V2 clients.

Supported query parameters:

ParameterScopeMeaning
protocolWebSocket1 or omitted uses Pusher-compatible Protocol V1. 2 enables Sockudo Protocol V2.
clientWebSocketClient library identifier. Accepted for compatibility and observability.
versionWebSocketClient library version. Accepted for compatibility and observability.
formatProtocol V2Wire format selector. Unknown V2 formats are rejected with 400 Bad Request.
echo_messagesProtocol V2Overrides per-connection echo behavior when echo control is enabled.
tokenProtocol V2Capability-token JWT alternative to unauthenticated app-key connect. The JWT header kid must match {appKey}.

Publish

MethodPathAuthPurpose
POST/apps/{appId}/eventsSigned app APIPublish one event to one or more channels.
POST/apps/{appId}/batch_eventsSigned app APIPublish multiple events in one request.
POST/apps/{appId}/revocationsSigned app APIRevoke Protocol V2 capability tokens by jti, client_id, or both. Matching local sockets receive sockudo:token_expired and close.
POST/apps/{appId}/users/{userId}/terminate_connectionsSigned app APIDisconnect every active socket for the supplied user ID.
POST/apps/{appId}/users/{userId}/force_reconnectSigned app APIClose every active socket for the supplied user ID with code 4200, prompting clients to reconnect.

Useful request controls:

Field or headerEndpointsMeaning
socket_idpublish endpointsSuppresses echo to the originating socket.
infopublish endpointsOptional response info such as subscription_count.
x-idempotency-keypublish endpointsDeduplicates accepted publishes when idempotency is enabled. Coordination failure returns retryable 503 instead of publishing without a claim.
idempotency_keypublish bodiesBody-level idempotency key accepted by Sockudo publish paths; retries must reuse the same key.
message_idpublish bodiesSDK-facing idempotent create key for AI/versioned-message publishes. Duplicate values return the original serial acknowledgement.

Revocation request body:

{
  "jti": "token-id",
  "client_id": "user-42",
  "expires_at": 1710003600,
  "ttl_seconds": 3600,
  "reason": "session revoked"
}

At least one of jti or client_id is required. ttl_seconds overrides expires_at; otherwise revocations default to 24 hours. Use the token's remaining lifetime for the TTL when it is known.

Channel state

MethodPathAuthPurpose
GET/apps/{appId}/channelsSigned app APIList occupied channels.
GET/apps/{appId}/channels/{channelName}Signed app APIRead state for one channel.
GET/apps/{appId}/channels/{channelName}/usersSigned app APIList current members of a presence channel.

Supported info tokens:

TokenEndpointsMeaning
subscription_count/channels, /channels/{channelName}, publish responsesInclude active subscription counts.
user_countpresence channel stateInclude presence user count.
cachecache channel stateInclude cache-channel occupancy details.

For channels matched by [ai_transport], /channels/{channelName} includes an ai object with active_streams, last_history_serial, and message_count.

Durable history

MethodPathAuthPurpose
GET/apps/{appId}/channels/{channelName}/historySigned app APIRead durable event history for one channel.
GET/apps/{appId}/channels/{channelName}/history/stateSigned app APIInspect stream continuity and degradation state.
POST/apps/{appId}/channels/{channelName}/history/resetSigned app APIRotate and reset a damaged or intentionally abandoned stream.
POST/apps/{appId}/channels/{channelName}/history/purgeSigned app APIPurge retained history without rotating continuity state.

History query parameters:

ParameterMeaning
limitPage size, bounded by server configuration.
cursorOpaque cursor returned by a previous page.
directionnewest_first or oldest_first.
start_serial, end_serialSerial range filter.
start_time_ms, end_time_msMillisecond timestamp range filter.

Presence history

MethodPathAuthPurpose
GET/apps/{appId}/channels/{channelName}/presence/historySigned app APIRead retained presence join/leave history.
GET/apps/{appId}/channels/{channelName}/presence/history/stateSigned app APIInspect presence-history continuity and degradation state.
POST/apps/{appId}/channels/{channelName}/presence/history/resetSigned app APIRotate and reset a presence-history stream.
GET/apps/{appId}/channels/{channelName}/presence/history/snapshotSigned app APIReconstruct a presence membership snapshot from retained history.

Presence history uses the same pagination and range controls as durable channel history. The snapshot endpoint is for operational reconstruction and should not be confused with /users, which returns current live members.

Versioned messages

MethodPathAuthPurpose
GET/apps/{appId}/channels/{channelName}/messages/{messageSerial}Signed app APIRead the latest visible version of a mutable V2 message.
GET/apps/{appId}/channels/{channelName}/messages/{messageSerial}/versionsSigned app APIList preserved versions of a mutable V2 message.
POST/apps/{appId}/channels/{channelName}/messages/{messageSerial}/updateSigned app APIApply a shallow mixin update and store a new version.
POST/apps/{appId}/channels/{channelName}/messages/{messageSerial}/deleteSigned app APIApply a soft delete version.
POST/apps/{appId}/channels/{channelName}/messages/{messageSerial}/appendSigned app APIAppend string content and store the rolled-up result.

Versioned-message endpoints require versioned_messages.enabled = true and a channel policy that permits mutable messages. They are Sockudo Protocol V2 surfaces. update, delete, and append accept optional op_id for mutation replay dedupe. Mutation responses include channel, message_serial, action, accepted, version_serial, history_serial, delivery_serial, and status.

Annotations

MethodPathAuthPurpose
GET/apps/{appId}/channels/{channelName}/messages/{messageSerial}/annotationsSigned app APIList annotation create/delete events.
POST/apps/{appId}/channels/{channelName}/messages/{messageSerial}/annotationsSigned app APIPublish an annotation event.
DELETE/apps/{appId}/channels/{channelName}/messages/{messageSerial}/annotations/{annotationSerial}Signed app APIPublish a delete event for an annotation.

Annotation request fields:

FieldEndpointMeaning
typecreate, list filterAnnotation type such as reactions:distinct.v1.
namecreateOptional logical annotation name.
clientId / client_idcreateUser or client identity associated with the annotation.
socketId / socket_idcreate/delete/listOptional socket used for capability checks and audit linkage.
countcreateNumeric annotation count.
datacreateArbitrary JSON payload.
encodingcreatePayload encoding marker.
from_seriallistReturn annotations after a known annotation serial.
limitlistPage size.

Annotations require versioned messages, global annotations.enabled, and channel-level annotation permission.

When built with ably-compat, the root compatibility router additionally exposes GET and POST /channels/{channelName}/messages/{messageSerial}/annotations. POST accepts an Ably annotation array for create or delete. GET negotiates JSON or MsgPack and returns relative first/next Link relations with an opaque cursor scoped to the app, channel, and message. Compatibility capabilities annotation-publish, annotation-subscribe, annotation-delete-own, and annotation-delete-any remain independent from message mutation capabilities.

Push notifications

Push notifications are a core Sockudo API surface. Push endpoints are available when the binary is built with the push feature. They use signed app authentication plus capability headers.

With ably-compat, the root router also exposes /push/publish, /push/deviceRegistrations, /push/channelSubscriptions, and /push/channels. These are DTO/auth projections over the same durable store, queue, planner, provider, feedback, retry, status, scheduler, and cleanup services listed below. The Ably realtime transport is a real MessageService provider delivery, not a synthetic provider success. Run the native monolith workers in an in-process deployment, or provide the corresponding external workers for the configured queue stages.

MethodPathAuthPurpose
POST/apps/{appId}/push/credentials/fcmSigned app API, push adminCreate or replace Firebase Cloud Messaging credential material.
POST/apps/{appId}/push/credentials/apnsSigned app API, push adminCreate or replace APNs credential material.
POST/apps/{appId}/push/credentials/webpushSigned app API, push adminCreate or replace Web Push VAPID credential material.
POST/apps/{appId}/push/credentials/hmsSigned app API, push adminCreate or replace Huawei Mobile Services credential material.
POST/apps/{appId}/push/credentials/wnsSigned app API, push adminCreate or replace Windows Notification Service credential material.
GET/apps/{appId}/push/credentialsSigned app API, push adminList provider credentials with secrets redacted.
POST/apps/{appId}/push/templatesSigned app API, push adminCreate or update a push payload template.
GET/apps/{appId}/push/templatesSigned app API, push adminList push templates.
GET/apps/{appId}/push/templates/{id}Signed app API, push adminRead one push template.
DELETE/apps/{appId}/push/templates/{id}Signed app API, push adminDelete one push template.
POST/apps/{appId}/push/deviceRegistrationsSigned app API, push admin or subscribeRegister or update a device.
GET/apps/{appId}/push/deviceRegistrationsSigned app API, push adminList device registrations.
DELETE/apps/{appId}/push/deviceRegistrationsSigned app API, push adminDelete devices by filter. Empty filters are rejected.
GET/apps/{appId}/push/deviceRegistrations/{id}Signed app API, push admin or device tokenRead one device registration.
DELETE/apps/{appId}/push/deviceRegistrations/{id}Signed app API, push admin or device tokenDelete one device registration.
POST/apps/{appId}/push/channelSubscriptionsSigned app API, push admin or subscribeUpsert a channel push subscription.
GET/apps/{appId}/push/channelSubscriptionsSigned app API, push adminList channel push subscriptions.
DELETE/apps/{appId}/push/channelSubscriptionsSigned app API, push admin or subscribeDelete subscriptions by channel or device.
GET/apps/{appId}/push/channelSubscriptions/channelsSigned app API, push adminList channels with push subscriptions.
POST/apps/{appId}/push/publishSigned app API, push adminAdmit one push publish request.
POST/apps/{appId}/push/batch/publishSigned app API, push adminAdmit multiple push publish requests.
GET/apps/{appId}/push/publish/{publishId}/statusSigned app API, push adminRead aggregate push publish status.
GET/apps/{appId}/push/deadLettersSigned app API, push adminList safe queue-native dead-letter metadata with optional provider, sinceMs, untilMs, limit, and cursor filters.
POST/apps/{appId}/push/deadLetters/{deadLetterId}/replaySigned app API, push adminRe-enqueue a replayable dead-letter's original queue item.
DELETE/apps/{appId}/push/scheduled/{jobId}Signed app API, push adminCancel a scheduled publish before dispatch when possible.
POST/apps/{appId}/push/deliveryStatusSigned app API, push adminIngest worker or provider delivery feedback.

Push publish bodies accept notBeforeMs to delay provider dispatch and expiresAtMs to stop late delivery and retry. The public API does not expose POST /push/scheduled; delayed delivery is created through /push/publish, while DELETE /push/scheduled/{jobId} only cancels jobs already persisted by scheduler/store integrations.

Publish responses include renderedPayloads. These previews are rendered from the same effective payload queued for delivery: templates are resolved at admission, request providerOverrides win over template overrides, and retries reuse the accepted rendered payload semantics. Missing templates, missing template variables, malformed overrides, and oversized provider payloads fail before provider dispatch.

Publish status inspection is available through GET /apps/{appId}/push/publish/{publishId}/status. Dead-letter messages are retained in the configured queue backend and are not exposed through a public HTTP listing endpoint yet.

Push headers:

HeaderValuesMeaning
x-sockudo-push-capabilitypush-admin, push-subscribeOmitted defaults to admin capability for trusted server calls. Client-assisted subscription flows use push-subscribe.
x-sockudo-device-identity-tokenBearer-style device tokenRequired when a non-admin request reads, updates, or deletes an existing device.
x-sockudo-rotate-device-identity-tokenbooleanAdmin-only device registration control that rotates the device identity token.
x-sockudo-push-quota-overrideimplementation-definedAdmin-only quota override hook for controlled operations.

Push list endpoints use cursor pagination with limit and opaque cursor.

Operational endpoints

MethodPathAuthPurpose
GET/liveNoneLiveness probe. Does not perform dependency checks.
GET/upNoneGlobal health probe.
GET/up/{appId}NoneApp-specific health probe.
GET/usageNone, when enabledMemory usage snapshot. Enabled by HTTP_API_USAGE_ENABLED.
GET/statsDispatches by authNative operator summary without Ably credentials; Ably interval stats with an Ably key or bearer token.
GET/operator/statsNone, when enabledUnambiguous alias for the native occupancy, memory, and history-health response.
GET/operator/stats/aggregationNone, with Ably compatibilityStats-worker backlog, capacity, dropped observations, flush failures, batch count, observation count, and last flush lag.
POST/statsAbly key or bearer tokenConformance fixture ingestion through the real stats store; available only when stats_fixture_ingest_enabled = true.

Ably GET /stats accepts interval IDs or epoch milliseconds for start and end, unit/by values minute, hour, day, or month, forward/backward direction, a bounded limit, and opaque cursors carried in Link headers. Pagination is anchored to interval IDs and a fixed query horizon.

Disable /usage, /operator/stats, and operator aggregation stats in exposed production environments unless they are behind trusted ingress controls.

Metrics endpoint

MethodPathPortAuthPurpose
GET/metricsMetrics port, default 9601None by defaultPrometheus plaintext scrape endpoint.

The metrics server is independent from the main WebSocket/API listener and is enabled by METRICS_ENABLED.

Signed app API parameters

All /apps/* requests use Pusher-style query signing:

ParameterMeaning
auth_keyApp key.
auth_timestampUnix timestamp used to reject stale requests.
auth_versionSigning protocol version, usually 1.0.
body_md5MD5 of the raw JSON body for body-bearing requests.
auth_signatureHMAC-SHA256 over method, path, and sorted query string.

Use server SDKs for signing when possible. Custom signers must sign the canonical path exactly as routed, including /apps/{appId}.

On this page