Skip to content
Cirrus home
Sign in

Reference

Webhooks

Signed HTTPS calls to your server when orders, trades or positions change.

Read the guide first

List webhooks #

GET /v1/postbacks app session

The signed-in user's webhooks (never their secrets), oldest first.

More about this

Event bodies are described in the document's webhooks section (order_update, trade, account_alert, positions, ping; components WebhookOrderUpdate, WebhookTrade, WebhookAccountAlert, WebhookPositions, WebhookPing), with how deliveries are signed and retried.

Errors

HTTPCodeWhen
401unauthorized

No credential, or the credential is invalid, expired or revoked.

403forbidden

The credential may not use this route (missing scope, app-session-only route, IP not allowed).

429rate_limited

Too many requests for this credential (or too many failed attempts); retry after the Retry-After header (seconds; error.retry_after_ms has the exact wait).

503webhooks_disabled

Webhooks are not enabled on this server.

503service_unavailable

A dependency is temporarily unavailable, or the feature is off on this server; retry later.

All fields (request and response schema)

Loading fields…

GET
curl "https://cirrus.pocketful.in/v1/postbacks" \
  -H "Authorization: token $CIRRUS_API_KEY"
Response · 200
{
  "status": "success",
  "data": [
    {
      "id": "pb_01m3pgps59en5pjhyj92tbsq65",
      "url": "http://127.0.0.1:63829/hooks/orders",
      "events": [
        "order_update",
        "trade"
      ],
      "accounts": [
        "P1"
      ],
      "description": "Order desk",
      "enabled": true,
      "disabled_reason": null,
      "disabled_at": null,
      "consecutive_failures": 0,
      "last_success_at": null,
      "last_failure_at": null,
      "previous_secret_expires_at": null,
      "secret_rotated_at": null,
      "created_at": "2026-09-29T12:02:21.993Z",
      "updated_at": "2026-09-29T12:02:21.993Z"
    }
  ],
  "error": null
}

Create a webhook #

POST /v1/postbacks app session

Registers an HTTPS receiver for the chosen events (optionally only for some of the user's accounts).

More about this

The signing secret is in this response only: store it now. A user may have at most 5 webhooks. Event bodies are described in the document's webhooks section (order_update, trade, account_alert, positions, ping; components WebhookOrderUpdate, WebhookTrade, WebhookAccountAlert, WebhookPositions, WebhookPing), with how deliveries are signed and retried.

Only the account holder, signed in themselves, can create webhooks.

Body fields

  • url string required

    The receiver: an https:// URL on a public host (private, loopback and link-local addresses are refused).

  • events string[] required

    Events to send, at least one: order_update, trade, account_alert, positions (ping cannot be subscribed to).

    One of: order_update, trade, account_alert, positions, ping

  • accounts string[] | null

    Only these of the user's accounts (non-empty, the user's own); leave out or null for every account, including ones added later.

  • description string | null

    A note for the owner, at most 200 characters.

Errors

HTTPCodeWhen
400malformed_json

The body is not JSON, or does not fit the request shape (unknown or missing fields, wrong types).

401unauthorized

No credential, or the credential is invalid, expired or revoked.

403own_session_required

Credentials can only be created from the user's own signed-in session.

403forbidden

The credential may not use this route (missing scope, app-session-only route, IP not allowed).

409webhook_limit_reached

The webhook limit is reached; delete one first.

422invalid_request

The request is well-formed but not valid; field names the input.

429rate_limited

Too many requests for this credential (or too many failed attempts); retry after the Retry-After header (seconds; error.retry_after_ms has the exact wait).

503webhooks_disabled

Webhooks are not enabled on this server.

503service_unavailable

A dependency is temporarily unavailable, or the feature is off on this server; retry later.

All fields (request and response schema)

Loading fields…

POST
curl -X POST "https://cirrus.pocketful.in/v1/postbacks" \
  -H "Authorization: token $CIRRUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "http://127.0.0.1:63829/hooks/orders",
    "events": [
      "order_update",
      "trade"
    ],
    "accounts": [
      "P1"
    ],
    "description": "Order desk"
  }'
