Skip to main content
Before you can issue a card, every applicant must pass two checks. Apocor orchestrates both — you never integrate with the card program or identity vendors directly.
LayerWho decidesAPI signal
Tenant KYCYou (the integrator)statusAPPROVED
Issuer KYCThe card program behind ApocorissuerKycReadytrue
status: APPROVED alone is not enough to issue cards. You must also wait for issuerKycReady: true. Card issuance returns ISSUER_KYC_INCOMPLETE otherwise.

What gets shared?

You never upload passports, selfies, or PDFs to Apocor. Identity providers support a share token — a short-lived credential that lets the card program pull an already-verified profile. Apocor accepts that token and forwards it upstream. Raw documents stay inside the identity provider.

Get your integration settings

cURL
curl -s 'https://sandbox.apocor.ai/v1/kyc/config' \
  -H 'Authorization: Bearer YOUR_TOKEN'
{
  "data": {
    "hostedVerificationAvailable": true,
    "shareVerificationAvailable": true,
    "shareRecipientId": "celeriz.com_139320",
    "sumsubWebhookMode": "apocor",
    "sumsubWebhookUrl": "https://sandbox.apocor.ai/v1/webhooks/sumsub",
    "verificationSync": "POST /v1/webhooks/sumsub on your Core API host, or POST /v1/applicants/{id}/submit to sync and hand off"
  }
}
FieldMeaning
hostedVerificationAvailableYou can use POST /v1/applicants/{id}/kyc-session and embed Apocor’s hosted widget
shareVerificationAvailableBYOK share tokens are accepted via kyc-share
shareRecipientIdApocor’s Sumsub client id — use as the share-token recipient in your identity provider (BYOK only). Never use the card-program or upstream partner id.
sumsubWebhookModeapocor = Core API /v1/webhooks/sumsub (target); seismic = legacy Railway seismic-cards
sumsubWebhookUrlExact URL to register in the Sumsub dashboard for this environment
Sumsub webhooks (target): register Sumsub against the Core API URL from sumsubWebhookUrl (POST /v1/webhooks/sumsub). Set SUMSUB_WEBHOOK_MODE=apocor and APOCOR_PUBLIC_API_URL on the API host. After the hosted widget completes, call POST /v1/applicants/{id}/submit to sync tenant status and trigger issuer handoff (webhooks may also update status). Use GET …/kyc-status to poll issuer progress. Legacy seismic mode (/webhooks/sumsub on seismic-cards) is migration-only — see Webhooks.

Option A — Apocor-hosted verification

Best when you don’t run your own Sumsub (or similar) account. Apocor hosts the widget and handles issuer handoff automatically.
1

Create an applicant

cURL
curl -s -X POST 'https://sandbox.apocor.ai/v1/applicants' \
  -H 'Authorization: Bearer YOUR_TOKEN' -H 'Content-Type: application/json' \
  -d '{
    "type": "PERSON",
    "email": "[email protected]",
    "data": {
      "firstName": "Jane",
      "lastName": "Doe",
      "country": "US",
      "addressLine1": "123 Main St",
      "city": "New York",
      "state": "NY",
      "postalCode": "10001"
    }
  }'
2

Start a verification session

cURL
curl -s -X POST 'https://sandbox.apocor.ai/v1/applicants/app_abc123/kyc-session' \
  -H 'Authorization: Bearer YOUR_TOKEN'
Response includes accessToken — pass it to the hosted WebSDK in your frontend. externalUserId is the Apocor applicant id.
3

User completes the widget

When verification succeeds in the widget, call POST /v1/applicants/{id}/submit to sync tenant status and trigger issuer handoff. With SUMSUB_WEBHOOK_MODE=apocor, Sumsub also posts to POST /v1/webhooks/sumsub on Core API — still call submit so issuer handoff is not delayed if the webhook is slow.
4

Confirm issuer readiness

cURL
curl -s 'https://sandbox.apocor.ai/v1/applicants/app_abc123/kyc-status' \
  -H 'Authorization: Bearer YOUR_TOKEN'
Wait until issuerKycReady is true, then create a cardholder and issue a card.
You can also call POST /v1/applicants/{id}/submit after the widget completes to poll tenant status and trigger issuer handoff in one step.

