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

# You own KYC

> What IB ownership of end-user KYC means today, what we still require on every participant, and why to enable document verification now.

You own the identity decision for your own customer. **That does not yet mean we skip ours**, and building your onboarding funnel on the assumption that it does is the most expensive mistake available on this page.

<Info>
  Prerequisites:

  * a working access token,
  * the `kyc:write` scope granted against your client — scopes are granted server-side and cannot be
    requested on the token exchange,
  * both firm strings and the difference between them — see
    [Firms, participants and accounts](/identity).
</Info>

## The recorded position, in one paragraph

**The IB owns end-user KYC, and an IB that is licensed may be able to remit against its own KYC policy, subject to AML sign-off. No timeframe is committed for that.** Everything else on this page follows from those two sentences, and they are the entirety of what has been decided. This answer has only ever existed in Slack; this page is the first time it has been written down for partners.

## What we still require, regardless

Until a reliance model is in force for your firm, every participant you send us goes through our identity path as well as yours.

* Our check is **Socure-backed. We run it and we make the decision** on the participant-provisioning path. You cannot override it, appeal it, or supply a decision.
* `decision`, `status` and `subStatus` on our response are **informational, not control flow.** Log them; do not branch on them.
* Branch on three things instead: is there a `docv` object in the response, did a terminal webhook arrive, and is `participantId` non-empty.
* **Only terminal events fire:** `kyc.approved`, `kyc.rejected` and `webhook.test`. There is no review event, so non-terminal states must be polled.
* **`participantId` can come back empty on an accept while provisioning finishes.** Observed gaps run from \~500 ms to **26 minutes**. Wait for the `kyc.approved` webhook before you enable trading.
* **One SSN maps to exactly one exchange account, platform-wide.** A trading account ID is derived from the customer's SSN. There is **no re-KYC, reset or PII-update path** — a customer whose SSN is already in use cannot be re-verified by you.
* **Our decline reasons are not exposed to you.** Retrieving one currently requires a human to open a Socure thread, and there is no internal procedure for it either. You cannot tell your customer why we declined them.
* `"In Review"` is a real `subStatus` value that is **not in the documented set** (`none` / `docv_required` / `pending`). A `switch` over the documented three falls through on it.

<Warning>
  **What changes on the day a reliance model is approved is not published.**

  Nobody has stated whether reliance removes our check, reduces it, or changes the payload you send.
  Do not design two onboarding code paths on the assumption that the second one is a small change.
  Ask for the answer in writing before you plan a migration to it.
</Warning>

## Enable document verification now. Do not wait for the reliance model.

This is the practical advice on record, and it is the one thing on this page you can act on today.

**Set `docv_eligible: true` on every submission.** It is what converts a review case into a self-service document upload. If you leave it off, review cases go to **manual review, 1–2 business days**, and your signup funnel absorbs that delay on every one of them.

The reasoning is a sequencing argument, not a technical one: the delay you avoid by enabling document verification is available immediately, and the delay you would avoid by relying on your own KYC has **no committed timeframe**. A funnel designed around a reliance model that is not in force is a funnel with a two-day hole in it.

Three details that decide whether document verification works for you:

| Detail                                                    | Value                                                        | Consequence                                                                              |
| --------------------------------------------------------- | ------------------------------------------------------------ | ---------------------------------------------------------------------------------------- |
| Digital Intelligence `session_token`                      | Optional on paper. **Treat it as required**                  | It is what keeps the review rate down. Without it, more of your customers land in review |
| `sdkKey` in the document-verification response            | **Always empty**                                             | Do not build an SDK initialisation path that waits on it                                 |
| `GET /v1/kyc/status` after the customer submits documents | Keeps returning the `docv` object for roughly **14 seconds** | Do not treat a still-present `docv` object as "not submitted" inside that window         |

<Warning>
  **Document verification has no published session lifecycle.**&#x20;
  There is no documented TTL for `docvTransactionToken` or `docv.url`, no documented way to re-issue
  one after a customer abandons the flow, and no documented behaviour when a session expires
  un-submitted. The observed behaviour on an expired session is `decision: ACCEPT` with
  `status: CLOSED` and an **empty `participantId`**, which is a bug. Do not treat that shape as an
  approval.
</Warning>

## What you may share with us, and under what agreement

Two different sharing relationships apply, and partners conflate them.

**Your customer's identity payload comes to us under your IB Agreement.** You send it on the KYC path; we run our check on it. Field mechanics you will hit immediately:

