Skip to content
Last updated

Kaito provides API-based connectivity as a payment rail to move value across regions and rails:

  • FIAT <-> FIAT
  • FIAT <-> CRYPTO
  • CRYPTO <-> FIAT
  • CRYPTO <-> CRYPTO

You integrate once with the Kaito API, and Kaito handles routing, provider selection, fallbacks, and settlement orchestration (where applicable).

Supported stablecoins

Kaito currently operates with the following stablecoins:

  • USDC (USD Coin)
  • USDT (Tether)

Kaito currently prefers to operate with these stablecoins for FIAT_CRYPTO and CRYPTO_FIAT flows.

Key concepts

  • railType: declares the flow type (FIAT_FIAT, FIAT_CRYPTO, CRYPTO_FIAT, CRYPTO_CRYPTO).
  • Quote: locks pricing and routing for a short time window.
  • Execution plan: optional multi-step plan derived from a quote.
  • Payment / Payout:
    • Payment: typically used for CRYPTO_CRYPTO or FIAT_CRYPTO flows.
    • Payout (off-ramp): used for CRYPTO_FIAT or FIAT_FIAT flows.
  • Webhooks: receive asynchronous updates for state changes.
  • Idempotency-Key: UUID v4 header to safely retry any POST request without risk of duplicate operations. Send on every POST. Window: 24 hours. Returns the original response on duplicate key + same payload; returns 409 Conflict on duplicate key + different payload.
  • x-kaito-trace-id: required for support and troubleshooting.

Security model

All requests to the Kaito API must be made over HTTPS. Plain HTTP is rejected.

Request authentication (Rail M2M)

The Rail M2M API is machine-to-machine. There is no Bearer/JWT. Each request carries an api-key identifier plus a per-request HMAC signature.

Every Rail M2M request must include all of the following headers:

HeaderDescription
x-kaito-api-keyPublic Rail API key identifier (rk_test_… / rk_live_…). Identifies the calling client.
x-kaito-timestampUnix timestamp (seconds or milliseconds). Must be within ±300s of server time.
x-kaito-trace-idCaller-generated correlation id. Echoed in the response header.
x-kaito-signatureHex HMAC-SHA256 of the canonical request, signed with the per-key secret.
x-kaito-contentHex SHA-256 of the raw request body. Required for POST/PATCH; optional for GET/DELETE.

The secret never leaves the partner's side. The api-key is the public identifier the server uses to look up the secret (KMS-encrypted in our DynamoDB) and recompute the signature.

Canonical signature

<x-kaito-timestamp>.<HTTP_METHOD>.<rawPath>.<rawQueryString>.<x-kaito-trace-id>.<contentSha256>
  • rawPath is the API Gateway path after the /v1 mapping key is stripped — e.g. signing POST /v1/quotes uses rawPath = "/quotes".
  • contentSha256 for an empty body is the SHA-256 of the empty string (e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855).

The signature is hex HMAC-SHA256 of the canonical string with the per-key secret. See Kaito as a Payment Rail for the full reference and a runnable Node.js example.

Webhook signatures (outbound)

When Kaito sends events to your endpoint, each request includes:

HeaderDescription
Kaito-TimestampUnix epoch seconds of delivery time.
Kaito-Signaturesha256=<hex> — HMAC-SHA256 of "{timestamp}.{raw_body}" signed with your webhook secret.

Verify the signature on your side to ensure the event originated from Kaito.