Create or upsert a partner customer
curl --request POST \
--url https://api.swapnice.com/v1/customers \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: <idempotency-key>' \
--data '
{
"external_id": "partner_user_1842",
"profile": {
"username": "collector1842"
},
"metadata": {
"source": "ios"
}
}
'const options = {
method: 'POST',
headers: {
'Idempotency-Key': '<idempotency-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
external_id: 'partner_user_1842',
profile: {username: 'collector1842'},
metadata: {source: 'ios'}
})
};
fetch('https://api.swapnice.com/v1/customers', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.swapnice.com/v1/customers"
payload = {
"external_id": "partner_user_1842",
"profile": { "username": "collector1842" },
"metadata": { "source": "ios" }
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"status": "created",
"customer": {
"id": "cust_8f2a1c",
"app_id": "app_91b0",
"external_id": "partner_user_1842",
"status": "active",
"profile": {
"username": "collector1842"
},
"metadata": {
"source": "ios"
},
"created_at": "2026-08-26T16:01:00.000Z",
"updated_at": "2026-08-26T16:01:00.000Z"
}
}{
"error": {
"code": "consent_denied",
"message": "<string>",
"request_id": "<string>",
"details": [
{
"code": "<string>",
"message": "<string>",
"field": "<string>"
}
]
}
}{
"error": {
"code": "consent_denied",
"message": "<string>",
"request_id": "<string>",
"details": [
{
"code": "<string>",
"message": "<string>",
"field": "<string>"
}
]
}
}Customers
Create or upsert a customer
Create the partner-scoped user. Body field is external_id, not customer_id.
POST
/
v1
/
customers
Create or upsert a partner customer
curl --request POST \
--url https://api.swapnice.com/v1/customers \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: <idempotency-key>' \
--data '
{
"external_id": "partner_user_1842",
"profile": {
"username": "collector1842"
},
"metadata": {
"source": "ios"
}
}
'const options = {
method: 'POST',
headers: {
'Idempotency-Key': '<idempotency-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
external_id: 'partner_user_1842',
profile: {username: 'collector1842'},
metadata: {source: 'ios'}
})
};
fetch('https://api.swapnice.com/v1/customers', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.swapnice.com/v1/customers"
payload = {
"external_id": "partner_user_1842",
"profile": { "username": "collector1842" },
"metadata": { "source": "ios" }
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"status": "created",
"customer": {
"id": "cust_8f2a1c",
"app_id": "app_91b0",
"external_id": "partner_user_1842",
"status": "active",
"profile": {
"username": "collector1842"
},
"metadata": {
"source": "ios"
},
"created_at": "2026-08-26T16:01:00.000Z",
"updated_at": "2026-08-26T16:01:00.000Z"
}
}{
"error": {
"code": "consent_denied",
"message": "<string>",
"request_id": "<string>",
"details": [
{
"code": "<string>",
"message": "<string>",
"field": "<string>"
}
]
}
}{
"error": {
"code": "consent_denied",
"message": "<string>",
"request_id": "<string>",
"details": [
{
"code": "<string>",
"message": "<string>",
"field": "<string>"
}
]
}
}Create the partner-scoped user. Body field is external_id, not customer_id.
profile accepts public display fields only. Do not send payment, government-id, or credential data.Authorizations
OAuth 2.1 authorization code with PKCE. Implicit and password flows are unsupported.
Headers
Required for mutating requests. Replays with the same key and payload hash return
the original logical result; replays with a different payload hash return 409.
Required string length:
16 - 255⌘I