# Auth Final

`POST https://api.agilitycredit.net/v3/prefill/auth/{session_id}`

Docs page: https://apidocs.agilitycredit.com/api/prefill-auth-final · Tag: Prefill

Completes or polls the possession step for the session identified by `{session_id}`. Behavior depends on the channel chosen at Auth Initial: - **OTP sessions** — submit the applicant's SMS code in `otp_code`. Returns a pass/fail (`passed`, `sms_status`). - **Magic Link sessions** — there is no code to submit; the applicant completes possession by tapping the Magic Link. Call this endpoint with an empty body to **poll** the result. `status` is `pending` until the applicant taps the link, then `verified` or `failed`. Poll until `completed` is `true`. > **Polling note:** this endpoint is a `POST` and responses are cached per `Idempotency-Key`. Send a **fresh** `Idempotency-Key` on each poll so you receive the latest status rather than a cached response.

Authentication: `Authorization: Bearer <api key>`.

## Parameters

| Name | In | Required | Description |
| --- | --- | --- | --- |
| `session_id` | path | yes | The session identifier returned from the corresponding initial request. |
| `Idempotency-Key` | header | yes | A unique, idempotent key. We recommend to use a guid |
| `Agc-Tenant-Id` | header | yes | The tenant ID provided by Agility Credit. |
| `Agc-User-Id` | header | yes | The requestor user ID. |
| `Agc-Applicant-Id` | header |  | If passed, will assign the report to that applicant. If not, will create a new applicant ID |

## Request body (`application/json`)

OTP completion payload (`otp_code`) for OTP sessions, or an empty body when polling a Magic Link session.

Variant 1: `ProveAuthFinal`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `otp_code` | string |  | The one-time passcode the applicant received via SMS. Required for OTP sessions; omit when polling a Magic Link session. |
| `secret` | string |  | Optional shared secret. When it matches the secret supplied at Auth Initial, the response is signed with an `X-Agc-Signature` header. |

## Responses

| Status | Description | Body |
| --- | --- | --- |
| 200 | Possession status | one of: ProveAuthResponseOtpFinal, ProveAuthResponseMagicLinkStatus |
| 400 | Bad Request | BadRequestResponse |
| 401 | Unauthorized | UnauthorizedResponse |
| 403 | Forbidden | UnauthorizedResponse |
| 410 | Gone - the session expired or was not found. Restart with POST /prefill/auth. | BadRequestResponse |
| 429 | Too Many Requests | TooManyRequestsResponse |
| 500 | Internal Server Error | AgilityServerErrorResponse |
The 200 body is one of: `ProveAuthResponseOtpFinal`, `ProveAuthResponseMagicLinkStatus`.

### Error bodies

400:

```json
{
  "status": "Bad Request - Invalid Parameters",
  "error": "Failed schema validation. Error: data.pull_type must be one of ['prequal', 'hard'], Path: ['data', 'pull_type'], Data: prequalification"
}
```

401:

```json
{
  "message": "Unauthorized"
}
```

403:

```json
{
  "message": "Unauthorized"
}
```

410:

```json
{
  "status": "Bad Request - Invalid Parameters",
  "error": "Failed schema validation. Error: data.pull_type must be one of ['prequal', 'hard'], Path: ['data', 'pull_type'], Data: prequalification"
}
```

429:

```json
{
  "error": "Too Many Requests"
}
```

500:

```json
{
  "message": "Agility Server Error"
}
```