Response · 201
{
  "status": "success",
  "data": {
    "id": "pb_01m3pgps59en5pjhyj92tbsq65",
    "url": "http://127.0.0.1:63829/hooks/orders",
    "events": [
      "order_update",
      "trade"
    ],
    "accounts": [
      "P1"
    ],
    "description": "Order desk",
    "enabled": true,
    "disabled_reason": null,
    "disabled_at": null,
    "consecutive_failures": 0,
    "last_success_at": null,
    "last_failure_at": null,
    "previous_secret_expires_at": null,
    "secret_rotated_at": null,
    "created_at": "2026-09-29T12:02:21.993Z",
    "updated_at": "2026-09-29T12:02:21.993Z",
    "secret": "whsec_kmM4VkgFv6UVjwsTRs15AdSvI23Js5hRdI8FN5OrYlQ=",
    "note": "Store the secret now: it is not shown again."
  },
  "error": null
}

Get a webhook #

GET /v1/postbacks/{id} app session

One webhook (never its secret): its settings and delivery health.

Parameters

  • id path · string required

    The webhook's id.

Errors

HTTPCodeWhen
401unauthorized

No credential, or the credential is invalid, expired or revoked.

403forbidden

The credential may not use this route (missing scope, app-session-only route, IP not allowed).

404webhook_not_found

No webhook with this id for the caller.

429rate_limited

Too many requests for this credential (or too many failed attempts); retry after the Retry-After header (seconds; error.retry_after_ms has the exact wait).

503webhooks_disabled

Webhooks are not enabled on this server.

503service_unavailable

A dependency is temporarily unavailable, or the feature is off on this server; retry later.

All fields (request and response schema)

Loading fields…

GET
curl "https://cirrus.pocketful.in/v1/postbacks/<id>" \
  -H "Authorization: token $CIRRUS_API_KEY"
Response · 200
{
  "status": "success",
  "data": {
    "id": "pb_01m3pgps59en5pjhyj92tbsq65",
    "url": "http://127.0.0.1:63829/hooks/orders",
    "events": [
      "order_update",
      "trade"
    ],
    "accounts": [
      "P1"
    ],
    "description": "Order desk",
    "enabled": true,
    "disabled_reason": null,
    "disabled_at": null,
    "consecutive_failures": 0,
    "last_success_at": null,
    "last_failure_at": null,
    "previous_secret_expires_at": null,
    "secret_rotated_at": null,
    "created_at": "2026-09-29T12:02:21.993Z",
    "updated_at": "2026-09-29T12:02:21.993Z"
  },
  "error": null
}

Change a webhook #

PATCH /v1/postbacks/{id} app session

Changes only the fields sent: url, events, accounts (null = every account), description (null removes it) and enabled.

More about this

enabled: true turns a webhook back on, also after it was turned off for failing (its failure count starts again). An empty body changes nothing.

Only the account holder, signed in themselves, can change webhooks.

Parameters

  • id path · string required

    The webhook's id.

Body fields

  • url string | null

    A new receiver URL (same rules as on creation).

  • events string[] | null

    A new event list (replaces the old one; at least one).

    One of: order_update, trade, account_alert, positions, ping

  • accounts string[] | null

    A new account list; null goes back to every account.

  • description string | null

    A new note; null or empty removes it.

  • enabled boolean | null

    false turns deliveries off; true turns them back on (also after the webhook was turned off for failing).

  • trigger_updates boolean | null

    true also sends trigger_update (a v2 trigger of the user changed; see the document's webhooks section); false stops it. A new webhook starts without it: opt in here.

Errors

HTTPCodeWhen
400malformed_json

The body is not JSON, or does not fit the request shape (unknown or missing fields, wrong types).

401unauthorized

No credential, or the credential is invalid, expired or revoked.

403own_session_required

Credentials can only be created from the user's own signed-in session.

403forbidden

The credential may not use this route (missing scope, app-session-only route, IP not allowed).

404webhook_not_found

No webhook with this id for the caller.

422invalid_request

The request is well-formed but not valid; field names the input.

429rate_limited

Too many requests for this credential (or too many failed attempts); retry after the Retry-After header (seconds; error.retry_after_ms has the exact wait).

503webhooks_disabled

Webhooks are not enabled on this server.

503service_unavailable

A dependency is temporarily unavailable, or the feature is off on this server; retry later.

All fields (request and response schema)

Loading fields…

PATCH
curl -X PATCH "https://cirrus.pocketful.in/v1/postbacks/<id>" \
  -H "Authorization: token $CIRRUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      "order_update",
      "trade",
      "positions"
    ],
    "accounts": null,
    "enabled": false
  }'
