Skip to main content
POST
/
customers
/
enroll
Enroll new customer
curl --request POST \
  --url https://api.cartevo.co/api/v1/customers/enroll \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "first_name": "John",
  "last_name": "Doe",
  "country": "Nigeria",
  "email": "john.doe@example.com",
  "street": "123 Main Street",
  "city": "Lagos",
  "state": "Lagos State",
  "postal_code": "100001",
  "country_iso_code": "CM",
  "country_phone_code": "+234",
  "phone_number": "8012345678",
  "identification_number": "12345678901",
  "id_document_front_url": "https://example.com/documents/front.jpg",
  "id_document_back_url": "https://example.com/documents/back.jpg",
  "id_document_type": "NIN",
  "date_of_birth": "1990-01-15"
}
'
{
  "success": true,
  "statusCode": 200,
  "message": "Data retrieved successfully",
  "data": {
    "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
    "first_name": "<string>",
    "last_name": "<string>",
    "country": "<string>",
    "email": "jsmith@example.com",
    "street": "<string>",
    "city": "<string>",
    "state": "<string>",
    "postal_code": "<string>",
    "phone_country_code": "<string>",
    "phone_number": "<string>",
    "identification_number": "<string>",
    "type": "<string>",
    "image": "<string>",
    "photo": "<string>",
    "number": "<string>",
    "date_of_birth": "2023-11-07T05:31:56Z",
    "is_active": true,
    "created_at": "2023-11-07T05:31:56Z",
    "updated_at": "2023-11-07T05:31:56Z"
  }
}

Overview

POST /customers/enroll registers a new customer in your company using publicly accessible URLs to the KYC documents instead of uploading the files directly. This is useful when documents are already hosted in your own object storage (S3, GCS, etc.). For local file uploads, use POST /customers instead. The customer is enrolled with the upstream card issuer in the same call, so they become eligible for card issuance immediately on success (subject to KYC outcome).

When to use it

Use this endpoint when…Use POST /customers when…
Documents are already hosted at public HTTPS URLs (S3, GCS, etc.).Documents are local files in your server.
You prefer JSON-only requests (easier to log, audit, and replay).You want a single round-trip without first uploading.

Prerequisites

  • Your company has completed KYB and is in APPROVED status.
  • The document URLs must be reachable over HTTPS by the upstream verifier (which may fetch them more than once).

Request

Headers

NameRequiredDescription
AuthorizationYesBearer <access_token>
Content-TypeYesapplication/json

Body fields

FieldTypeRequiredConstraints / notes
first_namestringYes3–255 chars
last_namestringYes3–255 chars
emailstringYesValid email
countrystringYesFull country name, e.g. "Cameroon"
streetstringYes2–255 chars
citystringYes2–255 chars
statestringYes2–255 chars
postal_codestringYes3–255 chars
country_iso_codestringYesISO 3166-1 alpha-2, e.g. CM, NG
country_phone_codestringYesDial code with +, e.g. +237
phone_numberstringYesLocal subscriber number (no country code)
identification_numberstringYesFormat depends on id_document_type
id_document_typestringYesEnum: NIN, PASSPORT, VOTERS_CARD, DRIVERS_LICENSE
date_of_birthstring (date)YesYYYY-MM-DD. Customer must be 18+
id_document_front_urlstring (URL)YesPublicly fetchable HTTPS URL to the front of the ID
id_document_back_urlstring (URL)YesPublicly fetchable HTTPS URL to the back of the ID

URL requirements

  • HTTPS only. Plain HTTP URLs are rejected.
  • Reachable by the upstream verifier. If the URL is gated (Basic Auth, IP allowlist, signed URL), the verifier will fail to fetch it.
  • Stable. The verifier may fetch the URL multiple times during processing. Signed URLs with very short expiry windows are not recommended; use a TTL of at least 30 minutes.
  • Direct file URLs, not landing pages. The response should be the image/PDF bytes with a correct Content-Type header.

Example

{
  "first_name": "John",
  "last_name": "Doe",
  "email": "john.doe@example.com",
  "country": "Cameroon",
  "country_iso_code": "CM",
  "country_phone_code": "+237",
  "phone_number": "600000000",
  "street": "123 Main Street",
  "city": "Yaoundé",
  "state": "Centre",
  "postal_code": "00237",
  "identification_number": "12345678901",
  "id_document_type": "NIN",
  "date_of_birth": "1990-01-15",
  "id_document_front_url": "https://cdn.your-app.com/kyc/abc123/front.jpg",
  "id_document_back_url": "https://cdn.your-app.com/kyc/abc123/back.jpg"
}

Response

201 — Customer enrolled

{
  "success": true,
  "statusCode": 201,
  "message": "Customer enrolled successfully",
  "data": {
    "id": "8d4f2a1b-5c3e-4d7f-9a6b-2e1c8f9d0a3b",
    "first_name": "John",
    "last_name": "Doe",
    "email": "john.doe@example.com",
    "country": "Cameroon",
    "street": "123 Main Street",
    "city": "Yaoundé",
    "state": "Centre",
    "postal_code": "00237",
    "phone_country_code": "+237",
    "phone_number": "600000000",
    "identification_number": "12345678901",
    "type": "NIN",
    "number": "12345678901",
    "image": "https://cdn.your-app.com/kyc/abc123/front.jpg",
    "photo": "https://cdn.your-app.com/kyc/abc123/back.jpg",
    "date_of_birth": "1990-01-15T00:00:00.000Z",
    "is_active": true,
    "created_at": "2026-05-09T10:15:00.000Z",
    "updated_at": "2026-05-09T10:15:00.000Z"
  }
}
See the POST /customers field reference for descriptions — the response shape is identical.

Error responses

Statusmessage exampleTrigger
400"id_document_front_url must be HTTPS"A document URL uses http:// instead of https://.
400"Customer must be 18 or older"date_of_birth is less than 18 years ago.
409"Customer with this email or ID already exists"Duplicate email or identification_number in your company.
422"Could not fetch id_document_front_url"The verifier couldn’t reach or download the URL.
422"KYC document unreadable"The verifier rejected the document quality.

Webhooks fired

  • customer.created — emitted immediately after the customer record is persisted.

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Body

application/json
first_name
string
required
Required string length: 3 - 255
Example:

"John"

last_name
string
required
Required string length: 3 - 255
Example:

"Doe"

country
string
required
Required string length: 2 - 255
Example:

"Nigeria"

email
string<email>
required
Example:

"john.doe@example.com"

street
string
required
Required string length: 2 - 255
Example:

"123 Main Street"

city
string
required
Required string length: 2 - 255
Example:

"Lagos"

state
string
required
Required string length: 2 - 255
Example:

"Lagos State"

postal_code
string
required
Required string length: 3 - 255
Example:

"100001"

country_iso_code
string
required
Required string length: 1 - 255
Example:

"CM"

country_phone_code
string
required
Required string length: 1 - 255
Example:

"+234"

phone_number
string
required
Required string length: 3 - 255
Example:

"8012345678"

identification_number
string
required
Required string length: 1 - 255
Example:

"12345678901"

id_document_front_url
string
required
Example:

"https://example.com/documents/front.jpg"

id_document_back_url
string
required
Example:

"https://example.com/documents/back.jpg"

id_document_type
enum<string>
required
Available options:
NIN,
PASSPORT,
VOTERS_CARD,
DRIVERS_LICENSE
Example:

"NIN"

date_of_birth
string<date>
required
Example:

"1990-01-15"

Response

Customer enrolled successfully

success
boolean
Example:

true

statusCode
integer
Example:

200

message
string
Example:

"Data retrieved successfully"

data
object