Onboarding API

Swarm's Onboarding API lets you embed KYC (Know Your Customer) identity verification and Source of Funds (SoF) checks directly into your own application. When a user passes verification, they receive an on-chain NFT permission token — the credential required to trade on Swarm's platform.

This is a RESTful APIs working with JSON payloads over HTTPS. All requests must include Content-Type: application/json.

Base URL: https://api.app.swarm.com

OpenAPI spec: docs.onboarding.swarm.com

Note: If you are looking to complete KYC as an end user rather than integrate the API, visit dotc.eth.limo to go through the KYC flow directly. The content below is for developers integrating the Onboarding API into their own applications.


Authentication

The Onboarding API uses Bearer token authentication (JWT).

Include your token in the Authorization header on every request:

Authorization: Bearer

Your source_key — a unique identifier assigned to your organisation by Swarm — is also required as a query parameter when initiating onboarding. Contact the Swarm team to obtain your source_key.

CredentialHow to provide itHow to obtain it
JWT tokenAuthorization: Bearer <token> headerIssued by your authentication flow
source_keyQuery parameterAssigned by Swarm — contact the team

Onboarding flow

A typical integration follows this sequence:

  1. Initiate onboarding → GET /onboarding/external Pass the user's wallet address and your source_key Returns a kyc_sumsub_access_token for launching the KYC SDK
  2. Launch KYC Select in your UI Use the access token to open the Sumsub identity verification widget The user submits their identity documents
  3. Submit Source of Funds → POST /sof/verifications/external Your app collects SoF details via a form and submits them to the API
  4. Poll for status → GET /onboarding/external Call the same initiate endpoint to check kyc_passed and sof_passed
  5. User receives NFT permission token on-chain They can now trade on Swarm

Endpoints

MethodPathDescription
GET/onboarding/externalInitiate a new onboarding session, or check an existing one
POST/sof/verifications/externalSubmit Source of Funds information for a user


Initiating KYC + SoF

Use GET /onboarding/external to start the onboarding process for a user. This endpoint serves a dual purpose: it initiates a new session when called for the first time, and returns the current verification status on subsequent calls.

Endpoint: GET https://api.app.swarm.com/onboarding/external

Authentication: BearerAuth (JWT) + source_key query parameter

Query parameters

ParameterTypeRequiredDescription
addressstringWallet address of the user being onboarded
source_keystringYour organisation's unique source key, assigned by Swarm

Example request

http GET https://api.app.swarm.com/onboarding/external?address=0xAbC123...&source_key=your-source-key Authorization: Bearer Content-Type: application/json

Response — 200 Success

json { "data": { "type": "external_onboarding_status", "attributes": { "status": "in_progress_user", "kyc_passed": false, "kyc_sumsub_access_token": "string", "sof_passed": false } } }

FieldTypeDescription
statusstringOverall onboarding status — see status values below
kyc_passedbooleanWhether identity verification has been approved
kyc_sumsub_access_tokenstringShort-lived token for launching the KYC widget in your UI
sof_passedbooleanWhether Source of Funds verification has been approved

Status values

ValueMeaning
in_progress_userAwaiting user action — use the kyc_sumsub_access_token to launch the KYC widget
in_progress_reviewDocuments submitted; under review by the Swarm compliance team
approvedKYC and SoF both passed; NFT permission token issued
rejectedVerification rejected — user should be informed

Launching the KYC widget

When the response includes a kyc_sumsub_access_token, use it to launch the KYC Select widget (powered by Sumsub) in your application. This widget handles identity document collection, selfie capture, and liveness checks on your behalf.

javascript // Example: initialise Sumsub SDK with the access token const snsWebSdk = require('@sumsub/websdk');

