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

# Verify Checkpoint (2FA)

> Submit a verification code to complete account connection

Complete 2FA verification for an account that returned `checkpoint_required` during login. Depending on the `challenge_type` used at login, either submit a verification code or simply confirm the app challenge.

<Note>
  This endpoint costs **1 credit** per request. Ignore this if you're on per-seat pricing: usage is unlimited.
</Note>

<Note>Also completes an **email** OAuth connection (Gmail / Microsoft): after the user consents, submit the `code` (and `state`) returned to your `redirect_uri` together with the `account_id`. See [Connect a mailbox](/api-reference/v2/accounts/login#email-mailbox).</Note>

<Note>**WhatsApp**: send only the `account_id` to get the current QR code, or `connected` once scanned. `resend: true` gives a new code once it expired. See [Connect Account](/api-reference/v2/accounts/login#whatsapp).</Note>

### Header Parameters

<ParamField header="x-api-key" type="string" required>
  Your API key
</ParamField>

### Body Parameters

<ParamField body="account_id" type="string" required>
  The account ID returned from the `/v2/login` endpoint with `checkpoint_required` status
</ParamField>

<ParamField body="code" type="string">
  The verification code received via email, SMS, or authenticator app. Required when `challenge_type` is `code_challenge`. Not needed for `app_challenge` — the user approves directly from the platform's mobile app.

  `checkpoint_type` in the login response tells where the code went. Each new `/v2/login` invalidates the previous code.
</ParamField>

<ParamField body="resend" type="boolean" default="false">
  LinkedIn only. Set to `true` to have LinkedIn send the verification code again on the same channel if the user did not receive it. No `code` needed, no credit consumed — then call this endpoint again with the code.
</ParamField>

### Response

<ResponseField name="success" type="boolean">
  Whether the verification was successful
</ResponseField>

<ResponseField name="data" type="object">
  <Expandable title="Properties">
    <ResponseField name="account_id" type="string">
      The account ID, now fully connected
    </ResponseField>

    <ResponseField name="status" type="string">
      `connected` — the account is ready to use
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseExample>
  ```json Success Response theme={null}
  {
    "success": true,
    "data": {
      "account_id": "69c127c37cae0494dd827286",
      "status": "connected"
    },
    "metadata": {
      "action": "checkpoint",
      "credits_consumed": 1,
      "timestamp": "2025-01-15T10:32:00.000000"
    }
  }
  ```

  ```json Resend (resend: true) theme={null}
  {
    "success": true,
    "data": {
      "account_id": "69c127c37cae0494dd827286",
      "status": "code_sent"
    },
    "metadata": {
      "action": "checkpoint",
      "credits_consumed": 0,
      "timestamp": "2025-01-15T10:31:00.000000"
    }
  }
  ```

  ```json Error — Invalid Code theme={null}
  {
    "success": false,
    "error": {
      "code": "CHANNEL_ERROR",
      "message": "Verification failed"
    },
    "metadata": {
      "action": "checkpoint",
      "credits_consumed": 0,
      "timestamp": "2025-01-15T10:32:00.000000"
    }
  }
  ```

  ```json Error — Session Expired theme={null}
  {
    "success": false,
    "error": {
      "code": "CHANNEL_ERROR",
      "message": "Session expired, please login again"
    },
    "metadata": {
      "action": "checkpoint",
      "credits_consumed": 0,
      "timestamp": "2025-01-15T10:32:00.000000"
    }
  }
  ```
</ResponseExample>

### Challenge Types

* **`code_challenge`** — The user receives a verification code (email, SMS, or authenticator app). Submit the code in the `code` field.
* **`app_challenge`** — The user approves the login directly from the platform's mobile app. Once approved, call this endpoint with only the `account_id` (no `code` needed).

### Notes

* If the session has expired, you need to call `/v2/login` again to restart the process
* Once verified, the account status changes to `connected` and is ready for use
* The `account_id` remains the same — no need to update your integration


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