---
title: "Submit KYC"
method: POST
path: "/v1/phone-numbers/kyc"
tags: ["Phone Numbers"]
---

# Submit KYC

`POST /v1/phone-numbers/kyc`

Submit the end customer's KYC (textual values, uploaded documents,
address) for a Tier 3/4 country. Documents are streamed straight to the
number provider and are not stored by Zernio. Builds + submits a
regulatory requirement group and claims a pending_regulatory slot; the
number is ordered + activated once the provider approves (asynchronous).
A customer may hold several same-country numbers in review at once; a
double-submit of the SAME attempt is deduped via `submissionId`.

For an ID-card document requirement, carriers commonly require BOTH sides:
combine the front and back into a single file before uploading (the
dashboard does this automatically). A one-sided ID is a common decline
reason; fix it via POST /v1/phone-numbers/{id}/remediate.

Before submitting, call GET /v1/phone-numbers/availability to
check the country has deliverable inventory and, for geographic-match
countries, which area the address must be in — otherwise the submission
can pass review yet never be assignable a number.

## Request body

- object
  - `profileId` string, required
  - `country` string, required
  - `submissionId` string — Idempotency token for this submission attempt. Once the number has been ordered, a retry with the same token returns that same number instead of ordering another. A submission that fails before the number is ordered releases the token, so you can correct your details and re-submit with it. Omit it and every call provisions a new number.
  - `quantity` integer — Provision several same-country numbers from one submission (1-5). The single verification covers all of them; each number is billed only when it activates. Numbers that fail to order are skipped (best-effort). With `areaCode`, a quantity above that area's live stock is rejected with a 400.
  - `reuse` boolean — Reuse a prior approved verification for this country (skips document/field collection; places the order immediately).
  - `reuseOptionId` string — Which reusable verification to use (GET reusable.options[].id). The unambiguous selection key. Omitted = the approved default. No match = 409.
  - `reuseFrom` string — Legacy fallback for `reuseOptionId`: the source phone number (GET reusable.options[].fromPhoneNumber). Ambiguous when a number labels two verifications — prefer `reuseOptionId`. Omitted = the approved default. No match = 409.
  - `areaCode` string — Area code (NDC) the number must be in. Hard constraint: an empty area pool fails with 409 code AREA_CODE_UNAVAILABLE instead of ordering from another area. Omit for any area. Options come from GET /v1/phone-numbers/availability (areaOptions); the purchase 202 kycUrl echoes the areaCode picked at purchase time so it can be passed here.
  - `endUserFirstName` string — End user's legal first name. Required when the country has an action/ID-verification (Onfido) requirement.
  - `endUserLastName` string — End user's legal last name. Same condition as endUserFirstName.
  - `values` object — requirementId → textual value
  - `documents` union[] — One per document requirement. Each is EITHER inline base64 OR a `documentId` returned by POST /v1/phone-numbers/kyc/upload-document (use the upload endpoint for large files to stay under the request-size limit).
    - union
      - object
        - `requirementId` string, required
        - `filename` string, required
        - `base64` string, required
      - object
        - `requirementId` string, required
        - `documentId` string, required — Id from POST /v1/phone-numbers/kyc/upload-document.
  - `address` object
    - `requirementId` string
    - `country_code` string
    - `business_name` string
    - `first_name` string
    - `last_name` string
    - `street_address` string
    - `extended_address` string — Address complement: apartment, suite, unit, or the quadra/lote used in some countries. Optional. Does not substitute for a building number on street_address.
    - `locality` string
    - `administrative_area` string
    - `postal_code` string

## Response `200`

KYC submitted (or already submitted); number pending review.

- object
  - `status` 'kyc_submitted' | 'kyc_reused' | 'kyc_already_submitted'
  - `phoneNumber` object — The first/primary number, kept at the top level for backward compatibility. See `numbers` for the full set when `quantity` > 1.
    - `id` string
    - `status` string
    - `country` string
  - `numbers` object[] — Every number provisioned from this submission. Length equals the requested `quantity` on full success (fewer if some orders failed; best-effort). The first element mirrors `phoneNumber`.
    - `id` string
    - `status` string
    - `phoneNumber` string
    - `country` string

## Other responses

- `400` — Validation error (e.g. address not in-country, file too large)
- `401` — Unauthorized
- `409` — Either reuse was requested but no prior approved verification exists for this country, or the requested areaCode has no deliverable inventory right now (code: area_code_unavailable; pick another area and resubmit).

---

[API](https://skmtc.net/zernio/apis/zernio-api.md) · [All operations](https://skmtc.net/zernio/apis/zernio-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/zernio/zernio-api/revisions/15e893e69e8c/schema)
