Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.proof.community/llms.txt

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

If you provide a webhook_url at onboarding, Proof POSTs a normalized transaction event to that URL on every status change. This channel is optional — many partners rely on WebSocket and polling only. The webhook is most useful when your backend needs to react server-side without keeping a persistent connection open.

Delivery model

AttributeValue
HTTP methodPOST
Content-Typeapplication/json
TriggerEvery status change for any of your transactions
DeliveryBest-effort, fire-and-forget
RetriesNone on a single status change. Proof relies on internal retries to redeliver, which can result in the same merchant_transaction_id arriving multiple times
Authoritative sourceNo — pair the webhook with polling or WebSocket for state your business depends on

Payload

{
  "merchant_transaction_id": "550e8400-e29b-41d4-a716-446655440000",
  "type": "buy",
  "status": "completed",
  "currency": "USDT",
  "network": "TRC20",
  "crypto_amount": "99.50",
  "fiat_currency": "EUR",
  "fiat_amount": "100.00",
  "created_at": "2026-04-01T10:00:00Z",
  "updated_at": "2026-04-01T10:03:45Z"
}
FieldTypeNotes
merchant_transaction_idstringStable across retries; use as your idempotency key
typestring"buy" or "sell"
statusstringNormalized: pending, processing, completed, failed, cancelled
currencystringCrypto currency
networkstringBlockchain network
crypto_amountstringMay be empty before processing
fiat_currencystringFiat currency
fiat_amountstringFiat amount
created_atstringISO 8601 timestamp (UTC)
updated_atstringISO 8601 timestamp (UTC) of this status change
The status enum matches GET /widget/transactions/{id} and the WebSocket tx.update event.

Handler expectations

Respond with any 2xx status code as quickly as possible. Heavy work should happen asynchronously after acknowledgement.
Be idempotent on merchant_transaction_id + status. Treat duplicate deliveries as no-ops.
Treat the webhook as advisory. If the webhook stops arriving for a transaction you care about, fall back to polling or WebSocket — do not block business logic on the webhook alone.

Example handler (Express)

app.post("/proof-webhook", express.json(), async (req, res) => {
  const event = req.body;

  // ACK first
  res.sendStatus(200);

  // Process asynchronously, idempotently
  await reconcileTransaction(event.merchant_transaction_id, event.status, event);
});

Updating the webhook URL

Contact the Proof team to add, change, or remove your webhook_url. There is no self-service endpoint.