Skip to main content
Use the identity methods to run KYC for Identity API integrations: capture the required customer data in your own UI, submit it through the SDK, and bring the customer to a verified state. The client handles authentication for you — no raw access token is required. The six methods wrap the Identity API endpoints and follow the same Result pattern as the rest of the client:
MethodEndpointPurpose
createIdentity()POST /platform/v1/identitiesCreate an identity for the connected customer.
getIdentity()GET /platform/v1/identities/{id}Fetch the identity, including its requirements.
updateIdentity()PATCH /platform/v1/identities/{id}Submit one or more outstanding requirements.
verifyIdentity()POST /platform/v1/identities/{id}/verificationsSubmit the identity for verification.
getIdentityUploadUrl()POST /platform/v1/identities/{id}/files/upload-urlIssue a presigned URL for a document upload.
submitIdentityFiles()POST /platform/v1/identities/{id}/filesConfirm previously uploaded documents.
The identity methods require an authenticated client. Run client.getConnection() with skipKyc: true first, and authenticate the customer with client.setupAuth() when the status is "connectionRequired".
For the field and document requirements by country, see What to capture.

client.createIdentity()

Create an identity for the connected customer. The response lists the requirements you need to fulfil before verification.
Create an identity
const result = await client.createIdentity({
  residentialAddress: { country: "USA" },
  capabilities: [{ product: "ramps" }],
});

if (!result.ok) {
  // Handle error
  console.error(result.error.code, result.error.message);
  return;
}

if (result.value.data === null) {
  // The customer is already onboarded — no outstanding requirements.
  return;
}

console.log(result.value.data.id, result.value.data.requirements);

createIdentity() parameters

FieldTypeRequiredDescription
residentialAddress.countrystringThe customer’s country of residence as an ISO 3166-1 alpha-3 code (for example, "USA").
capabilities{ product: "ramps" }[]The capabilities to unlock for the customer. Must contain at least one entry.

createIdentity() result

Returns a Result<{ data: Identity | null }, DevPlatformApiError>. data is null (HTTP 204) when the customer has no outstanding requirements — they are already onboarded.

client.getIdentity()

Fetch the identity, including the current status and requirement states.
Get an identity
const result = await client.getIdentity(identityId);

if (result.ok) {
  console.log(result.value.data.status, result.value.data.requirements);
}

getIdentity() parameters

FieldTypeRequiredDescription
idstringThe identity identifier.

getIdentity() result

Returns a Result<{ data: Identity }, DevPlatformApiError>.

client.updateIdentity()

Submit one or more outstanding requirements on the identity. Each top-level field maps to a requirement category — submit the categories listed as incomplete in requirements.
Update an identity
const result = await client.updateIdentity(identityId, {
  basicDetails: {
    firstName: "Ada",
    lastName: "Lovelace",
    dateOfBirth: "1990-12-10",
  },
  residentialAddress: {
    street: "123 Main St",
    locality: "San Francisco",
    administrativeArea: "CA",
    postalCode: "94105",
    country: "USA",
  },
  phoneNumber: { number: "+12025550143" },
});

updateIdentity() parameters

FieldTypeRequiredDescription
idstringThe identity identifier.
basicDetailsobjectThe customer’s name, nationality, and date of birth (YYYY-MM-DD).
residentialAddressobjectThe customer’s residential address. Country codes are ISO 3166-1 alpha-3.
phoneNumberobjectThe customer’s phone number in E.164 format (for example, "+12025550143").
taxIdentifiersarrayTax identifiers: { type: "ssn" | "cpf", value } or { type: "tin", country, value }.

updateIdentity() result

Returns a Result<{ data: Identity }, DevPlatformApiError> reflecting the updated requirement states.

client.verifyIdentity()

Submit the identity for verification once all requirements are complete.
Verify an identity
const result = await client.verifyIdentity(identityId);

if (!result.ok) {
  // requirements_incomplete: submit the missing requirements first.
  console.error(result.error.code, result.error.message);
  return;
}

switch (result.value.data.status) {
  case "approved":
    // The customer is verified.
    break;
  case "processing":
    // Verification is running — poll getIdentity() for the outcome.
    break;
  case "challengeRequired":
    // Render the challenge frame with setupChallenge().
    console.log(result.value.data.challenge.url);
    break;
}
When the status is "challengeRequired", pass challenge.url to client.setupChallenge(). The challenge completes with flow: "identity" and the identityId.