* Requests are `snake_case`, REST responses are `camelCase`, and webhook payloads are `snake_case`. One object graph, three conventions.
* `external_id` is capped at **49 characters**. `postal_code` is **five digits**.
* `{"code": 9, "message": "user already provisioned with a different SSN"}` returns as **HTTP 400**, not the documented 409.

**Your customer's agreement acceptance is with QCX LLC and QC Clearing LLC, not with you.** Four end-user documents are issued by those entities and hosted on `polymarketexchange.com`, under requirements R-1 to R-6. **R-3 forbids hosting modified, excerpted or re-rendered copies** — link to them, do not re-serve them.

<Warning>
  **The end-user agreement version identifier is not settled, and it is compliance-relevant.**

  Two incompatible formats are live across our own pages. Do not hard-code a version string until
  your integration lead confirms which one your submissions must carry.
  There is also no `agreement.version` discovery endpoint, no rotation policy, no grace period and no
  re-acceptance mechanism for already-approved customers.
</Warning>

<Warning>
  **What evidence of your own KYC programme we require, and where it goes, is not published.**

  Until that is answered: do not put customer PII or SSNs in the shared Slack channel, for any reason,
  including debugging. Quote your `external_id` and the `participantId` instead.
</Warning>

## Contrast with the ISV position

If you or your vendor have read ISV material, this table is what differs. The ISV column is correct for an ISV and wrong for you.

|                                    | ISV                                                                                                                  | You, as an IB                                                                 |
| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
| Who owns the end-user KYC decision | **We do.** The ISV collects the payload; we run Socure and decide                                                    | **You do**, for your own customer                                             |
| Can rely on its own KYC            | **No.** Without an IB licence every participant is verified through Socure again, however well the ISV verified them | **Possibly, once licensed** — subject to AML sign-off, no timeframe committed |
| What runs today                    | Our check, on every participant                                                                                      | **Our check, on every participant** — the same, until reliance is in force    |
| Decline reasons                    | Not exposed                                                                                                          | Not exposed                                                                   |
| Agreement covering the payload     | Vendor Connectivity Agreement + Fee Agreement                                                                        | **IB Agreement**                                                              |
| End-user legal documents           | The four QCX LLC / QC Clearing LLC documents                                                                         | The same four, unchanged                                                      |

The row readers get wrong is the third one. **"You own KYC" and "our check still runs on every participant" are both true at the same time**, and they will stay both true until a reliance model is signed off for your firm.

## Defer KYC to the point of trading

Do not put KYC in your signup form. Trigger it when the customer first tries to do something that requires an exchange account.

Three numbers drive this, and none of them changes because you are an IB:

* Manual review takes **1–2 business days**, so a KYC gate at signup abandons every review case at the front door.
* `participantId` can be empty for **up to 26 minutes** after an approval, so "signup complete" cannot mean "tradable".
* Our rejections are terminal and carry **no partner-visible reason**, so a customer rejected at signup has nothing to fix and no path back.

## What can go wrong

| Symptom                                                                | Cause                                                         | What you do                                                                     |
| ---------------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| A customer you verified yourself is declined by us                     | Our check still runs; no reliance model is in force           | Nothing on your side fixes it. Do not promise customers your approval is final  |
| Your funnel loses two days per review case                             | `docv_eligible: true` was not set                             | Set it on every submission                                                      |
| More customers in review than you expected                             | Digital Intelligence `session_token` was omitted              | Send it. It is optional on paper and required in practice                       |
| A `switch` on `subStatus` falls through                                | `"In Review"` is a real value outside the documented set      | Add a default branch that polls rather than failing                             |
| `decision: ACCEPT`, `status: CLOSED`, empty `participantId`            | An abandoned document-verification session — a known bug      | Do not enable trading. Raise it with the `external_id`                          |
| Trading enabled for a customer with no account                         | You gated on `decision` instead of the `kyc.approved` webhook | Gate on the webhook and a non-empty `participantId`                             |
| `HTTP 400` naming a different SSN                                      | That SSN already maps to an exchange account                  | One SSN is one account platform-wide. There is no re-KYC path; raise it         |
| `PERMISSION_DENIED` on the KYC path                                    | `kyc:write` not granted, or your token predates the grant     | Re-mint the token after the grant                                               |
| `{"code":12,"message":"unknown service connamara.ep3.v1beta1.KYCAPI"}` | You called KYC over gRPC                                      | Use the REST path. There is no supported gRPC KYC surface                       |
| Fields you sent are ignored                                            | Your client camel-cased the request body                      | Requests are `snake_case`; responses are `camelCase`. Serialize them separately |

## Next

[Funds handling](/funds)
