Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.ratiofx.com/llms.txt

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

Ratio sends HTTP POST callbacks to your registered webhook URL when events occur. Use webhooks for real-time event-driven integration without polling.

Configuration

SettingDetails
URLYour HTTPS endpoint, configured during onboarding
SecretHMAC-SHA256 key used for signature verification
Timeout5 seconds — return HTTP 200 to acknowledge receipt

Event types

EventTrigger
settlement.confirmedSwap settled on-chain successfully
settlement.failedSwap execution failed (on-chain revert)
quote.expiredFirm quote expired without execution
system.state_changeA corridor’s system state changed

Payloads

settlement.confirmed

Sent when a swap is confirmed on-chain.
{
  "event": "settlement.confirmed",
  "timestamp": "2026-02-27T10:00:32Z",
  "data": {
    "execution_id": "EX-9910-USD-IDR",
    "quote_id": "QT-8821-USD-IDR",
    "pair": "USD-IDR",
    "status": "SETTLED",
    "filled_rate": 16020.00,
    "source_amount": 50000,
    "destination_amount": 801000000,
    "tx_hash": "0xKAIA...ABC",
    "settled_at": "2026-02-27T10:00:32Z"
  }
}

settlement.failed

Sent when a swap execution fails due to an on-chain revert.
{
  "event": "settlement.failed",
  "timestamp": "2026-02-27T10:00:33Z",
  "data": {
    "execution_id": "EX-9911-USD-IDR",
    "quote_id": "QT-8822-USD-IDR",
    "pair": "USD-IDR",
    "status": "FAILED",
    "reason": "ON_CHAIN_REVERT",
    "tx_hash": "0xKAIA...DEF"
  }
}

quote.expired

Sent when a firm quote reaches its expiry_timestamp without being executed.
{
  "event": "quote.expired",
  "timestamp": "2026-02-27T10:01:00Z",
  "data": {
    "quote_id": "QT-8823-USD-SGD",
    "pair": "USD-SGD",
    "expired_at": "2026-02-27T10:00:45Z"
  }
}

system.state_change

Sent when a corridor transitions between system states.
{
  "event": "system.state_change",
  "timestamp": "2026-02-27T10:05:00Z",
  "data": {
    "corridor": "MYR-IDR",
    "previous_state": "NORMAL",
    "new_state": "PROTECT",
    "reason": "VOLATILITY_ELEVATED"
  }
}

Signature verification

Every webhook request includes a signature header you must verify before processing the payload:
X-Ratio-Signature: sha256=<hex_digest>
Compute the HMAC-SHA256 of the raw request body using your webhook secret, then compare the result against the header value. Reject any request where the signature does not match.
import hmac, hashlib

def verify(body: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(f"sha256={expected}", signature)

Retry policy

If your endpoint does not return HTTP 200 within 5 seconds, Ratio retries with exponential backoff:
AttemptDelay
1st retry10 seconds
2nd retry30 seconds
3rd retry2 minutes
4th retry10 minutes
5th retry1 hour
After 5 failed attempts the webhook is marked as failed. Query the execution status directly via the API as a fallback.

Best practices

Always verify the X-Ratio-Signature header before processing any payload. Discard requests that fail verification.
  • Make your handler idempotent. The same event may be delivered more than once. Use execution_id or quote_id to deduplicate.
  • Return 200 immediately, then process asynchronously. Your handler must respond within 5 seconds. Offload any slow processing to a queue or background task.
  • Log the full payload. Retain raw payloads for debugging and reconciliation.