snsWebSdk.init( accessToken, // kyc_sumsub_access_token from the API response () => fetchNewToken(), // token expiry handler — re-call GET /onboarding/external ) .withConf({ lang: 'en' }) .withOptions({ addViewportTag: false, adaptIframeHeight: true }) .on('idCheck.onStepCompleted', (payload) => { console.log('Step completed', payload); }) .on('idCheck.onApplicantSubmitted', () => { // User has submitted — poll GET /onboarding/external for status }) .build();

Refer to the Sumsub Web SDK documentation for full widget integration details.

Error responses

StatusDescription
400Bad request — check that address and source_key are present and correctly formatted
500Internal server error


Submitting Source of Funds

Use POST /sof/verifications/external to submit Source of Funds and suitability information for a user. Your application should collect this data via a form and submit it once the user completes the KYC identity step.

Endpoint: POST https://api.app.swarm.com/sof/verifications/external

Authentication: BearerAuth (JWT)

Request body

json { "data": { "type": "sof_external_verification_form", "attributes": { "address": "string", "terms_accepted": true, "answers_sof": { "amount": 150000, "source_of_income": "Salary", "show_other_source": true, "other_source": "Heritage", "invest_knowledge": "Poor/none", "annual_income": "Under $200,000", "net_worth": "Under $500,000", "document_url": "https://sof-verifications.s3.eu-central-1.amazonaws.com/00896053-fa02-4856-8af8-8fae6e332e4b.csv" }, "answers_suitability": { "knowledge_stocks": "Yes", "knowledge_bonds": "Yes", "school_qualification": "Economic secondary", "held_positions": "Yes", "risk_comfortable": "Yes", "investment_goal": "Provision for old age", "support_issues": "Yes" } } } }

Field reference

Top-level attributes:

FieldTypeRequiredDescription
addressstringUser's wallet address
terms_acceptedbooleanUser has accepted the terms and conditions
answers_sofobjectSource of Funds answers
answers_suitabilityobjectSuitability assessment answers

answers_sof fields:

FieldTypeDescription
amountnumberIntended investment amount in USD
source_of_incomestringPrimary source of income (e.g. "Salary", "Business income", "Investments")
show_other_sourcebooleanWhether an additional income source applies
other_sourcestringDescription of the additional income source (if show_other_source is true)
invest_knowledgestringSelf-reported investment knowledge level (e.g. "Poor/none", "Basic", "Good", "Expert")
annual_incomestringAnnual income bracket (e.g. "Under $200,000", "$200,000–$500,000", "Over $500,000")
net_worthstringNet worth bracket (e.g. "Under $500,000", "$500,000–$1,000,000", "Over $1,000,000")
document_urlstringURL to a supporting document uploaded to S3 (if required)

answers_suitability fields:

FieldTypeDescription
knowledge_stocksstringHas knowledge of stocks ("Yes" / "No")
knowledge_bondsstringHas knowledge of bonds ("Yes" / "No")
school_qualificationstringHighest educational qualification (e.g. "Economic secondary", "University")
held_positionsstringHas held relevant professional positions ("Yes" / "No")
risk_comfortablestringComfortable with investment risk ("Yes" / "No")
investment_goalstringPrimary investment objective (e.g. "Provision for old age", "Capital growth", "Income")
support_issuesstringHas received investment support or advice ("Yes" / "No")

Responses

StatusDescription
204Created — SoF information received and submitted for verification
401Unauthorised — JWT token is invalid or expired
403Forbidden — source_key is not authorised for this operation
409Conflict — a SoF submission already exists for this address
500Internal server error

Error response body (4xx/5xx)

json { "errors": [ { "title": "Unauthorized", "detail": "Session token is invalid. It either has expired or is corrupted. Please log in and obtain a new one.", "status": 401, "code": "session_token_not_found" } ] }

When to call this endpoint

Submit SoF information after the user has completed the KYC identity step in the Sumsub widget. The recommended flow is:

  1. Listen for the idCheck.onApplicantSubmitted event from the Sumsub widget
  2. Present your Source of Funds form to the user
  3. On form submission, call POST /sof/verifications/external
  4. On 204, proceed to polling for status

If the SoF information is incomplete or fails validation, the endpoint returns the current status as in_progress_user and the user receives an email prompting them to resubmit. See Resubmitting Documents below.



Checking Verification Status

Use GET /onboarding/external — the same endpoint used to initiate onboarding — to check the current status of a user's KYC and SoF verification.

Endpoint: GET https://api.app.swarm.com/onboarding/external

Query parameters

ParameterTypeRequiredDescription
addressstringWallet address of the user
source_keystringYour organisation's source key

Polling approach

The API does not push status updates — your application needs to poll. Call GET /onboarding/external at a reasonable interval (e.g. every 30–60 seconds) while the user's application is under review.

javascript async function pollOnboardingStatus(address, sourceKey, bearerToken) { const response = await fetch( https://api.app.swarm.com/onboarding/external?address=${address}&source_key=${sourceKey}, { headers: { 'Authorization': Bearer ${bearerToken}, 'Content-Type': 'application/json' } } );

const { data } = await response.json(); const { status, kyc_passed, sof_passed } = data.attributes;

if (kyc_passed && sof_passed) { // User is fully verified — proceed return 'approved'; }

return status; }

Reading the response

Scenariokyc_passedsof_passedstatusRecommended action
Just initiatedfalsefalsein_progress_userLaunch KYC widget using kyc_sumsub_access_token
KYC submitted, SoF pendingfalsefalsein_progress_userPresent SoF form
Both submitted, under reviewfalsefalsein_progress_reviewShow "under review" state in your UI
KYC passed, SoF pendingtruefalsein_progress_userPresent SoF form if not yet submitted
Fully approvedtruetrueapprovedNFT token issued — user can trade
RejectedrejectedInform the user; contact Swarm support

NFT permission token

When status is approved, Swarm automatically issues an on-chain NFT permission token to the user's wallet address. This token is the on-chain credential that gates access to trading on Swarm's platform. You do not need to take any action to trigger this — it is issued automatically upon approval.



Resubmitting Documents

If a user's KYC documents or Source of Funds information are incomplete or do not meet Swarm's regulatory requirements, they will be asked to resubmit. The flow differs slightly between KYC and SoF resubmissions.


KYC resubmission

If the identity documents provided are incomplete or rejected, the user receives an email with a link to resubmit. That link returns a new kyc_sumsub_access_token to your application.

Your application should:

  1. Detect that kyc_passed is still false after the user has previously submitted
  2. Call GET /onboarding/external to obtain a fresh kyc_sumsub_access_token
  3. Re-launch the KYC Select widget using the new token — the user will be taken directly to the step requiring resubmission

The Sumsub widget handles the resubmission UI internally. You only need to re-initialise it with the updated token.

javascript // Re-launch the widget on resubmission const { kyc_sumsub_access_token } = await getOnboardingStatus(address, sourceKey);

if (!kyc_passed && kyc_sumsub_access_token) { launchKYCWidget(kyc_sumsub_access_token); }


Source of Funds resubmission

If the SoF information submitted is incomplete, the POST /sof/verifications/external endpoint returns a status of in_progress_user and the user receives an email notification.

Your application should:

  1. Detect sof_passed: false alongside status: "in_progress_user" after a prior SoF submission
  2. Present the Source of Funds form to the user again
  3. Allow them to correct or complete their answers
  4. Resubmit to POST /sof/verifications/external

Note that a 409 Conflict response indicates a SoF submission already exists for this address. If you receive a 409 during what should be a resubmission, check whether the user's status is in_progress_review — their first submission may still be under review and a resubmission is not yet needed.


Distinguishing resubmission from first submission

There is no separate resubmission endpoint. The same endpoints are used throughout the lifecycle:

ActionEndpoint
Initiate / check status / get fresh KYC tokenGET /onboarding/external
Submit or resubmit SoFPOST /sof/verifications/external

The context for whether a call is a first submission or a resubmission is determined by the current status and kyc_passed / sof_passed values in the status response.