verifyIdentity() parameters

FieldTypeRequiredDescription
idstringThe identity identifier.

verifyIdentity() result

Returns a Result<{ data: IdentityVerificationResponse }, DevPlatformApiError>.
FieldTypeRequiredDescription
status"approved" | "processing" | "challengeRequired"The verification outcome.
challenge{ url: string; expiresAt: string }Present when status is "challengeRequired". Pass url to setupChallenge().

client.getIdentityUploadUrl()

Issue a presigned URL to upload an identity document. Upload the file with an HTTP PUT to the returned url, sending the returned headers.
Upload a document
const urlResult = await client.getIdentityUploadUrl(identityId, {
  fileType: "passport",
  mimeType: "image/jpeg",
});

if (!urlResult.ok) return;

const { uploadId, url, headers } = urlResult.value.data;

await fetch(url, {
  method: "PUT",
  headers,
  body: passportImageBlob,
});

getIdentityUploadUrl() parameters

FieldTypeRequiredDescription
idstringThe identity identifier.
fileTypestringOne of "drivingLicence", "nationalIdentityCard", "passport", "residencePermit", "selfie", "proofOfAddress".
sidestring"front" or "back". Required for two-sided documents (drivingLicence, nationalIdentityCard, residencePermit); omit otherwise.
mimeTypestring"image/jpeg", "image/png", or "application/pdf". Must match the Content-Type header you send on the upload request.

getIdentityUploadUrl() result

Returns a Result<{ data: IdentityFileUploadUrl }, DevPlatformApiError>.
FieldTypeRequiredDescription
uploadIdstringThe upload identifier to confirm with submitIdentityFiles().
urlstringThe presigned upload URL.
expiresAtstringAn ISO 8601 timestamp for when the URL expires.
headersobjectHeaders to send on the upload request (Content-Type).

client.submitIdentityFiles()

Confirm one or more uploaded documents so MoonPay processes them against the identity’s requirements.
Submit uploaded documents
const result = await client.submitIdentityFiles(identityId, {
  files: [{ uploadId, fileType: "passport" }],
});

if (result.ok) {
  console.log(result.value.data.requirements);
}

submitIdentityFiles() parameters

FieldTypeRequiredDescription
idstringThe identity identifier.
filesarrayThe uploads to confirm: { uploadId, fileType, side? }, matching the issued upload URLs.

submitIdentityFiles() result

Returns a Result<{ data: Identity }, DevPlatformApiError> reflecting the updated requirement states.

Shared types

Identity

FieldTypeRequiredDescription
idstringThe identity identifier.
statusIdentityStatusThe identity’s place in the KYC lifecycle.
capabilities{ product: "ramps" }[]The capabilities requested for the customer.
requirementsRequirementsOutstanding and completed requirements, keyed by category.
challenge{ url: string; expiresAt: string }Present only when status is "challengeRequired". Pass url to setupChallenge().
createdAtstringAn ISO 8601 creation timestamp.
updatedAtstringAn ISO 8601 last-update timestamp.

IdentityStatus

"created", "collecting", "verifying", "challengeRequired", "approved", "rejected", "manualReview", or "blocked".

Requirements

Each category is present when it applies to the customer’s jurisdiction, with a status of "incomplete" or "complete" and, for field-based categories, the requiredFields still outstanding.
CategoryFulfilled by
basicDetailsupdateIdentity()
residentialAddressupdateIdentity()
phoneNumberupdateIdentity()
taxIdentifiersupdateIdentity()
identityDocumentsgetIdentityUploadUrl() + submitIdentityFiles()
selfiegetIdentityUploadUrl() + submitIdentityFiles()
proofOfAddressgetIdentityUploadUrl() + submitIdentityFiles()

Errors

All identity methods return the standard MoonPay Platform API error shape, DevPlatformApiError, with code, message, and optional field-level errors. Notable codes: "requirements_incomplete" when verifying too early, "verification_rejected" on a terminal rejection, and "country_mismatch" when submitted data conflicts with the declared country.