> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fluz.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Requests for information (RFIs)

> Read the documentation requests Fluz sends to your customers and answer them from your own UI: questions, file uploads, bank links and submission for review.

## Overview

A **request for information (RFI)** is a set of questions Fluz sends to a customer when compliance needs more from them — most often during KYB review (formation documents, proof of address, an ownership chart), and sometimes later in the life of an account.

The RFI API lets your platform show those requests and collect the answers in your own UI, instead of sending the customer to Fluz. Across four operations you:

1. List the customer's open RFIs with [openRfis](https://docs.fluz.app/get-rfis), or read one with [rfi](https://docs.fluz.app/get-rfis),
2. Upload any documents the questions ask for with the [RFI document upload](https://docs.fluz.app/upload-rfi-document) endpoint,
3. Answer bank-link and address questions with Plaid, if you want to, using [completeRfiPlaidLink](https://docs.fluz.app/complete-rfi-plaid-link), and
4. Send the answers with [submitRfi](https://docs.fluz.app/submit-rfi) — all at once, or in parts.

Once submitted, the RFI moves to `IN_REVIEW` and Fluz reviews it. The outcome comes back as a new status on the same RFI.

> [!NOTE]
>
> **Questions are written per RFI.** Fluz builds each RFI for the customer it is sent to, so the questions, their order and which ones are required differ between RFIs. Render what the API returns rather than hard-coding a form.

***

## Requirements

| Requirement | If missing |
| - | - |
| Your application holds the `MANAGE_RFI` scope, and the customer's OAuth grant includes it | `AUTH-0031` |
| You call with a **Bearer user token**. Basic auth (your API key) is not accepted on any RFI operation | `AUTH-0002` |
| The token carries both `userId` and `accountId` | `AUTH-0008` |
| The token's user is the RFI's addressee (see [Who can answer an RFI](#who-can-answer-an-rfi)) | `G-0003` (`ACCESS_DENIED`) |
| For Plaid answers only: the token also carries `MANAGE_PAYMENT` | `AUTH-0031` |

Select **`MANAGE_RFI`** in your application's permission scopes in the Fluz dashboard. Customers approve it on the consent screen during OAuth like any other scope. See [Application scopes](https://docs.fluz.app/fluz-dashboard/application-scopes.md).

### Who can answer an RFI

An RFI is addressed to one account. The token's `accountId` must be that account, and the token's user must be the account's addressee:

| RFI is on | Addressee |
| - | - |
| A consumer account | The user who owns that consumer account |
| A business account | The business's **applicant** — the user who submitted `registerBusiness` |

Other business owners, authorized users and sub-users cannot read or answer a business's RFIs through the API. Mint the token for the applicant on the business `accountId`.

***

## Flow

**1. Find the open RFIs**

Call [openRfis](https://docs.fluz.app/get-rfis) with the customer's token. It returns every RFI waiting for their answers, newest first, with its questions. An empty list means there is nothing to do.

**2. Render the questions**

Show each question in `ordinal` order. Use `questionType` to pick the input, `options` for choice questions, and `visibilityCondition` to hide questions that do not apply. See [Question types](#question-types).

**3. Upload documents**

For each file the customer attaches, call the [upload endpoint](https://docs.fluz.app/upload-rfi-document) with the `rfiId` and `questionId`. Keep the `fileId` it returns.

**4. Link a bank, if offered**

Bank-statement and proof-of-address questions can be answered with a Plaid bank link instead of a file. Open Plaid Link, then pass the public token to [completeRfiPlaidLink](https://docs.fluz.app/complete-rfi-plaid-link).

**5. Submit**

Call [submitRfi](https://docs.fluz.app/submit-rfi) with the answers. With `finalize: true` (the default) the RFI goes to `IN_REVIEW`. Use `finalize: false` to save part of the answers and come back later.

**6. Track the outcome**

Read the RFI again with [rfi](https://docs.fluz.app/get-rfis) to see its status. If Fluz needs more, the same RFI comes back to `PENDING_DOCUMENTS` with new questions and appears in `openRfis` again.

```mermaid theme={null}
sequenceDiagram
    autonumber
    participant App as Your Application
    participant API as Fluz GraphQL API
    participant Files as Fluz File Upload (REST)
    participant Plaid as Plaid Link
    participant Fluz as Fluz Compliance

    Fluz->>API: RFI sent to the customer (PENDING_DOCUMENTS)
    App->>API: query openRfis
    API-->>App: RFIs with questions

    opt Question asks for documents
        App->>Files: POST /api/v1/file-upload/rfi-document
        Files-->>App: fileId
    end

    opt Customer links a bank instead
        App->>API: mutation createPlaidLinkToken
        App->>Plaid: Open Plaid Link
        Plaid-->>App: public_token
        App->>API: mutation completeRfiPlaidLink
        API-->>App: Bank linked, answer saved
    end

    App->>API: mutation submitRfi (finalize: true)
    API-->>App: status IN_REVIEW
    Fluz->>Fluz: Review
    App->>API: query rfi(rfiId)
    API-->>App: REQUIREMENTS_MET, REQUIREMENTS_NOT_MET, or PENDING_DOCUMENTS again
```

***

## RFI status lifecycle

```mermaid theme={null}
stateDiagram-v2
    [*] --> PENDING_DOCUMENTS: Fluz sends the RFI
    PENDING_DOCUMENTS --> IN_REVIEW: submitRfi with finalize true
    PENDING_DOCUMENTS --> EXPIRED: Expiry date passes before submission
    IN_REVIEW --> PENDING_DOCUMENTS: Fluz asks for more
    IN_REVIEW --> REQUIREMENTS_MET: Review passed
    IN_REVIEW --> REQUIREMENTS_NOT_MET: Review did not pass
    PENDING_DOCUMENTS --> CLOSED: Closed by Fluz
    IN_REVIEW --> CLOSED: Closed by Fluz
```

| `RfiStatus` | What it means | What your app should do |
| - | - | - |
| `PENDING_DOCUMENTS` | Waiting for the customer's answers. The only status that accepts answers | Show the questions and collect answers |
| `IN_REVIEW` | Answers submitted and under review | Show an "under review" state. Nothing to answer |
| `REQUIREMENTS_MET` | Review finished and the requirements were met | Clear the request from your UI |
| `REQUIREMENTS_NOT_MET` | Review finished and the requirements were not met | Show a neutral message and direct the customer to support |
| `EXPIRED` | The expiry date passed before the RFI was submitted | Direct the customer to support. An expired RFI cannot be answered |
| `CLOSED` | Closed by Fluz without a review outcome | Clear the request from your UI |

Questions are returned only while an RFI is `PENDING_DOCUMENTS`. In every other status `questions` is an empty list.

> [!NOTE]
>
> A business with an open or in-review RFI reads `PENDING` in [getBusiness](https://docs.fluz.app/get-business.md). Submitting the RFI does not approve the business — wait for `kybStatus` to change.

***

## Question types

Every answer is sent as `value` in an `RfiAnswerInput`. Its shape depends on the question's `questionType`.

| `questionType` | `value` | Rules |
| - | - | - |
| `FREE_FORM_TEXT` | String | Up to 10,000 characters. Trimmed |
| `SINGLE_LINE_TEXT` | String | Up to 10,000 characters. Trimmed |
| `EMAIL` | String | A valid email address |
| `PHONE_NUMBER` | String | 7–20 characters of digits, spaces, `+`, `-`, `.`, `(` and `)`, with at least one digit |
| `NUMBER` | Number or numeric string | For example `1250` or `"1250.50"` |
| `DATE` | String | `YYYY-MM-DD`, a real calendar date |
| `DROPDOWN` | String | Exactly one of the question's `options` |
| `SINGLE_CHECKBOX` | String | Exactly one of the question's `options` |
| `MULTIPLE_CHECKBOX` | List of strings | Each one of the question's `options`, no repeats |
| `MULTI_UPLOAD` | List of `{ "fileId": "<uuid>" }` | 1–20 files [uploaded](https://docs.fluz.app/upload-rfi-document) for this question |
| `BANK_LINK_OR_STATEMENT` | List of `{ "fileId": "<uuid>" }` | 1–20 PDF or image files, **or** a bank linked with [completeRfiPlaidLink](https://docs.fluz.app/complete-rfi-plaid-link) |
| `ADDRESS_VERIFICATION_OR_DOCUMENT` | List of `{ "fileId": "<uuid>" }` | 1–20 PDF or image files, **or** a bank link whose bank confirms the customer's address |
| `SECTION_BREAK` | — | A heading for layout only. Not answerable |

### Required and optional questions

`isOptional: false` means the question must be answered before the RFI can be finalized. Optional questions can be left out.

### Conditional questions

When `visibilityCondition` is set, the question applies only if the condition holds against the answers to **earlier** questions. Evaluate it in your UI to show or hide the question:

```json theme={null}
{
  "kind": "GROUP",
  "logic": "AND",
  "items": [
    { "kind": "PREDICATE", "questionId": "q_entity_type", "operator": "EQ", "value": "LLC" },
    { "kind": "PREDICATE", "questionId": "q_member_count", "operator": "GT", "value": "1" }
  ]
}
```

| Field | Values |
| - | - |
| `kind` | `GROUP` (combines `items` with `logic`) or `PREDICATE` (one test) |
| `logic` | `AND` or `OR` |
| `operator` | `EQ`, `NEQ`, `IN`, `NOT_IN`, `GT`, `GTE`, `LT`, `LTE` |
| `value` | A string, or a list of strings for `IN` and `NOT_IN` |

* Conditions are tested against text and choice answers only. File and bank-link answers count as unanswered.
* A question that does not apply is not required, and any answer you send for it is ignored.

***

## Webhooks

To know when an RFI arrives without polling, subscribe to the RFI webhook events. See [Webhooks](https://docs.fluz.app/fluz-dashboard/webhooks.md#rfi-events).

***

## Related pages

> [card] [Read RFIs](https://docs.fluz.app/get-rfis)
>
> `openRfis` and `rfi`: the questions, saved answers and status.

> [card] [Upload RFI documents](https://docs.fluz.app/upload-rfi-document)
>
> The REST endpoint that returns the `fileId` you submit.

> [card] [Submit an RFI](https://docs.fluz.app/submit-rfi)
>
> Save answers, finalize, and handle validation errors.

> [card] [Answer with a bank link](https://docs.fluz.app/complete-rfi-plaid-link)
>
> Use Plaid instead of a bank statement or proof of address.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.