Skip to main content
BETA — SUBJECT TO CHANGE. This API is in beta and may change without notice.
POST /v1/kyc/start is the primary endpoint for onboarding. You submit the participant’s identity data (optionally with a Socure Digital Intelligence session_token), and the response tells you which of the four outcomes applies.

Start verification

POST /v1/kyc/start
{
  "external_id": "your-internal-user-id-123",
  "ssn": "123456789",
  "first_name": "Jane",
  "middle_name": "",
  "last_name": "Smith",
  "date_of_birth": "1990-06-15",
  "email": "jane.smith@example.com",
  "phone_number": "+12125551234",
  "address": {
    "address_line_1": "123 Main St",
    "address_line_2": "Apt 4B",
    "city": "New York",
    "state": "NY",
    "postal_code": "10001",
    "country": "US"
  },
  "agreement": {
    "version": "PMX.ISV.v1.0",
    "signed_at": "2026-04-24T14:30:00Z"
  },
  "session_token": "{socure_di_session_token}",
  "ip_address": "203.0.113.42"
}

Request fields

FieldTypeRequiredDescription
external_idstringYesYour internal identifier for this participant. Max 49 chars, unique per firm. Echoed back in all responses and webhooks.
ssnstringYesSocial Security Number, digits only (no dashes)
first_namestringYesLegal first name (max 50)
middle_namestringNoLegal middle name
last_namestringYesLegal last name (max 50)
date_of_birthstringYesYYYY-MM-DD
emailstringYesEmail address
phone_numberstringYesE.164 format (e.g. +12125551234)
addressobjectYesResidential address (see below)
agreement.versionstringYesVersion of the participant agreement accepted. Confirm the current value with the onboarding team — do not hardcode.
agreement.signed_atstringYesUTC ISO-8601 timestamp of acceptance
session_tokenstringNoSocure Digital Intelligence token — strongly recommended
ip_addressstringYesParticipant’s IP address

Address object

FieldRequiredDescription
address_line_1YesStreet address
address_line_2NoApartment, suite, unit
cityYesCity
stateYesTwo-letter US state code
postal_codeYesZIP code
countryNoTwo-letter country code; use US. Not validated platform-side — passed to the verification provider.

Decision matrix

The response’s status object carries decision, status, subStatus, and externalId. Together with the presence of a docv object, the synchronous response indicates the path:
decisiondocv presentMeaning
ACCEPT / APPROVEDNoApproved — provisioning runs (often asynchronously; see below)
REVIEWYesDocument verification — direct the participant to docv.url or the SDK
REVIEWNoManual compliance review — inform the participant to wait
RESUBMITNoParticipant must resubmit documents
REJECTNoRejection — no account created
Treat decision / status / subStatus as informational, not control flow. These values are passed through from the verification provider and the provider may emit values beyond the set above. Key your logic off the docv presence for the synchronous step and off the webhook event_type / status (kyc.approved / kyc.rejected) for the terminal outcome.

Approval

The most common path. Note that approval is asynchronous even when the decision is instant: a successful POST /v1/kyc/start may return a non-terminal status while backend account provisioning completes in the background. participantId is often empty on this response — you learn the final values from the kyc.approved webhook and from a later GET /v1/kyc/status read.
You send snake_case, but REST responses come back in camelCase (protobuf JSON naming) — e.g. externalId, participantId. See Field naming.
{
  "status": {
    "decision": "ACCEPT",
    "status": "ON_HOLD",
    "subStatus": "Accept",
    "externalId": "your-internal-user-id-123"
  },
  "participantId": ""
}
Once provisioning completes, GET /v1/kyc/status (and the webhook) return the engine-neutral identifiers:
{
  "status": {
    "decision": "ACCEPT",
    "status": "CLOSED",
    "subStatus": "Accept",
    "externalId": "your-internal-user-id-123"
  },
  "participantId": "firms/ISV-Participant-YourFirmID/users/your-internal-user-id-123"
}
Automatic provisioning. On approval, Polymarket US automatically creates the participant’s trading identity and account — there is no separate account-creation step (see Onboard Participants). Because provisioning is asynchronous, wait for the webhook (or a populated participantId from status) before enabling trading rather than assuming the start response carries it.
Which field identifies the participant when you trade? Use participantId (the webhook calls the same value provisioned_participant) as the x-participant-id header — that is who the order is for, and the only provisioning identifier you need. Your externalId is your reference only and is never sent to identify the participant. See Using these identifiers to trade.

