API endpoints

API endpoints

Every HTTP route your platform needs to integrate Crebit Lock, with full request & response schemas, allowed-value dropdowns, and clickable sample payloads. Sandbox base URL: https://lock-apis-test.crebitpay.com.

The flow, every HTTP call
YouQuote

Price a rate lock for your customer over a time window.

You POST the trade (notional_currency, quote_currency, direction, notional_amount), a market_rate benchmark, the lock window, settlement rail, and a strike_mode (cip_fair / live_spot / custom). Crebit returns the priced quote with the locked_rate and strike_advantage_bps vs market.
POST /fx/quotes
YouLock

Turn the accepted quote into a binding contract.

You POST the quote_id the customer accepted. Crebit creates an immutable contract carrying the lock window, chain, settlement currency, and locked rate. The response includes the funding_wallet_address - send your deposit/premium there to activate the lock.
POST /fx/contracts
CustomerTransact

Customer transacts on your platform at the live spot rate.

No HTTP call on Crebit's side. You execute the trade at your live rate; the contract stays in active waiting for the next webhook.
YouTrigger payout

Webhook tells Crebit the live rate and the customer's payout wallet.

You POST event_type=contract_exercised with live_execution_rate and payout_wallet_address. Crebit uses these to compute the FX delta owed.
POST /fx/webhooks/inbound
CrebitPay out

Crebit sends the FX delta on-chain, then posts payout_settled.

Crebit computes FX delta = notional × (live_execution_rate − locked_rate) (sign depends on direction), converts to settlement_currency, and transfers it on chain to the customer's wallet. You receive an outbound payout_settled webhook with the on-chain transaction_hash.
Webhook → your URL

All routes

MethodPathPurpose
GET/api/v1/partners/meVerify API credentials
POST/api/v1/fx/quotesRequest a rate-lock quote
GET/api/v1/fx/quotesList quotes (paginated)
GET/api/v1/fx/quotes/{quote_id}Fetch one quote
POST/api/v1/fx/contractsLock the quote (create contract)
GET/api/v1/fx/customers/{customer_reference_id}/locksList FX locks for a customer
POST/api/v1/fx/webhooks/inboundNotify Crebit (funds, exercise)
GET/api/v1/fx/webhook-eventsAudit inbound events
GET/api/v1/fx/payout-eventsAudit outbound payout deliveries

Supported values

Enum fields below render as real dropdowns on each schema, never have to guess what to send.

FieldAllowed valuesNotes
chainethereum, polygon, solanaSettlement blockchain. Picked at quote time; immutable on the contract.
settlement_currencyUSDC, USDT, EURCStablecoin used for BOTH the upfront fee (you pay in) AND the FX delta payout (we pay out). One field, both legs.
contract_typeforward, optionforward = obligation; option = right but not obligation.
directionUSD_TO_BRL, BRL_TO_USD, USD_TO_MXN, MXN_TO_USD, USD_TO_EUR, EUR_TO_USDFX corridor as BASE_TO_QUOTE. USD against BRL, MXN, EUR, both directions.

Account · GET /api/v1/partners/me

Confirm your API key, environment, and partner id after onboarding. No request body.

Response body, 200 OK
  • partner_iduuidRequired

    Stable Crebit partner identifier. Echo on support tickets.

    Example11111111-…
  • partner_namestringRequired

    Display name configured at onboarding.

    ExampleAcme FX (sandbox)
  • api_key_iduuidRequired

    Public id of the API key used for this call.

    Example55555555-…
  • environmentstring (enum)Required

    Must match the X-Crebit-Environment header you sent.

    2 options
json, example response code sample
json, example response
{
  "partner_id": "11111111-1111-4111-8111-111111111111",
  "partner_name": "Acme FX (sandbox)",
  "api_key_id": "55555555-5555-4555-8555-555555555555",
  "environment": "sandbox"
}
HTTP code sample
curl -sS -X GET "https://lock-apis-test.crebitpay.com/api/v1/partners/me" \
  -H "Content-Type: application/json" \
  -H "X-Crebit-Key-Id: YOUR_KEY_ID" \
  -H "X-Crebit-Key-Secret: YOUR_KEY_SECRET" \
  -H "X-Crebit-Environment: sandbox"

Quotes · POST /api/v1/fx/quotes

Price a rate lock for a customer. The lock window is a calendar range - the customer may execute on ANY day from window_start through window_end (inclusive). Send Idempotency-Key (8–256 chars) on every POST.

Request body, every field

