Skip to main content

Answer an RFI

Each open RFI has two kinds of items: questions (free-text answers from the customer) and document requests (one or more files attached against a slot). Resolve every item and the case will close on the next review.

You can submit responses two ways:

  • Per-item: one HTTP call per question answer or per document attach. Easiest for incremental UIs.
  • Bulk: one HTTP call carrying every answer and attachment in a single batch. If any item is invalid, the whole batch is rejected (Error handling).

All endpoints require the standard AccountId and Authorization: Bearer <token> headers.


Answering a question​

See the Answer an RFI question API reference for the full request/response schema.

curl -L -X POST 'https://sandbox-api.hubpay.io/v1/rfi/11111111-1111-1111-1111-111111111111/questions/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/answer' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'AccountId: 058a2d45-139c-436b-8d1f-eec265e0f418' \
-H 'Authorization: Bearer <token>' \
-d '{
"answer": "Funds originate from the sale of investment property completed in March 2026."
}'

The response is the updated Rfi, so you can use it to refresh your local copy in one round trip. Re-submitting an answer to the same question replaces the previous answer. Once the case is closed or cancelled, further answer attempts return 409 CONFLICT (RFI_NOT_OPEN).


Attaching documents to a document request​

Document responses are a two-step flow:

  1. Upload the file bytes via the RFI-specific upload endpoint POST /v1/rfi/{rfiId}/documents/upload. You get back a documentUploadId for each file.
  2. Attach one or more upload IDs to a specific document request on the RFI.

Step 1: upload the file​

curl -L -X POST 'https://sandbox-api.hubpay.io/v1/rfi/11111111-1111-1111-1111-111111111111/documents/upload' \
-H 'Content-Type: multipart/form-data' \
-H 'Accept: application/json' \
-H 'AccountId: 058a2d45-139c-436b-8d1f-eec265e0f418' \
-H 'Authorization: Bearer <token>' \
-F 'file=@"/path/to/bank-statement.pdf"'

The response carries the id of the upload: this is the documentUploadId you feed into the attach call below.

Step 2: attach the upload to the document request​

See the Attach documents API reference for the full request/response schema.

curl -L -X POST 'https://sandbox-api.hubpay.io/v1/rfi/11111111-1111-1111-1111-111111111111/document-requests/cccccccc-cccc-cccc-cccc-cccccccccccc/attach' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'AccountId: 058a2d45-139c-436b-8d1f-eec265e0f418' \
-H 'Authorization: Bearer <token>' \
-d '{
"documentUploadIds": [
"d1d1d1d1-d1d1-d1d1-d1d1-d1d1d1d1d1d1"
]
}'

Multi-file requirements (e.g. front + back of an ID) can be satisfied by passing multiple upload IDs in a single attach call. They merge into a single document, which is what gets reviewed and what subsequent webhooks reference.

The attach response is the updated Rfi. The documentRequests[] entry you just satisfied now has a non-null documentId: persist this, see below.


Critical: persist documentId for webhook correlation​

v1.rfi.document.* webhooks identify the document by the attached document's UUID, not the upload UUID you got from the upload endpoint. If you want to route an incoming v1.rfi.document.approved (or .declined / .validation_warnings) back to the originating RFI, you must persist a documentId → rfiId mapping.

Do not persist documentUploadId → rfiId

A common but broken pattern is to persist the upload ID from step 1. The webhook never carries that ID. Persist the documentId from the attach response (step 2) instead.

Pattern:

On attach response, for each entry in Rfi.documentRequests[]:
if entry.documentId is not null:
map[entry.documentId] = Rfi.id

On webhook arrival, look up event.data.documentId in the map to find the parent rfiId.

Each entry also exposes documentUploads[], which contains the same files as a list. If you prefer to walk the file list, Rfi.documentRequests[].documentUploads[].id resolves to the same UUID as documentId. Either path populates the same map.


Submitting multiple responses in bulk​

If your UI lets the customer answer everything at once and submit, the bulk endpoint avoids N round-trips. See the Submit RFI responses in bulk API reference for the full request/response schema.

curl -L -X POST 'https://sandbox-api.hubpay.io/v1/rfi/11111111-1111-1111-1111-111111111111/responses' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'AccountId: 058a2d45-139c-436b-8d1f-eec265e0f418' \
-H 'Authorization: Bearer <token>' \
-d '{
"answers": [
{
"questionId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
"answer": "Funds originate from the sale of investment property completed in March 2026."
},
{
"questionId": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
"answer": "Yes: please find the latest audit report attached."
}
],
"attachments": [
{
"documentRequestId": "cccccccc-cccc-cccc-cccc-cccccccccccc",
"documentUploadIds": [
"d1d1d1d1-d1d1-d1d1-d1d1-d1d1d1d1d1d1"
]
}
]
}'

The bulk call is atomic: if any answer or attachment is invalid, the entire batch is rejected and no state changes. The response, on success, is the updated Rfi. Walk documentRequests[] and persist documentId → rfiId for the new entries exactly as you would for a per-item attach.


Replace semantics​

ActionBehaviour
Re-answering a questionReplaces the previous answer in place.
Re-attaching to a satisfied document slotReplaces the previously attached document. The earlier document is retired and will not be reviewed.
Submitting once an item is APPROVEDReturns 409 CONFLICT (RFI_ITEM_ALREADY_APPROVED). Approved items are locked. See error handling.
Submitting once the case is closed/cancelledReturns 409 CONFLICT (RFI_NOT_OPEN). See error handling.

Refer to the API Reference for the full request/response schemas.