Response · 200
{
  "status": "success",
  "data": {
    "id": "pb_01m3pgps59en5pjhyj92tbsq65",
    "url": "http://127.0.0.1:63829/hooks/orders",
    "events": [
      "order_update",
      "trade",
      "positions"
    ],
    "accounts": null,
    "description": "Order desk",
    "enabled": false,
    "disabled_reason": "disabled_by_user",
    "disabled_at": "2026-09-29T12:02:21.997Z",
    "consecutive_failures": 0,
    "last_success_at": null,
    "last_failure_at": null,
    "previous_secret_expires_at": null,
    "secret_rotated_at": null,
    "created_at": "2026-09-29T12:02:21.993Z",
    "updated_at": "2026-09-29T12:02:21.997Z"
  },
  "error": null
}

Delete a webhook #

DELETE /v1/postbacks/{id} app session

Deletes the webhook; nothing more is sent to it.

More about this

Only the account holder, signed in themselves, can delete webhooks.

Parameters

  • id path · string required

    The webhook's id.

Errors

HTTPCodeWhen
401unauthorized

No credential, or the credential is invalid, expired or revoked.

403own_session_required

Credentials can only be created from the user's own signed-in session.

403forbidden

The credential may not use this route (missing scope, app-session-only route, IP not allowed).

404webhook_not_found

No webhook with this id for the caller.

429rate_limited

Too many requests for this credential (or too many failed attempts); retry after the Retry-After header (seconds; error.retry_after_ms has the exact wait).

503webhooks_disabled

Webhooks are not enabled on this server.

503service_unavailable

A dependency is temporarily unavailable, or the feature is off on this server; retry later.

All fields (request and response schema)

Loading fields…

DELETE
curl -X DELETE "https://cirrus.pocketful.in/v1/postbacks/<id>" \
  -H "Authorization: token $CIRRUS_API_KEY"
Response · 200
{
  "status": "success",
  "data": {
    "id": "pb_01m3pgps5ctt0rdj2zq50g1dad",
    "deleted": true
  },
  "error": null
}

Rotate a webhook's secret #

POST /v1/postbacks/{id}/rotate-secret app session

Issues a new signing secret, shown only in this response.

More about this

For 24 hours deliveries are signed with both the new and the previous secret (one signature each in webhook-signature), so the receiver can switch without losing any. Only the account holder, signed in themselves, can rotate secrets.

Parameters

  • id path · string required

    The webhook's id.

Errors

HTTPCodeWhen
401unauthorized

No credential, or the credential is invalid, expired or revoked.

403own_session_required

Credentials can only be created from the user's own signed-in session.

403forbidden

The credential may not use this route (missing scope, app-session-only route, IP not allowed).

404webhook_not_found

No webhook with this id for the caller.

429rate_limited

Too many requests for this credential (or too many failed attempts); retry after the Retry-After header (seconds; error.retry_after_ms has the exact wait).

503webhooks_disabled

Webhooks are not enabled on this server.

503service_unavailable

A dependency is temporarily unavailable, or the feature is off on this server; retry later.

All fields (request and response schema)

Loading fields…

POST
curl -X POST "https://cirrus.pocketful.in/v1/postbacks/<id>/rotate-secret" \
  -H "Authorization: token $CIRRUS_API_KEY"