POST /api/v1/fx/quotes, request
  • customer_reference_idstring (1–256)Required

    Your stable id for the customer. Crebit treats it as opaque and echoes it back.

    Examplepartner-cust-ref-2026-0042
  • customer_namestring (1–256)Required

    Human-readable customer / business name. Used in audit logs and contract documents.

    ExampleAcme Imports Pvt Ltd
  • contract_typestring (enum)Required

    forward = obligation (refundable deposit). option = right but not obligation (upfront premium).

    2 options
  • directionstring (enum)Required

    FX corridor as BASE_TO_QUOTE. All six USD pairs against BRL, MXN, EUR are supported both ways.

    6 options
  • notional_currencystring (enum)Required

    Which side of the FX pair the notional_amount is denominated in. EITHER currency in the direction is valid, partner picks whichever the customer is fixing (the amount they're sending or the amount they want to receive). For direction=USD_TO_BRL, this can be USD or BRL.

    4 options
  • notional_amountdecimal stringRequired

    Trade size, denominated in notional_currency. Decimal string to preserve precision.

    Example50000.00
  • provider_ratedecimal stringRequired

    Your live FX rate at quote time. Crebit uses it as the pricing baseline.

    Example5.42
  • market_ratedecimal stringRequired

    REQUIRED. The benchmark mid-market FX rate you observed at quote time, either the direct interbank FX rate from your data feed, or the equivalent stablecoin pair from CoinGecko. Crebit uses this to track how your provider_rate correlates with an independent reference and audit pricing quality. Must be sent together with market_rate_timestamp.

    Example5.4180
  • market_rate_timestampdatetime (ISO-8601 UTC)Required

    REQUIRED. UTC time when market_rate was observed. Must be within ~5 min of the request.

    Example2026-05-24T16:00:00Z
  • provider_extra_spreaddecimal stringOptional

    OPTIONAL, your own spread (in rate units) stacked on top of the Crebit price. Pass it here and we'll echo it as provider_extra_spread on the quote response. Defaults to 0.

    Example0.0030
  • strike_modestring (enum)Optional

    How Crebit picks the strike. cip_fair (DEFAULT if omitted) = Crebit derives the CIP-fair forward rate from market_rate + the currency-pair interest rate differential. live_spot = strike is set to market_rate exactly (today's spot, no forward adjustment). custom = use target_strike (required when strike_mode=custom).

    3 options
  • target_strikedecimal stringOptional

    Required ONLY when strike_mode=custom. The exact strike you want the lock to execute at, e.g. an option struck ATM/OTM/ITM, or a forward matching an externally-quoted rate. Ignored if strike_mode is anything else.

    Example5.50
  • window_startdatetime (ISO-8601 UTC)Required

    First moment the customer may execute the locked rate. Now or any time up to 180 days ahead. Must be strictly before window_end.

    Example2026-08-04T00:00:00Z
  • window_enddatetime (ISO-8601 UTC)Required

    Last moment the customer may execute. Three constraints: (1) STRICTLY AFTER window_start (equal values return validation_error). (2) At least 1 hour AFTER the current time, i.e. the lock window has to last at least 1 hour. Crebit needs that hour of hedging runway before the customer could possibly transact. (3) Within 180 days of now.

    Example2026-08-11T00:00:00Z
  • chainstring (enum)Required

    Blockchain Crebit settles on, same chain you fund on and same chain Crebit pays out on. Set at quote time; immutable for the life of the contract.

    3 options
  • settlement_currencystring (enum)Required

    Stablecoin Crebit and the partner settle in. Partner sends the upfront fee in this stablecoin to funding_wallet_address; Crebit pays out any FX delta in this stablecoin. The end customer never sees stablecoins, partner bills them in local currency and converts. Set at quote time; immutable on the contract.

    3 options

Sample requests

Pick a variant

Most common shape. Omit strike_mode (or set cip_fair) and Crebit derives the forward strike from market_rate + the USD/BRL interest-rate differential. For USD→BRL, this lifts the strike above spot, customer gets MORE BRL per USD.

json code sample
json
{
  "customer_reference_id": "partner-cust-ref-2026-0042",
  "customer_name": "Acme Imports Pvt Ltd",
  "contract_type": "forward",
  "direction": "USD_TO_BRL",
  "notional_currency": "USD",
  "notional_amount": "50000.00",
  "provider_rate": "5.42",
  "provider_extra_spread": "0.0030",
  "market_rate": "5.4180",
  "market_rate_timestamp": "2026-05-24T16:00:00Z",
  "strike_mode": "cip_fair",
  "window_start": "2026-08-04T00:00:00Z",
  "window_end": "2026-08-11T00:00:00Z",
  "chain": "ethereum",
  "settlement_currency": "USDC"
}

How to call

HTTP code sample
curl -sS -X POST "https://lock-apis-test.crebitpay.com/api/v1/fx/quotes" \
  -H "Content-Type: application/json" \
  -H "X-Crebit-Key-Id: YOUR_KEY_ID" \
  -H "X-Crebit-Key-Secret: YOUR_KEY_SECRET" \
  -H "X-Crebit-Environment: sandbox" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"customer_reference_id":"partner-cust-ref-2026-0042","customer_name":"Acme Imports Pvt Ltd","contract_type":"forward","direction":"USD_TO_BRL","notional_currency":"USD","notional_amount":"50000.00","provider_rate":"5.42","provider_extra_spread":"0.0030","market_rate":"5.4180","market_rate_timestamp":"2026-05-24T16:00:00Z","strike_mode":"cip_fair","window_start":"2026-08-04T00:00:00Z","window_end":"2026-08-11T00:00:00Z","chain":"ethereum","settlement_currency":"USDC"}'

Response body, 201 Created

POST /api/v1/fx/quotes, response
  • iduuidRequired

    Quote id. Pass to POST /api/v1/fx/contracts.

    Example22222222-…
  • statusstring (enum)Required

    Quote outcome: created when pricing succeeded, failed otherwise.

    2 options
  • locked_ratedecimal stringRequired

    The strike, the FX rate Crebit will honor if the customer exercises. For forwards, this is the CIP-fair forward rate (or your target_strike if you supplied one). For options, this is the option strike price.

    Example5.42
  • strike_modestring (enum)Optional

    Echoes how the strike was chosen. cip_fair = Crebit derived it from covered-interest-parity. live_spot = strike was set to market_rate. custom = you supplied target_strike.

    3 options
  • target_strikedecimal string | nullOptional

    Echos the strike from the request, if strike_mode=custom and target_strike was provided.

    Examplenull
  • strike_advantage_bpsintegerRequired

    Basis points by which the strike differs from market_rate, from the CUSTOMER'S perspective. Positive = strike beats market (customer wins). Negative = customer pays a premium over market for the certainty. Use this to message your customer: '+220 bps better than mid-market'.

    Example12
  • provider_extra_spreaddecimal string | nullOptional

    Your spread from the request (zero if you didn't send provider_extra_spread).

    Example0.0005
  • premium_amountdecimal stringRequired

    All-in premium (option) or quoted fee (forward) the partner pays upfront. Denominated in settlement_currency.

    Example1565.00
  • deposit_amountdecimal string | nullOptional

    Security deposit (forwards only; null for options). Typically 5-10% of notional, denominated in settlement_currency. Collateral against the customer's obligation to transact, released back to the partner on successful exercise, FORFEITED if the customer fails to transact within the window.

    Example5000.00
  • total_amountdecimal stringRequired

    The total amount that would be due to Crebit to activate the lock. Adds premium_amount and deposit_amount.

    Example6565.00
  • window_startdatetime (ISO-8601 UTC)Required

    Echoes the lock-window start you sent.

    Example2026-08-04T00:00:00Z
  • window_enddatetime (ISO-8601 UTC)Required

    Echoes the lock-window end you sent.

    Example2026-08-11T00:00:00Z
  • chainstring (enum)Required

    Blockchain Crebit settles on, same chain you fund on and same chain Crebit pays out on. Set at quote time; immutable for the life of the contract.

    3 options
  • settlement_currencystring (enum)Required

    Stablecoin Crebit and the partner settle in. Partner sends the upfront fee in this stablecoin to funding_wallet_address; Crebit pays out any FX delta in this stablecoin. The end customer never sees stablecoins, partner bills them in local currency and converts. Set at quote time; immutable on the contract.

    3 options
  • expires_atdatetime (ISO-8601 UTC)Required

    Quote validity cutoff. POST the id to /contracts before this time. Default TTL is ~90 seconds, quotes are short-lived because FX moves; show the customer the quote with a countdown if you don't lock immediately.

    Example2026-05-24T16:16:30Z
  • created_atdatetime (ISO-8601 UTC)Required

    UTC timestamp the quote was issued.

    Example2026-05-24T16:15:00Z
json, example response code sample
json, example response
{
  "id": "22222222-2222-4222-8222-222222222222",
  "status": "created",
  "locked_rate": "5.42",
  "strike_mode": "cip_fair",
  "target_strike": null,
  "strike_advantage_bps": 12,
  "provider_extra_spread": "0.0005",
  "premium_amount": "1565.00",
  "deposit_amount": "5000.00",
  "total_amount": "6565.00",
  "window_start": "2026-08-04T00:00:00Z",
  "window_end": "2026-08-11T00:00:00Z",
  "chain": "ethereum",
  "settlement_currency": "USDC",
  "expires_at": "2026-05-24T16:16:30Z",
  "created_at": "2026-05-24T16:15:00Z"
}

List / get

GET /api/v1/fx/quotes, cursor pagination, optional filters status, limit, cursor.

HTTP code sample
curl -sS -X GET "https://lock-apis-test.crebitpay.com/api/v1/fx/quotes?status=created&limit=25" \
  -H "Content-Type: application/json" \
  -H "X-Crebit-Key-Id: YOUR_KEY_ID" \
  -H "X-Crebit-Key-Secret: YOUR_KEY_SECRET" \
  -H "X-Crebit-Environment: sandbox"
json, list response code sample
json, list response
{
  "items": [
    {
      "id": "22222222-2222-4222-8222-222222222222",
      "status": "created",
      "locked_rate": "5.42",
      "strike_mode": "cip_fair",
      "target_strike": null,
      "strike_advantage_bps": 12,
      "provider_extra_spread": "0.0005",
      "premium_amount": "1565.00",
      "deposit_amount": "5000.00",
      "total_amount": "6565.00",
      "window_start": "2026-08-04T00:00:00Z",
      "window_end": "2026-08-11T00:00:00Z",
      "chain": "ethereum",
      "settlement_currency": "USDC",
      "expires_at": "2026-05-24T16:16:30Z",
      "created_at": "2026-05-24T16:15:00Z"
    }
  ],
  "next_cursor": null
}

GET /api/v1/fx/quotes/{quote_id}, fetch a single quote by id.

Contracts · POST /api/v1/fx/contracts

Converts an accepted quote into a binding rate lock. The contract inherits the quote's lock window, chain, and payout currency - those terms are immutable once the contract exists.

Request body

POST /api/v1/fx/contracts, request
  • quote_iduuidRequired

    id returned by POST /api/v1/fx/quotes.

    Example22222222-…
  • partner_transaction_referencestringOptional

    Your platform's transaction id. Echoed in webhooks for reconciliation.

    Exampleplatform-tx-9901
Sample requests

Quote id from POST /api/v1/fx/quotes is the only required field.

json code sample
json
{
  "quote_id": "22222222-2222-4222-8222-222222222222"
}
HTTP code sample
curl -sS -X POST "https://lock-apis-test.crebitpay.com/api/v1/fx/contracts" \
  -H "Content-Type: application/json" \
  -H "X-Crebit-Key-Id: YOUR_KEY_ID" \
  -H "X-Crebit-Key-Secret: YOUR_KEY_SECRET" \
  -H "X-Crebit-Environment: sandbox" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"quote_id":"22222222-2222-4222-8222-222222222222","partner_transaction_reference":"platform-tx-9901"}'

Response body, 201 Created

POST /api/v1/fx/contracts, response
  • iduuidRequired

    Crebit contract id. Use this in API calls, pass as fx_contract_id on inbound webhooks. NOT for showing humans (use crebit_contract_reference instead).

    Example33333333-…
  • crebit_contract_referencestringRequired

    Human-readable contract reference, suitable for receipts, customer-facing emails, and support tickets. Don't use it as an API identifier, id is the canonical key.

    Examplecrebit_lock_7f3a9c2b1d
  • locked_ratedecimal stringRequired

    Rate Crebit will honor if exercised.

    Example5.42
  • provider_rate_at_lockdecimal stringRequired

    The FX rate you provided at quote time.

    Example5.42
  • market_rate_at_lockdecimal stringRequired

    The market FX rate you provided at quote time.

    Example5.4180
  • premium_amountdecimal stringRequired

    Premium / quoted fee due upfront, in settlement_currency.

    Example1565.00
  • deposit_amountdecimal string | nullOptional

    Refundable deposit held until execution (forwards only). In settlement_currency.

    Example5000.00
  • total_amountdecimal stringRequired

    The total amount due to Crebit to activate the lock. Adds premium_amount and deposit_amount.

    Example6565.00
  • window_startdatetime (ISO-8601 UTC) | nullOptional

    Inherited from the quote.

    Example2026-08-04T00:00:00Z
  • window_enddatetime (ISO-8601 UTC) | nullOptional

    Inherited from the quote.

    Example2026-08-11T00:00:00Z
  • chainstring (enum)Required

    Blockchain Crebit settles on, same chain you fund on and same chain Crebit pays out on. Set at quote time; immutable for the life of the contract.

    3 options
  • settlement_currencystring (enum)Required

    Stablecoin Crebit and the partner settle in. Partner sends the upfront fee in this stablecoin to funding_wallet_address; Crebit pays out any FX delta in this stablecoin. The end customer never sees stablecoins, partner bills them in local currency and converts. Set at quote time; immutable on the contract.

    3 options
  • funding_wallet_addressstringRequired

    Crebit-controlled wallet address on `chain`. Send the deposit / premium here in `settlement_currency`. Once Crebit observes the funds on-chain, Crebit fires an outbound `funds_received` webhook.

    Example0xCrebitFundingWalletForThisContract
  • created_atdatetime (ISO-8601 UTC)Required

    UTC timestamp the contract was created.

    Example2026-05-24T16:20:00Z
  • max_transaction_amountdecimal stringRequired

    The maximum amount of money (in notional_currency) able to be processed.

    Example50000.00
json, example response code sample
json, example response
{
  "id": "33333333-3333-4333-8333-333333333333",
  "crebit_contract_reference": "crebit_lock_7f3a9c2b1d",
  "locked_rate": "5.42",
  "provider_rate_at_lock": "5.42",
  "market_rate_at_lock": "5.4180",
  "premium_amount": "1565.00",
  "deposit_amount": "5000.00",
  "total_amount": "6565.00",
  "window_start": "2026-08-04T00:00:00Z",
  "window_end": "2026-08-11T00:00:00Z",
  "chain": "ethereum",
  "settlement_currency": "USDC",
  "funding_wallet_address": "0xCrebitFundingWalletForThisContract",
  "created_at": "2026-05-24T16:20:00Z",
  "max_transaction_amount": "50000.00"
}

Contract lifecycle

Lifecycle is driven by webhooks and outbound events, not returned on POST /api/v1/fx/contracts. Typical states:

statusSet byWhat it means
quote_createdCrebit (on create)Contract exists; awaiting funds at funding_wallet_address.
funds_in_routeOptional partner webhook (funds_in_route)You've dispatched premium / deposit on-chain to funding_wallet_address.
activeCrebit (after on-chain confirmation) → outbound funds_received firesLock is live, customer may transact at any moment in the window.
exercisedPartner webhook (contract_exercised)Customer transacted. Crebit is computing & dispatching the payout.
settledCrebit (after payout confirms) → outbound payout_settled firesPayout confirmed on-chain.
expiredCrebit (window_end passed)Customer did not transact within the window.
failedCrebitPre-active terminal failure.

List customer locks

GET /api/v1/fx/customers/{customer_reference_id}/locks returns paginated FX contracts (locks) for your opaque customer_reference_id, newest first. Use optional status to filter by lifecycle state.

Query & path parameters
  • customer_reference_idstringRequired

    Path parameter. Your opaque customer id from quote/contract creation.

    Examplepartner-cust-ref-2026-0042
  • statusstring (enum)Optional

    Optional filter. Return only locks in this lifecycle status.

    9 options
  • limitintegerOptional

    Page size (1–100). Default 25.

    Example25
  • cursorstringOptional

    Opaque pagination cursor from a previous response's next_cursor.

    ExampleeyJpZCI6IjMzMz…
HTTP code sample
curl -sS -X GET "https://lock-apis-test.crebitpay.com/api/v1/fx/customers/partner-cust-ref-2026-0042/locks?status=active&limit=25" \
  -H "Content-Type: application/json" \
  -H "X-Crebit-Key-Id: YOUR_KEY_ID" \
  -H "X-Crebit-Key-Secret: YOUR_KEY_SECRET" \
  -H "X-Crebit-Environment: sandbox"
Response body, 200 OK
  • itemsarray<object>Required

    FX locks (contracts) for this customer, newest first.

    Show 19 nested fields
    • iduuidRequired

      Crebit contract id. Pass as fx_contract_id on inbound webhooks.

      Example33333333-…
    • crebit_contract_referencestringRequired

      Human-readable contract reference for receipts and support.

      Examplecrebit_lock_7f3a9c2b1d
    • locked_ratedecimal stringRequired

      Rate Crebit will honor if exercised.

      Example5.42
    • provider_rate_at_lockdecimal stringRequired

      The FX rate you provided at quote time.

      Example5.42
    • market_rate_at_lockdecimal stringRequired

      The market FX rate you provided at quote time.

      Example5.4180
    • premium_amountdecimal stringRequired

      Premium / quoted fee due upfront, in settlement_currency.

      Example1565.00
    • deposit_amountdecimal string | nullOptional

      Refundable deposit held until execution (forwards only). In settlement_currency.

      Example5000.00
    • total_amountdecimal stringRequired

      Total amount due to Crebit to activate the lock.

      Example6565.00
    • window_startdatetime (ISO-8601 UTC) | nullOptional

      First moment the customer may execute the locked rate.

      Example2026-08-04T00:00:00Z
    • window_enddatetime (ISO-8601 UTC) | nullOptional

      Last moment the customer may execute the locked rate.

      Example2026-08-11T00:00:00Z
    • chainstring (enum)Required

      Blockchain Crebit settles on, same chain you fund on and same chain Crebit pays out on. Set at quote time; immutable for the life of the contract.

      3 options
    • settlement_currencystring (enum)Required

      Stablecoin Crebit and the partner settle in. Partner sends the upfront fee in this stablecoin to funding_wallet_address; Crebit pays out any FX delta in this stablecoin. The end customer never sees stablecoins, partner bills them in local currency and converts. Set at quote time; immutable on the contract.

      3 options
    • funding_wallet_addressstringRequired

      Send premium and deposit here in settlement_currency on chain.

      Example0xCrebitFundingWalletForThisContract
    • created_atdatetime (ISO-8601 UTC)Required

      UTC timestamp the contract was created.

      Example2026-05-24T16:20:00Z
    • max_transaction_amountdecimal stringRequired

      Maximum notional amount processable under this lock.

      Example50000.00
    • statusstring (enum)Required

      Current lifecycle status of the lock.

      9 options
    • quote_iduuidRequired

      Quote this lock was created from.

      Example22222222-…
    • customer_reference_idstringRequired

      Your opaque customer id (same value you sent at quote time).

      Examplepartner-cust-ref-2026-0042
    • partner_transaction_referencestring | nullOptional

      Your platform transaction id, echoed from the contract.

      Exampleplatform-tx-9901
  • next_cursorstring | nullOptional

    Pass as cursor on the next page. null when there are no more results.

    Examplenull
json, example response code sample
json, example response
{
  "items": [
    {
      "id": "33333333-3333-4333-8333-333333333333",
      "crebit_contract_reference": "crebit_lock_7f3a9c2b1d",
      "locked_rate": "5.42",
      "provider_rate_at_lock": "5.42",
      "market_rate_at_lock": "5.4180",
      "premium_amount": "1565.00",
      "deposit_amount": "5000.00",
      "total_amount": "6565.00",
      "window_start": "2026-08-04T00:00:00Z",
      "window_end": "2026-08-11T00:00:00Z",
      "chain": "ethereum",
      "settlement_currency": "USDC",
      "funding_wallet_address": "0xCrebitFundingWalletForThisContract",
      "created_at": "2026-05-24T16:20:00Z",
      "max_transaction_amount": "50000.00",
      "status": "active",
      "quote_id": "22222222-2222-4222-8222-222222222222",
      "customer_reference_id": "partner-cust-ref-2026-0042",
      "partner_transaction_reference": "platform-tx-9901"
    }
  ],
  "next_cursor": null
}

Webhooks (in + out)

Six event types in total. Same envelope shape on both sides: event_type at the top discriminates which schema applies.

Directionevent_typeWho calls whoTrigger
Inboundfunds_in_routePartner → CrebitOptional: partner pre-announces an on-chain deposit/premium dispatch.
Inboundcontract_exercisedPartner → CrebitCustomer transacted within the lock window, Crebit pays out the FX delta.
Outboundfunds_receivedCrebit → PartnerCrebit confirmed funding on-chain, contract is now active.
Outboundpayout_settledCrebit → PartnerOn-chain payout to customer confirmed.
Outboundpayout_failedCrebit → PartnerPayout could not complete (retries unless will_retry=false).
Outboundcontract_expiredCrebit → PartnerLock window passed without exercise. For forwards, includes deposit refund tx.

Inbound, partner → Crebit

Single endpoint, single envelope: POST /api/v1/fx/webhooks/inbound. The first field is always event_type, Crebit uses it to pick the right schema. Every POST requires Idempotency-Key (8–256 chars).

Inbound event variants

Notify Crebit you've dispatched the deposit on-chain to funding_wallet_address. Optional but recommended, Crebit can pre-stage processing.

json code sample
json
{
  "event_type": "funds_in_route",
  "fx_contract_id": "33333333-3333-4333-8333-333333333333",
  "payment_type": "deposit",
  "amount": "5000.00",
  "currency": "USDC",
  "chain": "ethereum",
  "transaction_hash": "0xabc123…",
  "source_wallet_address": "0xPartnerTreasury…"
}

funds_in_route, schema

Notify Crebit that premium or deposit is on the way (or already on-chain). Crebit advances the contract from quote_created funds_in_route, then to active once the on-chain transfer confirms (an outbound funds_received webhook fires at that point).

Only fire this once funds are actually in motion. We understand USD→stablecoin onramps can take time, fire funds_in_routethe moment you've initiated the on-chain transfer (or queued the onramp that will produce it), NOT just because the customer has clicked "accept". Pre-firing puts Crebit's lock state out of sync with the on-chain reality and will trigger reconciliation alerts on our side. Accurate reporting keeps the hedge tight.
event_type = funds_in_route
  • event_typestring (const)Required

    Discriminator. Must be the literal string funds_in_route.

    1 option
  • fx_contract_iduuidRequired

    Contract id returned by POST /api/v1/fx/contracts.

    Example33333333-…
  • payment_typestring (enum)Optional

    Which leg you're funding. Omit if you're notifying the full amount at once.

    2 options
  • amountdecimal stringOptional

    Amount dispatched on-chain to funding_wallet_address.

    Example5000.00
  • currencystring (enum)Optional

    Stablecoin you sent, must match the contract's settlement_currency.

    3 options
  • chainstring (enum)Optional

    Chain you sent on, must match the contract's chain.

    3 options
  • transaction_hashstringOptional

    On-chain tx hash. Crebit uses this to confirm receipt.

    Example0xabc123…
  • source_wallet_addressstringOptional

    Wallet the funds were sent from.

    Example0xPartnerTreasury…

contract_exercised, schema (triggers payout)

This is the call that triggers Crebit to pay out. Fire it the moment the customer transacts on your platform within the lock window. Crebit reads locked_rate from the contract, compares against live_execution_rate, converts the delta to settlement_currency, and transfers it to payout_wallet_address on chain. The chain + settlement_currency MUST match what was locked at quote time, otherwise Crebit returns 409 contract_mismatch and does not pay out.
event_type = contract_exercised
  • event_typestring (const)Required

    Discriminator. Must be the literal string contract_exercised. THIS IS THE CALL THAT TRIGGERS CREBIT TO PAY OUT.

    1 option
  • fx_contract_iduuidRequired

    Contract the customer just transacted against.

    Example33333333-…
  • executed_atdatetime (ISO-8601 UTC)Required

    UTC timestamp of the customer's underlying transaction. Must fall within the contract's [window_start, window_end] window.

    Example2026-08-07T13:42:00Z
  • live_execution_ratedecimal stringRequired

    Live mid-market FX rate the moment the customer transacted. Crebit compares against locked_rate to compute the FX delta.

    Example5.51
  • payout_wallet_addressstringRequired

    On-chain destination for the FX delta payout.

    Example0xEndUserWallet…
  • payout_currencystring (enum)Optional

    Stablecoin Crebit pays out in. Must match the contract's settlement_currency unless you explicitly override (e.g. BRLA corridor). Defaults to USDC when omitted.

    2 options
  • chainstring (enum)Required

    Blockchain Crebit pays out on. Must match the contract's chain from quote time.

    3 options

How to call (either variant)

HTTP code sample
curl -sS -X POST "https://lock-apis-test.crebitpay.com/api/v1/fx/webhooks/inbound" \
  -H "Content-Type: application/json" \
  -H "X-Crebit-Key-Id: YOUR_KEY_ID" \
  -H "X-Crebit-Key-Secret: YOUR_KEY_SECRET" \
  -H "X-Crebit-Environment: sandbox" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"event_type":"contract_exercised","fx_contract_id":"33333333-3333-4333-8333-333333333333","executed_at":"2026-08-07T13:42:00Z","live_execution_rate":"5.51","payout_wallet_address":"0xEndUserWallet…","payout_currency":"USDC","chain":"ethereum"}'

