Overview
An information request (RFI) is MoonPay Enterprise asking for more detail about one of your customers. An RFI carries questions, a request for documents, or both. You collect the answers from your customer, submit them through the API, and MoonPay reviews and closes the RFI. There are three types:probing_questions: questions about the customer or their activitysource_of_funds: questions about specific transactions. Always tied to a transactionliveness: a new selfie check. The RFI carries aliveness_urlto send your customer to. It takes no answers and no follow-up rounds, so a response to it returns400
RFIs do not emit webhooks. Poll
GET /api/rfis to pick up new requests.Rounds
Every RFI has at least one round. Round 1 is created with the RFI. If your answers don’t settle the question, MoonPay sends a follow-up round with new questions on the same RFI. Only the latest round accepts a response. The write endpoints take around_id and return 409 Conflict if that round is not the latest one, so read the RFI first and use the round with the highest round_number. Rounds come back sorted by round_number ascending.
Statuses
Submitting a response moves an RFI from
waiting_on_response to needs_review. A follow-up round moves it back to waiting_on_response.
The API does not return how an RFI was resolved. A
closed RFI tells you MoonPay is done with it, not whether the response passed.How it works
1
Poll for open RFIs
GET /api/rfisReturns open RFIs grouped by customer, oldest first.2
Read the latest round
Take the round with the highest
round_number. Its questions are what you need to answer, and documents_requested tells you whether documents are also needed.3
Upload documents, if requested
POST /api/rfis/{rfi_id}/rounds/{round_id}/documentsCollect the files from your customer and upload each one. Upload at least one before you submit the response.4
Submit the response
POST /api/rfis/{rfi_id}/rounds/{round_id}/responseAnswer every required question in one call. The RFI moves to needs_review.5
Wait for MoonPay
MoonPay either closes the RFI or sends a follow-up round. Keep polling to find out which.
Answer an RFI in the dashboard
Every RFI also shows up in the Partner Dashboard, so your team can answer one without an integration. The dashboard calls the same endpoints documented below, so an RFI answered there reachesneeds_review exactly as an API response does.
1. Open the RFI queue
Compliance > RFIs: every customer with an open request, how many requests each one has, and the age of the oldest. The status column separates what you owe a response on from what is already back with MoonPay.
2. Read the request
Click the customer’s name. Questions · Round 1 lists what was asked, with a Needs action badge while a response is outstanding. The copy button copies the questions to your clipboard to forward to your customer. Required questions carry an asterisk, and each answer box matches the question type: free text, or Yes/No with an optional details field.
3. Submit the response
Submit response stays disabled until every required question has an answer. When documents were requested, the card also shows a file upload, and submitting is blocked until at least one file is uploaded. After submitting, the card turns read-only: a Submitted badge, your answers echoed under each question, a Responded timestamp, and Copy Q&A for the whole exchange. The customer’s row drops its needs-action badge.
A follow-up round arrives as a new Questions · Round 2 card on the same RFI, and the customer’s row goes back to needs action. Answer it the same way.
List open RFIs
GET /api/rfis
By default, returns RFIs in waiting_on_response or needs_review, grouped by customer. Customers with at least one RFI still waiting on a response come first, then the customer whose oldest RFI was sent earliest. Closed RFIs are not included unless you pass state=completed, which returns only closed RFIs, most recently closed first.
Query parameters
Response
cursor is the customer ID to pass as cursor for the next page. It is null on the last page.
List a customer’s RFIs
GET /api/customers/{customer_id}/rfis
Returns the open RFIs for one customer as a flat array, newest first. Closed RFIs are not included here. Fetch a closed RFI by ID instead.
Get an RFI
GET /api/rfis/{rfi_id}
Returns one RFI in any status, including closed.
Response
string (UUID)
required
The RFI ID.
string (UUID)
required
The customer the RFI is about.
string (UUID)
The transaction under review. Always set for
source_of_funds, null otherwise.string
required
probing_questions, source_of_funds, or liveness.string
required
waiting_on_response, needs_review, or closed.string
The verification link to send your customer on a
liveness RFI. Omitted on every other RFI type, and on a liveness RFI until the link is ready.array
required
One entry per round, sorted by
round_number ascending.string (ISO 8601)
required
When the latest round was sent. A follow-up round resets it.
string (ISO 8601)
When your response to the latest round arrived.
null until you respond, and reset to null when a follow-up round is sent.string (ISO 8601)
When MoonPay closed the RFI.
null while it is open.string
A note from MoonPay about a closed RFI. Set only on some closed RFIs,
null otherwise.string (ISO 8601)
required
When the RFI was created.
string (ISO 8601)
required
When the RFI last changed.
Upload a document
POST /api/rfis/{rfi_id}/rounds/{round_id}/documents
Uploads one file for a round that has documents_requested: true. Send it as multipart/form-data in a file field. Each file must be a PDF, PNG, or JPEG of at most 10 MB, and a round holds at most 20 files. Call it once per file.
200 with the uploaded document:
400 with a plain-text body:
This
POST requires an Idempotency-Key header. See Idempotency for retry behavior.Record that the upload link was opened
POST /api/rfis/{rfi_id}/rounds/{round_id}/document-link-opened
Applies only to legacy rounds that carry a document_upload_url. Records that the link was opened, and stamps document_link_opened_at. Call it once, when you hand the link to your customer.
On a legacy round, an API key can submit a response with documents_uploaded: true without this call. A signed-in dashboard user has to open the link first, otherwise the response is rejected with 400.
200 with an empty body.
This
POST requires an Idempotency-Key header. See Idempotency for retry behavior.409. See Common errors.
Submit a response
POST /api/rfis/{rfi_id}/rounds/{round_id}/response
Submits answers for one round. One call per round: there is no partial save, so send every answer you have at once.
Body
200 with an empty body. The RFI moves to needs_review and response_received_at is set on both the round and the RFI.
This
POST requires an Idempotency-Key header. See Idempotency for retry behavior.Error response
A rejected response returns400 with a plain-text body, not JSON:
Common errors
Among errors,
400 is the only status that carries a body. Unlike most of the API, these endpoints return no message or trace_id on 500.