Option B — Bring your own identity provider (BYOK)

Best for regulated companies that already run their own Sumsub (or compatible) environment. You never use Apocor’s hosted widget.
1

Create an applicant in Apocor

Save the returned id — you will use it as externalUserId in your identity provider.
2

Verify the user in your provider

Run your existing KYC flow. Set externalUserId to the Apocor applicant id so records stay linked.
3

Generate a share token

Call your provider’s share-token API with:
  • Applicant id — from your provider
  • RecipientshareRecipientId from GET /v1/kyc/config (Apocor’s id, not the card issuer)
Example (Sumsub):
POST /resources/accessTokens/-/shareToken?applicantId={id}&forClientId={shareRecipientId}
Apocor imports the shared verification and forwards it to the card program internally. The token expires quickly (typically ~10 minutes). Generate it immediately before calling Apocor.
4

Submit the token to Apocor

cURL
curl -s -X POST 'https://sandbox.apocor.ai/v1/applicants/app_abc123/kyc-share' \
  -H 'Authorization: Bearer YOUR_TOKEN' -H 'Content-Type: application/json' \
  -d '{
    "sumsub_share_token": "YOUR_SHARE_TOKEN",
    "kyc_vendor_ref": "your-provider-applicant-id",
    "status": "APPROVED"
  }'
FieldRequiredDescription
sumsub_share_tokenYesShort-lived share token from your provider
kyc_vendor_refNoYour provider’s applicant id (stored internally)
statusRecommendedSet to APPROVED to attest verification in the same request
5

Poll until ready

cURL
curl -s 'https://sandbox.apocor.ai/v1/applicants/app_abc123/kyc-status' \
  -H 'Authorization: Bearer YOUR_TOKEN'
Issue cards only when issuerKycReady is true.
BYOK tenants do not need Apocor-hosted verification credentials. They only need an Apocor API key and the shareRecipientId from /v1/kyc/config.

Applicant response fields

Every applicant includes white-labeled issuer fields:
{
  "data": {
    "id": "app_abc123",
    "status": "APPROVED",
    "issuerKycStatus": "SUBMITTED",
    "issuerKycReady": false
  }
}
issuerKycStatusMeaning
PENDINGIssuer account exists; identity not submitted yet
SUBMITTEDShare token forwarded; issuer processing
APPROVEDIssuer accepted identity — cards can be issued
REJECTEDIssuer declined identity
UNKNOWNCould not determine status — call kyc-status to refresh

Endpoints summary

MethodPathPurpose
GET/v1/kyc/configIntegration settings + share recipient id
POST/v1/applicantsCreate applicant
POST/v1/applicants/{id}/kyc-sessionHosted widget session (Option A)
POST/v1/applicants/{id}/submitPoll tenant KYC; when approved, provision issuer account and trigger handoff
POST/v1/applicants/{id}/kyc-shareSubmit BYOK share token (Option B)
GET/v1/applicants/{id}/kyc-statusPoll issuer KYC fields only — does not submit share tokens

Troubleshooting

SymptomLikely causeFix
issuerKycReady stays false after mock sandbox KYCMock verification does not produce real share tokensUse hosted verification or BYOK share tokens against a live environment
ISSUER_KYC_INCOMPLETE on card issueIssuer still processing or share token never submittedCall POST …/submit or kyc-share, then poll GET …/kyc-status until issuerKycReady is true
Card issue fails with address / state errorResidential address in KYC is missing state (state of birth alone is not enough)Re-run verification with full address including state/subdivision, then re-submit issuer handoff
Share token rejectedWrong shareRecipientId, reusable KYC not enabled, or token not addressed to ApocorConfirm GET /v1/kyc/config returns Apocor’s client id; ask Sumsub to enable sharing tenant → Apocor → issuer
KYC_NOT_APPROVED on kyc-shareTenant status not approvedInclude "status": "APPROVED" when attesting BYOK verification
See Error codes for the full list of error.code values.

Next steps

Applicants

Applicant lifecycle and statuses

Cards

Issue cards after issuer KYC is ready

Quickstart

End-to-end sandbox walkthrough

API Reference

Try endpoints in the playground