Inbound ACK response, 200 OK

Crebit's response to your inbound POST
  • webhook_event_iduuidRequired

    Crebit's id for the event. Echo in support tickets.

    Example44444444-…
  • statusstring (enum)Required

    processed = handled now. duplicate = same Idempotency-Key already seen. queued = accepted, async work pending.

    3 options
json, example response code sample
json, example response
{
  "webhook_event_id": "44444444-4444-4444-8444-444444444444",
  "status": "processed"
}

Outbound, Crebit → partner

Crebit POSTs JSON to the webhook_url you configured during onboarding (one URL per environment). The first field is again event_type, switch on it.

No outbound webhook URL configured yet? Send Crebit support the URL and environment. Until then, poll GET /api/v1/fx/payout-events to learn payout state on demand.
Outbound event variants

Crebit confirmed your funding deposit/premium on-chain. Contract is now active, customer may transact.

json code sample
json
{
  "event_id": "evt_4a7e9c2f8b1d6a3e",
  "event_type": "funds_received",
  "delivered_at": "2026-05-24T16:35:12Z",
  "fx_contract_id": "33333333-3333-4333-8333-333333333333",
  "crebit_contract_reference": "crebit_lock_7f3a9c2b1d",
  "funds": {
    "amount": "5000.00",
    "currency": "USDC",
    "chain": "ethereum",
    "funding_wallet_address": "0xCrebitFundingWalletForThisContract",
    "transaction_hash": "0xabc123…",
    "block_number": 21345600,
    "confirmed_at": "2026-05-24T16:35:08Z"
  },
  "contract_status": "active"
}

