PaymentProvider KYC

Submit RFI answers

POST
/openapi/v1/customers/provider-kyc/rfis/{rfiId}/answers

Submits the answers to all questions of an RFI waiting for answers.

The request is multipart/form-data. The data part is the JSON answers. Each other part is one file, and its part name equals a value in answers[].clientFileIds.

  • If the RFI is already under review (UNDER_REVIEW), the current status is returned. Nothing is written and there is no submittedAt.
  • Idempotency-Key is required. Reuse the original key when you retry the same submission. The provider does not accept it twice.
  • Acceptance is not approval and does not lift restrictions.
  • Stabo checks only that required fields are not empty, the safe characters of clientFileId, the file part match, and file size and type. The provider decides question ownership, required questions, length, file count, and selected values. A failure returns openapi.channel.rejected.

For the answer format of each question type, see Provider KYC and account opening.

Authorization

bearerAuth
headerAuthorizationBearer <token>

The access_token obtained from POST /oauth2/token. Header format: Authorization: Bearer {accessToken}.

Path Parameters

rfiId*string

RFI ID assigned by the provider.

Header Parameters

X-Channel-Provider*string

Provider identifier. Provider KYC supports only LEGEND now.

Idempotency-Key*string

Unique request identifier, at most 128 characters. Reuse the original key when you retry the same submission. If it is missing, error.idempotent.key.missing is returned.

Request Body

multipart/form-data
  1. body

The data part plus file parts. The part name of each file part equals a value in answers[].clientFileIds.

data*

Answers to the full RFI, sent as the multipart data part. Unknown fields are rejected.

[key: string]?unknown

File content. One file is at most 2 MB. Only PDF, PNG, and JPEG.

Response Body

The submit result.

application/json
  1. response
code?integer

Business status code

message?string
traceId?string

Request trace ID. Provide it when you contact technical support

data?
Example Request
curl -X POST 'https://api.test.stabofx.com/openapi/v1/customers/provider-kyc/rfis/rfc_xxx/answers' \  -H 'X-Channel-Provider: LEGEND' \  -H 'Idempotency-Key: 5f0c7b2e-1d3a-4c8e-9b6f-2a4d6e8f0a1c' \  -F 'data={  "customerUid": "cust_example_001",  "answers": [    {      "questionId": "rfq_text"    }  ]}' \  -F 'property1=null' \  -F 'property2=null'
Example Response
{  "code": 200,  "message": "OK",  "traceId": "trace-uuid-string",  "data": {    "rfiId": "rfc_xxx",    "status": "UNDER_REVIEW",    "submittedAt": "2026-11-10T10:00:00+08:00"  }}

Create an IDV session POST

Creates an identity verification session for an IDV question of an RFI waiting for answers. - If the RFI is not `ACTION_REQUIRED`, `provider_kyc.rfi.not_actionable` is returned. If the question is not an IDV question of this RFI, `provider_kyc.rfi.question_not_idv` is returned. - `url` is a one-time session link. Give it only to the person who completes the verification. Do not log or forward it. - After the verification, still submit this question with the full RFI.

Create a fiat account POST

Create a fiat account. The request format depends on the provider: LEGEND uses `application/json`, and GLDB uses `multipart/form-data`. **LEGEND** - `Idempotency-Key` is required. - On synchronous success, the standard account is returned directly, and the status can be `ACTIVE`. If `PENDING` is returned, query the account detail. - If `fiat.account.channel.detail_unavailable` is returned, query with the account ID in the message. Do not open the account again. - A request body with undefined fields is rejected. **GLDB** - Do not send `Idempotency-Key`. If you send it, `fiat.account.idempotency_key.unsupported` is returned. - `currency` accepts only one currency. Multi-currency applications are not supported. - Account opening requires manual review. Create returns `PENDING`, and `accountId` is the application number. Use it to poll the account detail. After approval, the status changes to `ACTIVE`. - No Webhook is sent for status changes. If you send a field that belongs to the other provider, `fiat.account.field.unsupported` is returned. If a field that this provider requires is missing, `fiat.account.field.required` is returned.