curl --request POST \
--url https://api.usenumero.com/numeroaccount/api/v1/customers \
--header 'Content-Type: application/json' \
--header 'X-Numero-Api-Key: <api-key>' \
--header 'X-Numero-Signature: <api-key>' \
--data '
{
"externalId": "<string>",
"firstName": "<string>",
"lastName": "<string>",
"email": "[email protected]",
"phoneNumber": "<string>",
"dateOfBirth": "2023-12-25",
"country": "<string>",
"bvn": "<string>",
"address1": "<string>",
"address2": "<string>",
"city": "<string>",
"state": "<string>",
"zipcode": "<string>",
"idType": "<string>",
"idNumber": "<string>",
"idDocumentFrontUrl": "<string>",
"idDocumentBackUrl": "<string>",
"metadataJson": "<string>",
"profiles": []
}
'import requests
url = "https://api.usenumero.com/numeroaccount/api/v1/customers"
payload = {
"externalId": "<string>",
"firstName": "<string>",
"lastName": "<string>",
"email": "[email protected]",
"phoneNumber": "<string>",
"dateOfBirth": "2023-12-25",
"country": "<string>",
"bvn": "<string>",
"address1": "<string>",
"address2": "<string>",
"city": "<string>",
"state": "<string>",
"zipcode": "<string>",
"idType": "<string>",
"idNumber": "<string>",
"idDocumentFrontUrl": "<string>",
"idDocumentBackUrl": "<string>",
"metadataJson": "<string>",
"profiles": []
}
headers = {
"X-Numero-Api-Key": "<api-key>",
"X-Numero-Signature": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Numero-Api-Key': '<api-key>',
'X-Numero-Signature': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
externalId: '<string>',
firstName: '<string>',
lastName: '<string>',
email: '[email protected]',
phoneNumber: '<string>',
dateOfBirth: '2023-12-25',
country: '<string>',
bvn: '<string>',
address1: '<string>',
address2: '<string>',
city: '<string>',
state: '<string>',
zipcode: '<string>',
idType: '<string>',
idNumber: '<string>',
idDocumentFrontUrl: '<string>',
idDocumentBackUrl: '<string>',
metadataJson: '<string>',
profiles: []
})
};
fetch('https://api.usenumero.com/numeroaccount/api/v1/customers', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.usenumero.com/numeroaccount/api/v1/customers",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'externalId' => '<string>',
'firstName' => '<string>',
'lastName' => '<string>',
'email' => '[email protected]',
'phoneNumber' => '<string>',
'dateOfBirth' => '2023-12-25',
'country' => '<string>',
'bvn' => '<string>',
'address1' => '<string>',
'address2' => '<string>',
'city' => '<string>',
'state' => '<string>',
'zipcode' => '<string>',
'idType' => '<string>',
'idNumber' => '<string>',
'idDocumentFrontUrl' => '<string>',
'idDocumentBackUrl' => '<string>',
'metadataJson' => '<string>',
'profiles' => [
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Numero-Api-Key: <api-key>",
"X-Numero-Signature: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.usenumero.com/numeroaccount/api/v1/customers"
payload := strings.NewReader("{\n \"externalId\": \"<string>\",\n \"firstName\": \"<string>\",\n \"lastName\": \"<string>\",\n \"email\": \"[email protected]\",\n \"phoneNumber\": \"<string>\",\n \"dateOfBirth\": \"2023-12-25\",\n \"country\": \"<string>\",\n \"bvn\": \"<string>\",\n \"address1\": \"<string>\",\n \"address2\": \"<string>\",\n \"city\": \"<string>\",\n \"state\": \"<string>\",\n \"zipcode\": \"<string>\",\n \"idType\": \"<string>\",\n \"idNumber\": \"<string>\",\n \"idDocumentFrontUrl\": \"<string>\",\n \"idDocumentBackUrl\": \"<string>\",\n \"metadataJson\": \"<string>\",\n \"profiles\": []\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Numero-Api-Key", "<api-key>")
req.Header.Add("X-Numero-Signature", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.usenumero.com/numeroaccount/api/v1/customers")
.header("X-Numero-Api-Key", "<api-key>")
.header("X-Numero-Signature", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"externalId\": \"<string>\",\n \"firstName\": \"<string>\",\n \"lastName\": \"<string>\",\n \"email\": \"[email protected]\",\n \"phoneNumber\": \"<string>\",\n \"dateOfBirth\": \"2023-12-25\",\n \"country\": \"<string>\",\n \"bvn\": \"<string>\",\n \"address1\": \"<string>\",\n \"address2\": \"<string>\",\n \"city\": \"<string>\",\n \"state\": \"<string>\",\n \"zipcode\": \"<string>\",\n \"idType\": \"<string>\",\n \"idNumber\": \"<string>\",\n \"idDocumentFrontUrl\": \"<string>\",\n \"idDocumentBackUrl\": \"<string>\",\n \"metadataJson\": \"<string>\",\n \"profiles\": []\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.usenumero.com/numeroaccount/api/v1/customers")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Numero-Api-Key"] = '<api-key>'
request["X-Numero-Signature"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"externalId\": \"<string>\",\n \"firstName\": \"<string>\",\n \"lastName\": \"<string>\",\n \"email\": \"[email protected]\",\n \"phoneNumber\": \"<string>\",\n \"dateOfBirth\": \"2023-12-25\",\n \"country\": \"<string>\",\n \"bvn\": \"<string>\",\n \"address1\": \"<string>\",\n \"address2\": \"<string>\",\n \"city\": \"<string>\",\n \"state\": \"<string>\",\n \"zipcode\": \"<string>\",\n \"idType\": \"<string>\",\n \"idNumber\": \"<string>\",\n \"idDocumentFrontUrl\": \"<string>\",\n \"idDocumentBackUrl\": \"<string>\",\n \"metadataJson\": \"<string>\",\n \"profiles\": []\n}"
response = http.request(request)
puts response.read_bodyCreate or update a customer 🔒
Upsert an end-customer record. Passing your own externalId makes the call idempotent — repeating it with the same externalId updates that customer rather than minting a duplicate.
curl --request POST \
--url https://api.usenumero.com/numeroaccount/api/v1/customers \
--header 'Content-Type: application/json' \
--header 'X-Numero-Api-Key: <api-key>' \
--header 'X-Numero-Signature: <api-key>' \
--data '
{
"externalId": "<string>",
"firstName": "<string>",
"lastName": "<string>",
"email": "[email protected]",
"phoneNumber": "<string>",
"dateOfBirth": "2023-12-25",
"country": "<string>",
"bvn": "<string>",
"address1": "<string>",
"address2": "<string>",
"city": "<string>",
"state": "<string>",
"zipcode": "<string>",
"idType": "<string>",
"idNumber": "<string>",
"idDocumentFrontUrl": "<string>",
"idDocumentBackUrl": "<string>",
"metadataJson": "<string>",
"profiles": []
}
'import requests
url = "https://api.usenumero.com/numeroaccount/api/v1/customers"
payload = {
"externalId": "<string>",
"firstName": "<string>",
"lastName": "<string>",
"email": "[email protected]",
"phoneNumber": "<string>",
"dateOfBirth": "2023-12-25",
"country": "<string>",
"bvn": "<string>",
"address1": "<string>",
"address2": "<string>",
"city": "<string>",
"state": "<string>",
"zipcode": "<string>",
"idType": "<string>",
"idNumber": "<string>",
"idDocumentFrontUrl": "<string>",
"idDocumentBackUrl": "<string>",
"metadataJson": "<string>",
"profiles": []
}
headers = {
"X-Numero-Api-Key": "<api-key>",
"X-Numero-Signature": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Numero-Api-Key': '<api-key>',
'X-Numero-Signature': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
externalId: '<string>',
firstName: '<string>',
lastName: '<string>',
email: '[email protected]',
phoneNumber: '<string>',
dateOfBirth: '2023-12-25',
country: '<string>',
bvn: '<string>',
address1: '<string>',
address2: '<string>',
city: '<string>',
state: '<string>',
zipcode: '<string>',
idType: '<string>',
idNumber: '<string>',
idDocumentFrontUrl: '<string>',
idDocumentBackUrl: '<string>',
metadataJson: '<string>',
profiles: []
})
};
fetch('https://api.usenumero.com/numeroaccount/api/v1/customers', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.usenumero.com/numeroaccount/api/v1/customers",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'externalId' => '<string>',
'firstName' => '<string>',
'lastName' => '<string>',
'email' => '[email protected]',
'phoneNumber' => '<string>',
'dateOfBirth' => '2023-12-25',
'country' => '<string>',
'bvn' => '<string>',
'address1' => '<string>',
'address2' => '<string>',
'city' => '<string>',
'state' => '<string>',
'zipcode' => '<string>',
'idType' => '<string>',
'idNumber' => '<string>',
'idDocumentFrontUrl' => '<string>',
'idDocumentBackUrl' => '<string>',
'metadataJson' => '<string>',
'profiles' => [
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Numero-Api-Key: <api-key>",
"X-Numero-Signature: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.usenumero.com/numeroaccount/api/v1/customers"
payload := strings.NewReader("{\n \"externalId\": \"<string>\",\n \"firstName\": \"<string>\",\n \"lastName\": \"<string>\",\n \"email\": \"[email protected]\",\n \"phoneNumber\": \"<string>\",\n \"dateOfBirth\": \"2023-12-25\",\n \"country\": \"<string>\",\n \"bvn\": \"<string>\",\n \"address1\": \"<string>\",\n \"address2\": \"<string>\",\n \"city\": \"<string>\",\n \"state\": \"<string>\",\n \"zipcode\": \"<string>\",\n \"idType\": \"<string>\",\n \"idNumber\": \"<string>\",\n \"idDocumentFrontUrl\": \"<string>\",\n \"idDocumentBackUrl\": \"<string>\",\n \"metadataJson\": \"<string>\",\n \"profiles\": []\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Numero-Api-Key", "<api-key>")
req.Header.Add("X-Numero-Signature", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.usenumero.com/numeroaccount/api/v1/customers")
.header("X-Numero-Api-Key", "<api-key>")
.header("X-Numero-Signature", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"externalId\": \"<string>\",\n \"firstName\": \"<string>\",\n \"lastName\": \"<string>\",\n \"email\": \"[email protected]\",\n \"phoneNumber\": \"<string>\",\n \"dateOfBirth\": \"2023-12-25\",\n \"country\": \"<string>\",\n \"bvn\": \"<string>\",\n \"address1\": \"<string>\",\n \"address2\": \"<string>\",\n \"city\": \"<string>\",\n \"state\": \"<string>\",\n \"zipcode\": \"<string>\",\n \"idType\": \"<string>\",\n \"idNumber\": \"<string>\",\n \"idDocumentFrontUrl\": \"<string>\",\n \"idDocumentBackUrl\": \"<string>\",\n \"metadataJson\": \"<string>\",\n \"profiles\": []\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.usenumero.com/numeroaccount/api/v1/customers")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Numero-Api-Key"] = '<api-key>'
request["X-Numero-Signature"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"externalId\": \"<string>\",\n \"firstName\": \"<string>\",\n \"lastName\": \"<string>\",\n \"email\": \"[email protected]\",\n \"phoneNumber\": \"<string>\",\n \"dateOfBirth\": \"2023-12-25\",\n \"country\": \"<string>\",\n \"bvn\": \"<string>\",\n \"address1\": \"<string>\",\n \"address2\": \"<string>\",\n \"city\": \"<string>\",\n \"state\": \"<string>\",\n \"zipcode\": \"<string>\",\n \"idType\": \"<string>\",\n \"idNumber\": \"<string>\",\n \"idDocumentFrontUrl\": \"<string>\",\n \"idDocumentBackUrl\": \"<string>\",\n \"metadataJson\": \"<string>\",\n \"profiles\": []\n}"
response = http.request(request)
puts response.read_bodyAuthorizations
Your business API key (live_key_...). Issued on approval; managed in Dashboard → Settings → Developer.
Base64(HMAC-SHA256(publicApiKey, input)) over the raw request body (POST) or canonicalized
query string (signed GET). Also send X-Numero-Signature-Version: v2. Required on
money-movement / state-changing endpoints (marked 🔒).
The HMAC key is your Public Key as raw UTF-8 bytes — a SECRET despite the name, and a
different value from the X-Numero-Api-Key authentication header. Signing with the API key
will never produce a valid signature.
Body
All fields are optional. Supply externalId to make the call idempotent and to keep the record in sync with your own system.
Your own stable id for this customer. Repeating a call with the same value updates that customer.
ISO 3166-1 alpha-2 (NG
Stored for later verification. A BVN you assert does not raise the customer's tier — only a successful KYC check does.
Opaque merchant metadata
Which profiles to attach — card and/or billing. Explicit rather than inferred from which fields are populated.
card, billing