funds_received, schema

Delivered once Crebit observes the partner's funding deposit/premium confirmed on-chain at funding_wallet_address. Contract moves to active, your customer may now transact. Treat this as the authoritative "the lock is live" signal.

event_type = funds_received
  • event_idstringRequired

    Stable unique id, use as your idempotency key.

    Exampleevt_4a7e9c2f8b1d6a3e
  • event_typestring (const)Required

    Always the literal string funds_received.

    1 option
  • delivered_atdatetimeRequired

    UTC timestamp Crebit emitted this delivery attempt.

    Example2026-05-24T16:35:12Z
  • fx_contract_iduuidRequired

    Contract whose funding was confirmed.

    Example33333333-…
  • crebit_contract_referencestringRequired

    Human-readable contract reference.

    Examplecrebit_lock_7f3a9c2b1d
  • fundsobjectRequired

    On-chain confirmation of the funding deposit/premium.

    Show 7 nested fields
    • amountdecimal stringRequired

      Amount confirmed on-chain.

      Example5000.00
    • currencystring (enum)Required

      Stablecoin received. Matches the contract's settlement_currency.

      3 options
    • chainstring (enum)Required

      Blockchain where funds were received.

      3 options
    • funding_wallet_addressstringRequired

      Crebit wallet that received the deposit/premium.

      Example0xCrebitFundingWalletForThisContract
    • transaction_hashstringRequired

      On-chain transaction hash for the funding transfer.

      Example0xabc123…
    • block_numberintegerRequired

      Block number where the transfer was confirmed.

      Example21345600
    • confirmed_atdatetime (ISO-8601 UTC)Required

      UTC timestamp when Crebit confirmed the transfer on-chain.

      Example2026-05-24T16:35:08Z
  • contract_statusstring (enum)Required

    Always 'active' on this event, the lock is now live and the customer may transact.

    1 option

