Skip to main content
Webhooks are one of two ways to price RFQs. The maker WebSocket carries the same rounds over one outbound connection, with no public endpoint and no signature to check.
Your pricer serves three endpoints under the base URL you register. We call them, and you answer. Every request has a JSON body and an X-Novig-Signature header. Check the signature before you trust the body. Webhook signing shows how.

Quote an RFQ

We call /quote for every RFQ, with the outcomes the taker wants to combine. You answer with a price and the largest wager you’ll take at that price.

Request body

We send the same rfq_id again on /confirm. Universe model explains outcome IDs. GET /rfq/executions returns the same IDs sorted by outcome ID, not in request order. We leave out min_wager when the taker didn’t set one. We never pick a quote whose max_wager is below min_wager or below the platform minimum of 10.00, whichever is higher.

Response body

A price of 0.45 means the taker stakes $0.45 for each $1.00 of payout. We round price to the nearest 0.001, from 0.001 to 0.999. The order book’s tick sizes don’t apply to RFQ quotes. Send max_wager as a JSON string to keep its precision. quote_id can be up to 256 bytes. We send it back as external_flag on /confirm.
A quote has no expiry field. We set its lifetime when the auction closes: 30 seconds before the game and 10 seconds for a live market.

When we drop your quote

We wait 3 seconds for quotes. We drop a response that arrives later, and the taker never sees it.
We also drop your quote when:
  • Your response has a status other than 2xx.
  • The body isn’t valid JSON.
  • price rounds to 0 or 1, or falls outside that range.
  • max_wager is 0 or less.
  • quote_id is longer than 256 bytes.
When we drop a quote, the taker doesn’t see it. You lose that trade, and nothing else happens.

Decline an RFQ

Return 204 No Content to pass on an RFQ. We record a 204 as a deliberate pass. An error or a timeout also drops your quote, but it looks like a broken pricer. A 204 keeps your webhook active. After 7 days of only errors and timeouts, we stop calling it.

Confirm a trade

If your quote wins, we call /confirm just before we write the trade. It carries the taker’s actual wager, which is never more than your max_wager. This is your last chance to back out.
You have 1 second to answer. If you haven’t answered by then, we reject the trade. An early answer waits for the full second, so a fast answer gains nothing.

Request body

We only call the winning pricer, so price is always yours. We leave out external_flag when you sent no quote_id. Don’t expect a null.

Response body

When you reject, we write nothing and the parlay is rejected.
Always include confirmed. A response without it, a non-2xx status, or an invalid body rejects the trade, just like false.

Answer a ping

We call /ping only when you call POST /rfq/pricer/ping. It checks that we can reach you and that your signature check works. It isn’t part of trading and carries no quote. A 2xx answer also restarts a paused webhook.

Request body

Check the signature exactly as you do on /quote and /confirm.

Response

Return any 2xx status. No body is required. We report your status as ok and status in the ping result. A non-2xx status, a rejected signature, or an unreachable host all show up as a failed ping.

Keep your webhook active

We stop sending RFQs to a webhook that hasn’t answered for 7 days. Your registration stays, and the WebSocket isn’t affected. Your webhook counts as active each time it answers one of these:
  • A /quote request, with a quote or a 204.
  • A ping, with a 2xx status.
An error, a timeout, or an invalid body doesn’t count. To get RFQs on a paused webhook again, call POST /rfq/pricer/ping. When the result has ok: true, RFQs reach your webhook again within a minute.

Types and encoding

  • max_wager, wager, and the /confirm price are JSON strings, not numbers.
  • The /quote response price is a JSON number between 0 and 1.
  • UUIDs are lowercase strings with hyphens.