Skip to main content
POST
/
cs2
/
v1
/
recovery
/
initiate_request
Initiate Oddin-style stateful recovery
curl --request POST \
  --url https://ticktock.bet/cs2/v1/recovery/initiate_request \
  --header 'X-API-Key: <api-key>'
{}

Documentation Index

Fetch the complete documentation index at: https://docs.ticktock.bet/llms.txt

Use this file to discover all available pages before exploring further.

When to call it

Use this endpoint whenever your AMQP consumer falls behind and you need to resync without polling REST for every match individually. Typical triggers:
  • AMQP connection dropped and your durable queue’s TTL elapsed.
  • Service restart with no persisted last-message timestamp.
  • The <alive> message arrived with subscribed="0" (producer downtime) — Oddin convention is to immediately initiate recovery.

How it works

You make a single REST call. The server schedules a background replay onto your tenant’s AMQP vhost (the same exchange the live feed uses, ttfeed). For every booked match the replay publishes:
  1. One <odds_change> listing the current active B2B market offers with up-to-date odds.
  2. One <bet_settlement> per match for offers settled between after and now.
  3. One <bet_cancel> per match for offers voided between after and now.
  4. A terminating <snapshot_complete request_id="…"> so you know the replay is finished.
Recovery messages carry a recovery=1 AMQP header and use routing-key priority lo (vs live hi). You can route them to the same queue as live or bind a separate queue for them.

Required scope

  • Minimum: cs2:recovery:initiate
This scope is included by default in the cs2.odds.basic bundle, so existing odds-feed customers don’t need a new key.

Parameters

ParameterRequiredDescription
afteryesUnix timestamp in milliseconds. The replay includes settlements and voids whose latest transition happened after this moment; active markets are republished regardless of after. Must be within the stateful-recovery window (3 days by default) and not in the future.
request_idyesClient-chosen identifier (≤ 64 chars). Echoed back on the final <snapshot_complete> so your code can correlate the replay with the request that triggered it.
node_idnoOptional multi-node tag (≤ 64 chars). When supplied, it appears in the last section of every recovery routing key. Use it to bind a per-node queue if multiple of your processes consume the same vhost — only the node that asked for the replay sees it.

Errors

StatusReason
409Another recovery for this tenant is already in flight. Wait for <snapshot_complete> from the previous request before retrying, or skip — one recovery is enough.
409The API key has cs2:recovery:initiate but the tenant has no provisioned AMQP vhost yet. Contact support.
422after is in the future, or older than the configured stateful-recovery window (3 days). Pick a more recent timestamp.

Example

# Replay everything since five minutes ago for client node "edge-3"
curl -X POST -H "X-API-Key: $TT_KEY" \
  "https://ticktock.bet/cs2/v1/recovery/initiate_request?after=$(($(date +%s%3N) - 300000))&request_id=recovery-2026-05-12-001&node_id=edge-3"
{
  "data": {
    "request_id": "recovery-2026-05-12-001",
    "after": 1778586502057,
    "node_id": "edge-3",
    "scheduled_at": 1778586802057
  }
}

Client recipe

1

Detect the loss

Your AMQP consumer disconnects, falls behind, or you see an <alive subscribed="0"> message. Stop processing live messages until recovery completes — either pause your consumer or buffer the incoming envelopes and apply them after <snapshot_complete>.
2

Initiate the replay

POST /cs2/v1/recovery/initiate_request with after = <unix_ms of last processed message>. The server returns 202 Accepted immediately; the replay is scheduled in the background.
3

Apply recovery envelopes

Resume reading from your AMQP queue. Recovery envelopes (header recovery=1, priority lo) overwrite your local state for the keys they touch. Active markets get their current odds; settled / voided markets get their final result.
4

Switch back to live

When you receive <snapshot_complete request_id="..."/> whose request_id matches the one you sent, your state is in sync. Apply any buffered live messages, then resume normal processing.
If you get a 409 "Another recovery is already running" error, don’t retry — just wait for the in-flight <snapshot_complete> to arrive. A single recovery delivers everything you need to be in sync.

Routing keys produced

lo.-.live.odds_change.3.od:match.{match_num}.{node_id}
lo.-.live.bet_settlement.3.od:match.{match_num}.{node_id}
lo.-.live.bet_cancel.3.od:match.{match_num}.{node_id}
-.-.-.snapshot_complete.-.-.-.{node_id}
When node_id is omitted, the last section is -.

See also

Authorizations

X-API-Key
string
header
required

Tenant API key issued during onboarding

Query Parameters

after
integer
required

Unix timestamp in milliseconds. The replay includes settlements / voids that happened strictly after this moment. Must be within the stateful-recovery window.

request_id
string
required

Client-chosen identifier echoed back on the final <snapshot_complete> message so the client can correlate this replay with its bookkeeping.

Maximum string length: 64
node_id
string | null

Optional client-node identifier. When supplied, it appears in the last section of the AMQP routing key so multi-node clients can bind a per-node queue and receive the replay only for that node.

Maximum string length: 64

Response

Successful Response

The response is of type Response Initiate Recovery Cs2 V1 Recovery Initiate Request Post · object.

Last modified on May 12, 2026