payout_settled, schema

event_type = payout_settled
  • event_idstringRequired

    Stable unique id for this delivery, use as your idempotency key.

    Exampleevt_5f8a1c7b9d2e4a3f
  • event_typestring (const)Required

    Always the literal string payout_settled.

    1 option
  • delivered_atdatetimeRequired

    UTC timestamp Crebit emitted this delivery attempt.

    Example2026-08-07T13:43:12Z
  • fx_contract_iduuidRequired

    Contract this payout settled for.

    Example33333333-…
  • crebit_contract_referencestringRequired

    Human-readable contract reference.

    Examplecrebit_lock_7f3a9c2b1d
  • partner_transaction_referencestring | nullOptional

    Echoed from the contract, your reconciliation id.

    Exampleplatform-tx-9901
  • payoutobjectRequired

    On-chain payout settlement details.

    Show 8 nested fields
    • statusstring (const)Required

      Always the literal string settled.

      1 option
    • amountdecimal stringRequired

      FX delta amount paid out, in currency.

      Example4500.00
    • currencystring (enum)Required

      Stablecoin Crebit paid out.

      3 options
    • chainstring (enum)Required

      Blockchain where the payout was sent.

      3 options
    • destination_wallet_addressstringRequired

      Wallet that received the payout (from contract_exercised).

      Example0xEndUserWallet…
    • transaction_hashstringRequired

      On-chain transaction hash for the payout transfer.

      Example0xf3a1...e29c
    • block_numberintegerRequired

      Block number where the payout was confirmed.

      Example21345678
    • settled_atdatetime (ISO-8601 UTC)Required

      UTC timestamp when the payout was confirmed on-chain.

      Example2026-08-07T13:43:08Z
  • contractobjectOptional

    Pricing snapshot at the moment of exercise.

    Show 4 nested fields
    • locked_ratedecimal stringRequired

      Rate locked on the contract at creation.

      Example5.42
    • live_execution_ratedecimal stringRequired

      Live rate from your contract_exercised webhook.

      Example5.51
    • notional_amountdecimal stringRequired

      Notional amount the customer transacted against.

      Example50000.00
    • fx_delta_in_quote_currencydecimal stringRequired

      FX delta Crebit paid out, in quote currency terms.

      Example4500.00

