Customers API
Buscá clientes, creá una identidad cuando no exista y consultá su estado de loyalty.
Operaciones
GET
/api/customers/searchSearch a tenant-scoped customer by email
Credential tenant is authoritative; tenant headers are optional consistency hints.
Scopes requeridos
customers.readParámetros y headers
programIdqueryrequerido{
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
}emailqueryrequerido{
"format": "email",
"type": "string"
}X-Tenant-IDheaderopcionalOptional consistency hint; must match the credential tenant.
{
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
}X-Tenant-SubdomainheaderopcionalOptional consistency hint; must resolve to and match the credential tenant.
{
"type": "string"
}Request body
No aplica
Respuestas
HTTP 200 — Customer found or no customer matched the tenant/program/email boundary.
Códigos de error
customer_not_found{
"oneOf": [
{
"additionalProperties": false,
"properties": {
"data": {
"additionalProperties": false,
"properties": {
"customer": {
"additionalProperties": false,
"properties": {
"active": {
"type": [
"boolean",
"null"
]
},
"email": {
"format": "email",
"type": [
"string",
"null"
]
},
"firstName": {
"type": [
"string",
"null"
]
},
"id": {
"type": "integer"
},
"lastName": {
"type": [
"string",
"null"
]
},
"phone": {
"type": [
"string",
"null"
]
},
"points": {
"type": "number"
},
"programId": {
"type": "integer"
},
"tenantId": {
"type": "integer"
},
"tier": {
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"tenantId",
"programId",
"email",
"firstName",
"lastName",
"phone",
"points",
"tier",
"active"
],
"type": "object"
}
},
"required": [
"customer"
],
"type": "object"
},
"ok": {
"const": true
}
},
"required": [
"ok",
"data"
],
"type": "object"
},
{
"additionalProperties": false,
"properties": {
"data": {
"additionalProperties": false,
"properties": {
"customer": {
"type": "null"
}
},
"required": [
"customer"
],
"type": "object"
},
"ok": {
"const": true
},
"warnings": {
"items": {
"additionalProperties": false,
"properties": {
"code": {
"const": "customer_not_found"
},
"message": {
"const": "No customer was found for the provided email in this tenant/program."
}
},
"required": [
"code",
"message"
],
"type": "object"
},
"maxItems": 1,
"minItems": 1,
"type": "array"
}
},
"required": [
"ok",
"data",
"warnings"
],
"type": "object"
}
]
}HTTP 400 — Customer search request validation error.
Códigos de error
ambiguous_tenant_hintinvalid_emailinvalid_include_inactiveinvalid_program_idinvalid_tenant_hintmissing_emailmissing_program_idunknown_query_parameter{
"additionalProperties": false,
"properties": {
"error": {
"additionalProperties": false,
"properties": {
"code": {
"enum": [
"missing_program_id",
"invalid_program_id",
"missing_email",
"invalid_email",
"invalid_include_inactive",
"invalid_tenant_hint",
"ambiguous_tenant_hint",
"unknown_query_parameter"
],
"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 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 — Sanitized customer search internal failure.
Códigos de error
internal_error{
"additionalProperties": false,
"properties": {
"error": {
"additionalProperties": false,
"properties": {
"code": {
"const": "internal_error"
},
"message": {
"type": "string"
}
},
"required": [
"code",
"message"
],
"type": "object"
},
"ok": {
"const": false
}
},
"required": [
"ok",
"error"
],
"type": "object"
}Ejemplos probados
Customer search existing
- HTTP esperado
- 200
- Última prueba
- 2026-08-11
curl --request GET \
--url 'https://api.qualth.com/api/customers/search?programId={{program_id}}&email={{existing_customer_email}}' \
--header 'X-API-Key: {{api_key}}' \
--header 'X-Tenant-Subdomain: {{tenant_subdomain}}'Customer search miss
- HTTP esperado
- 200
- Última prueba
- 2026-08-11
curl --request GET \
--url 'https://api.qualth.com/api/customers/search?programId={{program_id}}&email={{new_customer_email}}' \
--header 'X-API-Key: {{api_key}}' \
--header 'X-Tenant-Subdomain: {{tenant_subdomain}}'