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

# KYC Flow

> Collect and verify identity.

<Tip>Prerequisite: have a session token. See Authentication.</Tip>

## Flow

```mermaid theme={null}
sequenceDiagram
  participant Backend as Your Backend
  participant MachinesAPI as Machines API

  Backend->>MachinesAPI: POST /sessions (create session)
  Backend->>MachinesAPI: GET /kyc/values
  Backend->>MachinesAPI: POST /kyc/applications
  MachinesAPI-->>Backend: status = pending
  loop poll
    Backend->>MachinesAPI: GET /kyc/status
    MachinesAPI-->>Backend: status = approved | needs_information | denied
  end
  Backend->>MachinesAPI: GET /agreements
  Backend->>MachinesAPI: POST /agreements
```

## Steps

<Steps>
  <Step title="1) Get fields + values">
    <a href="/api/kyc/values" target="_blank" rel="noreferrer"><code>GET /kyc/values</code></a> to see required fields and allowed values.
  </Step>

  <Step title="2) Submit application">
    <a href="/api/kyc/applications" target="_blank" rel="noreferrer"><code>POST /kyc/applications</code></a> with the fields below. Sandbox: set <code>lastName</code> to <code>approved</code> to auto‑approve.
  </Step>

  <Step title="3) Complete verification">
    We return a <code>completionLink</code> (or <code>externalVerificationLink</code>). Open it in a browser for document upload and face match. Users finish verification there — you don’t need to handle media.
  </Step>

  <Step title="4) Check status">
    Poll <a href="/api/kyc/status" target="_blank" rel="noreferrer"><code>GET /kyc/status</code></a> until the status becomes <code>approved</code> (or an actionable state such as <code>needs\_information</code>).
  </Step>

  <Step title="5) Accept agreements">
    After approval, fetch the agreements and collect user consent. See <a href="/agreements">Agreements</a>.
  </Step>
</Steps>

## States

* approved
* pending
* needs\_information
* needs\_verification
* manual\_review
* denied
* locked
* canceled

## Fields (submit application)

<ParamField path="firstName" type="string" required>
  Given name.
</ParamField>

<ParamField path="lastName" type="string" required>
  Family name. Sandbox shortcut: set to <code>approved</code> to auto-approve.
</ParamField>

<ParamField path="birthDate" type="string" required>
  YYYY-MM-DD (e.g., 1990-01-01).
</ParamField>

<ParamField path="nationalId" type="string" required>
  Government ID number (letters, numbers, dashes only).
</ParamField>

<ParamField path="countryOfIssue" type="string" required>
  ISO-3166-1 alpha-2 country code (e.g., US). Case-insensitive.
</ParamField>

<ParamField path="email" type="string" required>
  Email address.
</ParamField>

<ParamField path="phoneCountryCode" type="string">
  Optional phone dial code digits only (e.g., 1).
</ParamField>

<ParamField path="phoneNumber" type="string">
  Optional phone number digits only (include area code).
</ParamField>

<ParamField path="address.line1" type="string" required>
  Street address (line 1).
</ParamField>

<ParamField path="address.line2" type="string">
  Street address (line 2).
</ParamField>

<ParamField path="address.city" type="string" required>
  City.
</ParamField>

<ParamField path="address.region" type="string" required>
  State/region (e.g., CA).
</ParamField>

<ParamField path="address.postalCode" type="string" required>
  Postal/ZIP code.
</ParamField>

<ParamField path="address.countryCode" type="string" required>
  ISO-3166-1 alpha-2 country code (e.g., US). Case-insensitive.
</ParamField>

<ParamField path="occupation" type="string" required>
  SOC occupation code (e.g., <code>49-3023</code>). Full list: <a href="/kyc-values">KYC Field Values</a>.
</ParamField>

<ParamField path="annualSalary" type="string" required>
  Choose one label (we map to the underlying range for you):

  * <code>\<40k</code>
  * <code>50k–99k</code>
  * <code>100k–149k</code>
  * <code>150k+</code>
</ParamField>

<ParamField path="accountPurpose" type="string" required>
  Choose one:

  * <code>everyday spend</code>
  * <code>subscriptions</code>
  * <code>business expenses</code>
  * <code>testing</code>
  * <code>other</code>
</ParamField>

<ParamField path="expectedMonthlyVolume" type="string" required>
  Choose one label (we map to the underlying range for you):

  * <code>under \$1k</code>
  * <code>$1k–$5k</code>
  * <code>$5k–$20k</code>
  * <code>\$20k+</code>
</ParamField>

## Response (status)

<ResponseField name="status" type="string" required>
  One of: <code>approved</code>, <code>pending</code>, <code>needs\_information</code>, <code>needs\_verification</code>, <code>manual\_review</code>, <code>denied</code>, <code>locked</code>, <code>canceled</code>.
</ResponseField>

<ResponseField name="applicationId" type="string">
  Identifier for the submitted application (when available).
</ResponseField>

<ResponseField name="reason" type="string">
  Additional context for non-approved statuses.
</ResponseField>

<Note>Sandbox shortcut: set <code>lastName</code> to <code>approved</code> to auto‑approve. See <a href="/kyc-values">KYC Field Values</a> for allowed field values.</Note>