payout_failed, schema

event_type = payout_failed
  • event_idstringRequired

    Use as your idempotency key.

    Exampleevt_6e9c2d8a4f1b3c7e
  • event_typestring (const)Required

    Always the literal string payout_failed.

    1 option
  • delivered_atdatetimeRequired

    UTC timestamp Crebit emitted this delivery attempt.

    Example2026-08-07T13:44:05Z
  • fx_contract_iduuidRequired

    Contract whose payout failed.

    Example33333333-…
  • payoutobjectRequired

    Failure detail for the payout attempt.

    Show 9 nested fields
    • statusstring (const)Required

      Always the literal string failed.

      1 option
    • failure_codestringRequired

      Machine-readable failure reason for your ops dashboards.

      Exampledestination_wallet_unreachable
    • failure_messagestringRequired

      Human-readable detail about why the payout failed.

      ExampleDestination wallet rejected the transfer.
    • will_retrybooleanRequired

      Whether Crebit will retry this payout automatically.

      Exampletrue
    • next_retry_atdatetime (ISO-8601 UTC) | nullOptional

      When Crebit will retry. null when will_retry is false.

      Example2026-08-07T14:00:00Z
    • destination_wallet_addressstringRequired

      Wallet Crebit attempted to pay out to.

      Example0xEndUserWallet…
    • amountdecimal stringRequired

      FX delta amount Crebit attempted to pay out.

      Example4500.00
    • currencystring (enum)Required

      Stablecoin Crebit attempted to pay out.

      3 options
    • chainstring (enum)Required

      Blockchain Crebit attempted the payout on.

      3 options

