GuidesAPI ReferenceChangelog
API Reference

RFI Webhooks

Receive notifications when a transaction RFI needs information, has been answered, is rejected, or is closed.

Use RFI webhooks to find out when we need information from you and when the case moves to a new review stage.

Treat every webhook as a notification that something changed, not as the complete case. After you receive an event, retrieve the case before deciding what to do next.

Handle every RFI webhook

Follow the same steps for every RFI event:

  1. Verify the webhook signature.
  2. Deduplicate the delivery using the X-Webhook-Event-Id request header.
  3. Read the case_id from resource.id.
  4. Retrieve the latest case from GET /v1/customers/{customer_id}/rfi-cases/{case_id}.
  5. If the case includes action_required, respond to every requirement marked ACTION_REQUIRED.
  6. Keep a slower polling job running with updated_from so you can recover any event you missed.

Events you can receive

EventWhat happenedWhat you should do
rfi.transaction.action_requiredWe need a new or corrected response from you. You may receive this event more than once for the same case.Retrieve the case and send the requested TEXT or FILE information.
rfi.transaction.answeredWe received everything requested in the current round and can continue our review.No response is needed right now. Keep monitoring the case.
rfi.transaction.rejectedWe rejected the RFI case.Stop sending new information to the case and retrieve the related transaction separately for its outcome.
rfi.transaction.closedWe completed our review and closed the case.No action is needed unless we reopen the case and request more information.

A returned FILE or TEXT response is not the same as a rejected case. When a response needs correction, its requirement returns to ACTION_REQUIRED, and we send another rfi.transaction.action_required event. Read data.note for the latest instructions.

Delivery and reconciliation

Webhook delivery is asynchronous and at least once. An event may arrive late or more than once, and events may not arrive in the same order as the case changes.

That is why the webhook should start a case lookup rather than update your local status by itself. Always retrieve the case for its current status, and use the list endpoint with updated_from as a recovery check. See Webhooks for signature verification, retries, and delivery headers.

Find the case and transaction

Every RFI event identifies both the case that changed and its related transaction:

{
  "event_name": "rfi.transaction.action_required",
  "resource": {
    "type": "rfi_cases",
    "id": "TC-8U4F-K9TF"
  },
  "data": {
    "case_id": "TC-8U4F-K9TF",
    "subject": {
      "type": "TRANSACTION",
      "id": "d6e8f011-853c-41d5-81e5-34dfedaac553",
      "transaction_type": "FIAT_PAYOUT_THIRD_PARTY"
    }
  }
}
FieldHow to use it
event_nameUse this to route the event to the right handler.
resource.typeThis is always rfi_cases for RFI events.
resource.idThis is the RFI case_id. Use it to retrieve the case.
data.case_idThis repeats the same case_id for convenience.
data.subjectThis identifies the transaction related to the case.

The event body does not contain the delivery ID. Use the X-Webhook-Event-Id request header when you deduplicate deliveries.

When we need more information

We send rfi.transaction.action_required when a FILE or TEXT requirement needs a response. The event includes a stable data.requirement_id so you can correlate it with the case, but you do not send that ID back when responding.

FILE requirement

{
  "event_name": "rfi.transaction.action_required",
  "resource": {
    "type": "rfi_cases",
    "id": "TC-8U4F-K9TF"
  },
  "data": {
    "case_id": "TC-8U4F-K9TF",
    "subject": {
      "type": "TRANSACTION",
      "id": "d6e8f011-853c-41d5-81e5-34dfedaac553",
      "transaction_type": "FIAT_PAYOUT_THIRD_PARTY"
    },
    "action": "SUBMIT_INFORMATION",
    "requirement_id": "RQ-2HTM-XQ7N",
    "requirement_type": "FILE",
    "document_type": "CONTRACT_AGREEMENT",
    "note": "Please provide the signed agreement."
  }
}

Retrieve the case, then send a multipart FILE response using the requested document_type. Do not include requirement_id in the submission path or body.

TEXT requirement

{
  "event_name": "rfi.transaction.action_required",
  "resource": {
    "type": "rfi_cases",
    "id": "TC-8U4F-K9TF"
  },
  "data": {
    "case_id": "TC-8U4F-K9TF",
    "subject": {
      "type": "TRANSACTION",
      "id": "d6e8f011-853c-41d5-81e5-34dfedaac553",
      "transaction_type": "FIAT_PAYOUT_THIRD_PARTY"
    },
    "action": "SUBMIT_INFORMATION",
    "requirement_id": "RQ-7GQ9-2CMX",
    "requirement_type": "TEXT",
    "note": "Please explain the business purpose of this payment."
  }
}

The webhook note tells you what we need. Retrieve the case, then send your answer in the JSON text field:

{
  "type": "TEXT",
  "text": "The payment is for invoice INV-2026-001."
}

When we have the current response

We send rfi.transaction.answered after we receive everything requested in the current round. The case is now ANSWERED and waiting for our review.

You do not need to respond to this event. Keep monitoring the case because we may ask for more information later. If that happens, the case returns to ACTION_REQUIRED, and we send a new action-required event.

{
  "event_name": "rfi.transaction.answered",
  "resource": {
    "type": "rfi_cases",
    "id": "TC-8U4F-K9TF"
  },
  "data": {
    "case_id": "TC-8U4F-K9TF",
    "subject": {
      "type": "TRANSACTION",
      "id": "d6e8f011-853c-41d5-81e5-34dfedaac553",
      "transaction_type": "FIAT_PAYOUT_THIRD_PARTY"
    }
  }
}

When we reject the case

We send rfi.transaction.rejected when we reject the RFI case. The event does not include an internal rejection reason.

The RFI case and transaction have separate outcomes, so do not infer the transaction result from this event. Retrieve the transaction separately.

{
  "event_name": "rfi.transaction.rejected",
  "resource": {
    "type": "rfi_cases",
    "id": "TC-8U4F-K9TF"
  },
  "data": {
    "case_id": "TC-8U4F-K9TF",
    "subject": {
      "type": "TRANSACTION",
      "id": "d6e8f011-853c-41d5-81e5-34dfedaac553",
      "transaction_type": "FIAT_PAYOUT_THIRD_PARTY"
    }
  }
}

When we close the case

We send rfi.transaction.closed when our review is complete and the case moves to CLOSED. Closing the case does not change the transaction status.

{
  "event_name": "rfi.transaction.closed",
  "resource": {
    "type": "rfi_cases",
    "id": "TC-8U4F-K9TF"
  },
  "data": {
    "case_id": "TC-8U4F-K9TF",
    "subject": {
      "type": "TRANSACTION",
      "id": "d6e8f011-853c-41d5-81e5-34dfedaac553",
      "transaction_type": "FIAT_PAYOUT_THIRD_PARTY"
    }
  }
}

If we reopen the case and need another response, you will receive rfi.transaction.action_required.

Related guides

  • Webhook overview explains signature verification, retries, and delivery headers.