Customers API
Buscá clientes, creá una identidad cuando no exista y consultá su estado de loyalty.
Operaciones
POST
/api/customersCreate a customer in a tenant-scoped program
Strict create semantics. This operation is not an upsert and does not promise an Idempotency-Key.
Scopes requeridos
customers.writeParámetros y headers
x-request-idheaderopcionalOptional caller correlation identifier.
{
"type": "string"
}X-Tenant-IDheaderopcionalOptional consistency hint; it never replaces the credential tenant.
{
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
}X-Tenant-SubdomainheaderopcionalOptional consistency hint; it must resolve to the credential tenant.
{
"type": "string"
}Request body
requerido
{
"additionalProperties": false,
"properties": {
"birthdate": {
"format": "date",
"type": "string"
},
"document": {
"maxLength": 80,
"minLength": 1,
"pattern": ".*\\S.*",
"type": "string"
},
"email": {
"format": "email",
"type": "string"
},
"first_name": {
"maxLength": 120,
"minLength": 1,
"pattern": ".*\\S.*",
"type": "string"
},
"last_name": {
"maxLength": 120,
"minLength": 1,
"pattern": ".*\\S.*",
"type": "string"
},
"phone": {
"maxLength": 40,
"minLength": 1,
"pattern": ".*\\S.*",
"type": "string"
},
"program_id": {
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
}
},
"required": [
"program_id",
"email"
],
"type": "object"
}Respuestas
HTTP 201 — Customer created.
{
"additionalProperties": false,
"properties": {
"data": {
"additionalProperties": false,
"properties": {
"created": {
"const": true
},
"customer": {
"additionalProperties": false,
"properties": {
"active": {
"type": "boolean"
},
"document": {
"type": [
"string",
"null"
]
},
"email": {
"format": "email",
"type": "string"
},
"firstName": {
"type": [
"string",
"null"
]
},
"id": {
"minimum": 1,
"type": "integer"
},
"lastName": {
"type": [
"string",
"null"
]
},
"phone": {
"type": [
"string",
"null"
]
},
"points": {
"type": "number"
},
"programId": {
"minimum": 1,
"type": "integer"
},
"tenantId": {
"minimum": 1,
"type": "integer"
},
"tier": {
"oneOf": [
{
"additionalProperties": false,
"properties": {
"id": {
"minimum": 1,
"type": "integer"
},
"name": {
"type": "string"
}
},
"required": [
"id",
"name"
],
"type": "object"
},
{
"type": "null"
}
]
}
},
"required": [
"id",
"tenantId",
"programId",
"email",
"firstName",
"lastName",
"phone",
"document",
"points",
"tier",
"active"
],
"type": "object"
}
},
"required": [
"created",
"customer"
],
"type": "object"
},
"ok": {
"const": true
}
},
"required": [
"ok",
"data"
],
"type": "object"
}HTTP 400 — Customer create validation or tenant-hint error.
Códigos de error
ambiguous_tenant_hintinvalid_jsoninvalid_requestinvalid_tenant_hint{
"additionalProperties": false,
"properties": {
"error": {
"additionalProperties": false,
"properties": {
"code": {
"enum": [
"invalid_json",
"invalid_request",
"invalid_tenant_hint",
"ambiguous_tenant_hint"
],
"type": "string"
},
"message": {
"type": "string"
}
},
"required": [
"code",
"message"
],
"type": "object"
},
"ok": {
"const": false
}
},
"required": [
"ok",
"error"
],
"type": "object"
}HTTP 401 — Missing or invalid API key.
Códigos de error
invalid_api_keymissing_api_key{
"additionalProperties": false,
"properties": {
"error": {
"additionalProperties": false,
"properties": {
"code": {
"enum": [
"missing_api_key",
"invalid_api_key"
],
"type": "string"
},
"message": {
"type": "string"
}
},
"required": [
"code",
"message"
],
"type": "object"
},
"ok": {
"const": false
}
},
"required": [
"ok",
"error"
],
"type": "object"
}HTTP 403 — Scope, tenant or program boundary denial.
Códigos de error
insufficient_scopeprogram_not_allowedtenant_mismatch{
"additionalProperties": false,
"properties": {
"error": {
"additionalProperties": false,
"properties": {
"code": {
"enum": [
"insufficient_scope",
"tenant_mismatch",
"program_not_allowed"
],
"type": "string"
},
"message": {
"type": "string"
}
},
"required": [
"code",
"message"
],
"type": "object"
},
"ok": {
"const": false
}
},
"required": [
"ok",
"error"
],
"type": "object"
}HTTP 409 — Customer identity already exists in the requested tenant/program boundary.
Códigos de error
customer_document_conflictcustomer_email_conflict{
"additionalProperties": false,
"properties": {
"error": {
"additionalProperties": false,
"properties": {
"code": {
"enum": [
"customer_email_conflict",
"customer_document_conflict"
],
"type": "string"
},
"message": {
"type": "string"
}
},
"required": [
"code",
"message"
],
"type": "object"
},
"ok": {
"const": false
}
},
"required": [
"ok",
"error"
],
"type": "object"
}HTTP 429 — Generic rate-limit denial; no numeric limit or retry timing is promised.
Códigos de error
rate_limited{
"additionalProperties": false,
"properties": {
"error": {
"additionalProperties": false,
"properties": {
"code": {
"const": "rate_limited"
},
"message": {
"type": "string"
}
},
"required": [
"code",
"message"
],
"type": "object"
},
"ok": {
"const": false
}
},
"required": [
"ok",
"error"
],
"type": "object"
}HTTP 500 — Ambiguous or internal create failure; reconcile using customer search before retry.
Códigos de error
customer_create_failedinternal_error{
"additionalProperties": false,
"properties": {
"error": {
"additionalProperties": false,
"properties": {
"code": {
"enum": [
"customer_create_failed",
"internal_error"
],
"type": "string"
},
"message": {
"type": "string"
}
},
"required": [
"code",
"message"
],
"type": "object"
},
"ok": {
"const": false
}
},
"required": [
"ok",
"error"
],
"type": "object"
}Ejemplos probados
Customer create after miss
- HTTP esperado
- 201
- Última prueba
- 2026-08-11
curl --request POST \
--url 'https://api.qualth.com/api/customers' \
--header 'X-API-Key: {{api_key}}' \
--header 'X-Tenant-Subdomain: {{tenant_subdomain}}' \
--header 'Content-Type: application/json' \
--data '{
"program_id": {{program_id}},
"email": "{{new_customer_email}}",
"first_name": "Sales",
"last_name": "Path"
}'Customer create duplicate conflict
- HTTP esperado
- 409
- Última prueba
- 2026-08-11
curl --request POST \
--url 'https://api.qualth.com/api/customers' \
--header 'X-API-Key: {{api_key}}' \
--header 'X-Tenant-Subdomain: {{tenant_subdomain}}' \
--header 'Content-Type: application/json' \
--data '{
"program_id": {{program_id}},
"email": "{{new_customer_email}}",
"first_name": "Sales",
"last_name": "Path"
}'