contract_expired, schema

Lock window passed and the customer never exercised.

  • For forwards, the customer was obligated to transact and didn't, so the security deposit is forfeitedto cover Crebit's hedge cost. Payload carries deposit_outcome.status="forfeited" with the amount, currency, chain, and forfeit timestamp.
  • For options, the premium was non-refundable anyway, so deposit_outcome is null and this delivery is purely a terminal status notification.
event_type = contract_expired
  • event_idstringRequired

    Use as your idempotency key.

    Exampleevt_7c1d3e8b4a9f2d6c
  • event_typestring (const)Required

    Always the literal string contract_expired.

    1 option
  • delivered_atdatetimeRequired

    UTC timestamp Crebit emitted this delivery attempt.

    Example2026-08-11T00:01:30Z
  • fx_contract_iduuidRequired

    Contract that expired.

    Example33333333-…
  • crebit_contract_referencestringRequired

    Human-readable contract reference.

    Examplecrebit_lock_7f3a9c2b1d
  • partner_transaction_referencestring | nullOptional

    Echoed from the contract.

    Exampleplatform-tx-9901
  • contractobjectRequired

    Snapshot of the expired contract.

    Show 2 nested fields
    • contract_typestring (enum)Required

      forward or option.

      2 options
    • expired_atdatetime (ISO-8601 UTC)Required

      UTC timestamp when the lock window ended.

      Example2026-08-11T00:00:00Z
  • deposit_outcomeobject | nullOptional

    Forwards only (null for options). Reports what happened to the security deposit.

    Show 5 nested fields
    • statusstring (const)Required

      Always forfeited on contract_expired for forwards.

      1 option
    • amountdecimal stringRequired

      Deposit amount forfeited.

      Example5000.00
    • currencystring (enum)Required

      Stablecoin of the forfeited deposit.

      3 options
    • chainstring (enum)Required

      Blockchain where the deposit was held.

      3 options
    • forfeited_atdatetime (ISO-8601 UTC)Required

      UTC timestamp when Crebit marked the deposit forfeited.

      Example2026-08-11T00:01:25Z

Signature, retries, ordering

  • Signature. Outbound deliveries include an X-Crebit-Signature header: hex-encoded HMAC-SHA256 of the raw body, keyed with your webhook secret. Verify before trusting the payload.
  • Idempotency. Use event_id as your idempotency key, Crebit may retry an identical delivery.
  • Retries. Reply 2xx within 10s. Crebit retries non-2xx with exponential backoff (~30s, 2m, 10m, 1h, 4h, 12h) for up to 24h.
  • Ordering. Not guaranteed across contracts. Within a single contract, Crebit serialises deliveries.

