---
title: "Upload the back of the ID"
method: POST
path: "/api/v2/kyc/documents/back"
tags: ["Identity verification"]
---

# Upload the back of the ID

`POST /api/v2/kyc/documents/back`

Uploads the back of the document. The response tells you what to do next — this is the branch point of the flow:

- `needs_information` → collect exactly the `required_fields` and post them to `/kyc/information`.
- `requires_verification` → show the user the `iframe_url` for the face scan.
- `rejected` → the document couldn't be verified.

## Request body

- object
  - `user_id` string, required — The connected user's id.
  - `image` string, required — The image bytes, base64-encoded.
  - `mime_type` string — The image's MIME type.
  - `document_type` 'drivers_license' | 'state_id' | 'passport' — Optional document-type hint. Without it the document is auto-detected and defaults to a US driver's license. If a response `warnings` entry asks you to resubmit with a `document_type`, send the same image again with this field set — no need to go back to the user.
  - `issuing_country` string — Optional ISO 3166-1 country code (alpha-2 or alpha-3) of the country that issued the document. Defaults to US when the document doesn't reveal it — always send it for non-US documents (e.g. `DE` for a German national ID).

## Response `200`

The next step of the flow.

- KycState — The single status contract every KYC response carries.
  - `object` 'kyc'
  - `status` 'awaiting_documents' | 'needs_information' | 'requires_verification' | 'pending' | 'approved' | 'rejected' — `awaiting_documents` — upload the front and back. `needs_information` — collect the `required_fields` and submit them. `requires_verification` — show the user the `iframe_url`. `pending` — under review, no action needed. `approved` — verified, done. `rejected` — the user did not pass. Statuses are not one-way: a review can send a user back — `pending` may return to `needs_information` (a detail didn't match the document; re-collect the listed fields and resubmit, the check re-runs automatically) or to `awaiting_documents` (the images were unusable; upload both sides again). Always branch on the current status.
  - `required_fields` string[] — Only on `needs_information` — exactly the fields to collect and post to `/kyc/information`.
  - `iframe_url` string — Only on `requires_verification` — the URL to show the user for the face scan. Embed it in an iframe with `allow="camera; microphone"`. Short-lived: always use the most recent one from a poll or webhook, never a stored copy.
  - `warnings` string[] — Optional, on document uploads — actionable feedback safe to show the user (for example, that the other side of the document is still needed).
  - `extracted` object — Optional, on document uploads — what the document reader pulled off the uploaded image(s), so you can prefill your details form instead of asking the user to re-type what the ID already says. Keys match the `/kyc/information` request fields (`first_name`, `last_name`, `date_of_birth`, `address_line1`, `address_city`, `address_region`, `address_postal_code`, `address_country`) plus `document_type`, `issuing_country`, and `document_number` (the number printed on the document — for US documents this is NOT the SSN, so never prefill it into `national_id_number` when `issuing_country` is `US`). Fields appear as they become readable: the front usually carries the name and date of birth; a US back adds the barcode address. Always let the user confirm or correct prefilled values.
  - `reason` string — Optional, on `needs_information`, `awaiting_documents`, `requires_verification`, and `rejected` — a short, end-user-safe explanation of what the review asked for (for example, “Enter your full name exactly as it appears on your identity document.”). Safe to show the user verbatim.

## Other responses

- `400` — `invalid_request` — missing `user_id` or `image`, or an unrecognized `document_type` / `issuing_country`. `invalid_image` — `image` isn't valid base64. `client_credentials_required` — the token wasn't minted from client credentials.
- `401` — `unauthorized` — the platform access token is missing or expired. Exchange your client credentials for a fresh one.
- `404` — `connection_not_found` — no connection exists for that user under your client.
- `409` — `user_conflict` — the email on file in your organization belongs to a different account. Contact support.
- `422` — `document_rejected` — the image couldn't be processed; ask the user to retake the photo. `document_expired` — the document itself is expired; ask for a valid one. Either may include a `warnings` array with actionable feedback.
- `502` — `verification_error` — the step failed downstream. Try again.

---

[API](https://skmtc.net/agentcard/apis/agentcard-api.md) · [All operations](https://skmtc.net/agentcard/apis/agentcard-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/agentcard/agentcard-api/versions/638d12c8303f/schema)