Document verification (DocV)

When Socure can’t verify from the submitted data alone, the response includes a docv object. Detect it by the presence of a non-empty docv field (with decision: "REVIEW").
{
  "status": {
    "decision": "REVIEW",
    "status": "ON_HOLD",
    "subStatus": "Document Request Initiated",
    "externalId": "your-internal-user-id-123"
  },
  "docv": {
    "url": "https://verify.socure.com/doc/abc123",
    "qrCode": "data:image/png;base64,...",
    "docvTransactionToken": "dt_abc123...",
    "eventId": "evt_456",
    "sdkKey": "a0a1869f-cf3e-4acb-919a-62b9fef30e3f"
  }
}
FieldUse
urlRedirect or embed for browser-based document upload
qrCodeBase64 PNG — display on desktop for mobile handoff
docvTransactionTokenLaunch token for the Socure mobile SDK
sdkKeyPublic key to initialise the Socure mobile SDK
eventIdSocure event identifier
You can direct the participant three ways — a web URL, a QR code for desktop→mobile handoff, or the native Socure SDK. Document capture is fully handled by Socure’s UI; you don’t build capture logic yourself.
The SDK onSuccess callback (or completing the web upload) only means the participant submitted documents — not that they were approved. After submission, await the kyc.approved webhook or poll GET /v1/kyc/status.
After the participant completes DocV, Socure notifies Polymarket US, which provisions the account (on approval) and sends you the final-decision webhook.

Manual compliance review

If Socure can’t make a determination and no DocV path is available, the response is REVIEW/OPEN with no docv field. The Polymarket US compliance team reviews the case.
{
  "status": {
    "decision": "REVIEW",
    "status": "OPEN",
    "subStatus": "In Review",
    "externalId": "your-internal-user-id-123"
  }
}
Tell the participant their application is under review (typically 1–2 business days) and await the webhook. Implement the polling fallback for resilience.

Rejection

{
  "status": {
    "decision": "REJECT",
    "status": "CLOSED",
    "subStatus": "Reject",
    "externalId": "your-internal-user-id-123"
  }
}
No account is created. Rejection can also occur after DocV or after a manual review, in which case you receive a kyc.rejected webhook.

Check status

Poll the current status with the external_id you submitted. The response mirrors the start response, including participantId once provisioned.
GET /v1/kyc/status?external_id=your-internal-user-id-123
Partner-relevant status.status values:
status.statusMeaning
OPENIn progress (for example, manual review)
REVIEW / IN REVIEWUnder review
ON_HOLDNon-terminal provider status (for example, an instant approval while provisioning completes, or a document-upload step)
CLOSEDTerminal — check decision
Values are passed through from the verification provider and may extend beyond this set. Use a populated participantId (and the webhook) as your signal that the participant is ready to trade — not a specific status string.

Error handling & polling

HTTPgRPCMeaningAction
200OKSuccessProcess the response
400INVALID_ARGUMENTMissing or invalid fieldFix the request
401UNAUTHENTICATEDInvalid/expired tokenRefresh the token
403PERMISSION_DENIEDFirm lacks KYC API accessContact the onboarding team
409ALREADY_EXISTSParticipant already has approved KYCFetch via GET /v1/kyc/status
429Throttled at the edge before reaching the APIRetry with backoff (honor Retry-After)
500INTERNALGateway errorRetry with exponential backoff
external_id is idempotent. Re-submitting POST /v1/kyc/start for a participant who already passed KYC returns 409 ALREADY_EXISTS. Handle it by fetching the existing status rather than treating it as an error.
Prefer webhooks over polling. As a fallback, poll GET /v1/kyc/status every 5–10 seconds for up to 5 minutes after DocV submission. For manual-review cases, poll on a longer cadence (e.g. every 30 minutes for up to 2 business days) and notify the participant asynchronously.

Outcome flowchart

Sandbox testing

In sandbox, Socure decides the outcome from the name and email you submit:
OutcomeHow to trigger
RejectionSet email to reject@example.com
ReviewSet first_name to Paulina and last_name to Gizela (with any email other than reject@example.com)
ApprovalUse any other name / email combination
Use these placeholder agreement values in sandbox (the onboarding team provides production values):
FieldSandbox value
agreement.versionPMX.ISV.SANDBOX.v1.0
agreement.signed_atCurrent UTC timestamp

Next steps

Webhooks

Receive the async approval/rejection notifications.

Digital Intelligence

Lower your REVIEW rate with the session_token.