Audit endpoints

GET /api/v1/fx/webhook-events, every inbound POST you sent, with status, retry count, and the raw payload Crebit received.

HTTP code sample
curl -sS -X GET "https://lock-apis-test.crebitpay.com/api/v1/fx/webhook-events?limit=25" \
  -H "Content-Type: application/json" \
  -H "X-Crebit-Key-Id: YOUR_KEY_ID" \
  -H "X-Crebit-Key-Secret: YOUR_KEY_SECRET" \
  -H "X-Crebit-Environment: sandbox"
json, example response code sample
json, example response
{
  "items": [
    {
      "id": "44444444-4444-4444-8444-444444444444",
      "partner_id": "11111111-1111-4111-8111-111111111111",
      "fx_contract_id": "33333333-3333-4333-8333-333333333333",
      "direction": "incoming",
      "event_type": "funds_in_route",
      "idempotency_key": "idem-funds-2026-05-24-001",
      "status": "processed",
      "retry_count": 0,
      "last_error": null,
      "payload": {
        "event_type": "funds_in_route",
        "fx_contract_id": "33333333-3333-4333-8333-333333333333",
        "payment_type": "deposit",
        "amount": "5000.00",
        "currency": "USDC",
        "chain": "ethereum",
        "transaction_hash": "0xabc123…",
        "source_wallet_address": "0xPartnerTreasury…"
      },
      "created_at": "2026-05-24T17:00:00Z",
      "processed_at": "2026-05-24T17:00:01Z"
    },
    {
      "id": "55555555-5555-4555-8555-555555555556",
      "partner_id": "11111111-1111-4111-8111-111111111111",
      "fx_contract_id": "33333333-3333-4333-8333-333333333333",
      "direction": "outgoing",
      "event_type": "funds_received",
      "idempotency_key": "evt_4a7e9c2f8b1d6a3e",
      "status": "delivered",
      "retry_count": 0,
      "last_error": null,
      "payload": {
        "event_id": "evt_4a7e9c2f8b1d6a3e",
        "event_type": "funds_received",
        "delivered_at": "2026-05-24T16:35:12Z",
        "fx_contract_id": "33333333-3333-4333-8333-333333333333",
        "crebit_contract_reference": "crebit_lock_7f3a9c2b1d",
        "funds": {
          "amount": "5000.00",
          "currency": "USDC",
          "chain": "ethereum",
          "funding_wallet_address": "0xCrebitFundingWalletForThisContract",
          "transaction_hash": "0xabc123…",
          "block_number": 21345600,
          "confirmed_at": "2026-05-24T16:35:08Z"
        },
        "contract_status": "active"
      },
      "created_at": "2026-05-24T16:35:12Z",
      "processed_at": "2026-05-24T16:35:12Z"
    },
    {
      "id": "55555555-5555-4555-8555-555555555557",
      "partner_id": "11111111-1111-4111-8111-111111111111",
      "fx_contract_id": "33333333-3333-4333-8333-333333333333",
      "direction": "outgoing",
      "event_type": "payout_settled",
      "idempotency_key": "evt_5f8a1c7b9d2e4a3f",
      "status": "delivered",
      "retry_count": 0,
      "last_error": null,
      "payload": {
        "event_id": "evt_5f8a1c7b9d2e4a3f",
        "event_type": "payout_settled",
        "delivered_at": "2026-08-07T13:43:12Z",
        "fx_contract_id": "33333333-3333-4333-8333-333333333333",
        "crebit_contract_reference": "crebit_lock_7f3a9c2b1d",
        "partner_transaction_reference": "platform-tx-9901",
        "payout": {
          "status": "settled",
          "amount": "4500.00",
          "currency": "USDC",
          "chain": "ethereum",
          "destination_wallet_address": "0xEndUserWallet…",
          "transaction_hash": "0xf3a1...e29c",
          "block_number": 21345678,
          "settled_at": "2026-08-07T13:43:08Z"
        },
        "contract": {
          "locked_rate": "5.42",
          "live_execution_rate": "5.51",
          "notional_amount": "50000.00",
          "fx_delta_in_quote_currency": "4500.00"
        }
      },
      "created_at": "2026-08-07T13:43:12Z",
      "processed_at": "2026-08-07T13:43:12Z"
    }
  ],
  "next_cursor": null
}

GET /api/v1/fx/payout-events, every outbound payout Crebit attempted to deliver to your webhook_url. Use this when your endpoint was down and you need to backfill.

HTTP code sample
curl -sS -X GET "https://lock-apis-test.crebitpay.com/api/v1/fx/payout-events?limit=25" \
  -H "Content-Type: application/json" \
  -H "X-Crebit-Key-Id: YOUR_KEY_ID" \
  -H "X-Crebit-Key-Secret: YOUR_KEY_SECRET" \
  -H "X-Crebit-Environment: sandbox"

OpenAPI spec

Every field, enum, and example documented above is also published as a standard OpenAPI 3.1 document, the same source of truth this docs site renders from. Use it for codegen (openapi-generator, swagger-typescript-api, etc.) or import it into Postman / Insomnia / Bruno to get an instant collection with the enum dropdowns and sample-payload pickers baked in.

  • Partner spec (sandbox + production servers): /openapi-partner.json , only the routes your platform actually calls.
  • Postman: File → Import → paste the URL above. Postman will surface every enum as a dropdown and the multi-example payloads as a request-body picker.
  • Insomnia / Bruno: Same flow, import as OpenAPI 3.x.
  • SDK codegen: openapi-generator generate -i /openapi-partner.json -g typescript-fetch -o ./crebit-lock-sdk
Crebit runs custody, pricing engines, and operator tooling behind the scenes, none of that is part of your integration. The partner spec is the only surface you should hit.