Response · 200
{
  "status": "success",
  "data": {
    "id": "pb_01m3pgps5ctt0rdj2zq50g1dad",
    "url": "http://127.0.0.1:63815/hooks/alerts",
    "events": [
      "account_alert"
    ],
    "accounts": null,
    "description": null,
    "enabled": true,
    "disabled_reason": null,
    "disabled_at": null,
    "consecutive_failures": 0,
    "last_success_at": null,
    "last_failure_at": null,
    "previous_secret_expires_at": "2026-09-30T12:02:21.998Z",
    "secret_rotated_at": "2026-09-29T12:02:21.998Z",
    "created_at": "2026-09-29T12:02:21.996Z",
    "updated_at": "2026-09-29T12:02:21.998Z",
    "secret": "whsec_sesnDRH8eVMm3rJqiKEp0+QVa3wcLxUqhsXlqR2dqeQ=",
    "note": "Store the secret now: it is not shown again."
  },
  "error": null
}

Send a test delivery #

POST /v1/postbacks/{id}/test app session

Sends one signed ping event (body: component WebhookPing) to the webhook now, even when it is turned off, and says how the receiver answered.

More about this

One attempt, no retry; it is logged with the webhook's deliveries. Only the account holder, signed in themselves, can send tests.

Parameters

  • id path · string required

    The webhook's id.

Errors

HTTPCodeWhen
401unauthorized

No credential, or the credential is invalid, expired or revoked.

403own_session_required

Credentials can only be created from the user's own signed-in session.

403forbidden

The credential may not use this route (missing scope, app-session-only route, IP not allowed).

404webhook_not_found

No webhook with this id for the caller.

429rate_limited

Too many requests for this credential (or too many failed attempts); retry after the Retry-After header (seconds; error.retry_after_ms has the exact wait).

503webhooks_disabled

Webhooks are not enabled on this server.

503service_unavailable

A dependency is temporarily unavailable, or the feature is off on this server; retry later.

All fields (request and response schema)

Loading fields…

POST
curl -X POST "https://cirrus.pocketful.in/v1/postbacks/<id>/test" \
  -H "Authorization: token $CIRRUS_API_KEY"
Response · 200
{
  "status": "success",
  "data": {
    "event_id": "evt_cc2f23548b726e8a6a8bf980be542540",
    "delivered": true,
    "status_code": 200,
    "duration_ms": 0,
    "error_kind": null
  },
  "error": null
}

List a webhook's delivery attempts #

GET /v1/postbacks/{id}/deliveries app session

Every delivery attempt of the last 7 days, newest first: event, attempt number, outcome, the receiver's status and timing (never the body).

More about this

Page with limit and cursor.

Parameters

  • id path · string required

    The webhook's id.

  • limit query · integer

    Page size, 1-200 (default 50).

  • cursor query · string

    next_cursor of the previous page.

Errors

HTTPCodeWhen
400invalid_query

The query string does not fit the route's parameters.

401unauthorized

No credential, or the credential is invalid, expired or revoked.

403forbidden

The credential may not use this route (missing scope, app-session-only route, IP not allowed).

404webhook_not_found

No webhook with this id for the caller.

422invalid_request

The request is well-formed but not valid; field names the input.

429rate_limited

Too many requests for this credential (or too many failed attempts); retry after the Retry-After header (seconds; error.retry_after_ms has the exact wait).

503webhooks_disabled

Webhooks are not enabled on this server.

503service_unavailable

A dependency is temporarily unavailable, or the feature is off on this server; retry later.

All fields (request and response schema)

Loading fields…

GET
curl "https://cirrus.pocketful.in/v1/postbacks/<id>/deliveries" \
  -H "Authorization: token $CIRRUS_API_KEY"
Response · 200
{
  "status": "success",
  "data": {
    "deliveries": [
      {
        "id": "01M3PGPS5DF35SYE2PF2KKBM9V",
        "event_id": "evt_cc2f23548b726e8a6a8bf980be542540",
        "type": "ping",
        "attempt": 1,
        "outcome": "delivered",
        "status_code": 200,
        "duration_ms": 0,
        "error_kind": null,
        "at": "2026-09-29T12:02:21.997Z"
      }
    ],
    "next_cursor": null
  },
  "error": null
}