Contactos
El recurso Contactos gestiona tanto clientes como proveedores. Ambos comparten la misma estructura y se diferencian por el campo type (client o provider).
Todas las rutas son relativas a la URL base de producción:
https://api-pos.zelta.dev/public/v1INFO
La autenticación se hace con el header Authorization: Bearer <key> o X-API-Key: <key>, usando una llave con prefijo zpk_. Consulta para más detalles.
Crear un contacto
POST /contactsCrea un cliente o proveedor. Devuelve 201.
Campos del cuerpo
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
name | string | Sí | Nombre del contacto. Máx. 200 caracteres. |
identification | string | No | Documento de identidad. Máx. 60 caracteres. |
kind | string | No | Tipo de contribuyente: natural, juridica o gobierno. |
ruc | string | No | RUC del contacto. Máx. 60 caracteres. Se valida contra el registro de la DGI. |
dv | string | No | Dígito verificador. Máx. 10 caracteres. |
email | string | No | Correo electrónico. |
phone | string | No | Teléfono. Máx. 40 caracteres. |
type | string | No | client o provider. Por defecto client. |
WARNING
El campo dv se acepta al crear y actualizar, pero no se devuelve en la respuesta. El ruc se valida contra el registro de la DGI, así que un RUC inexistente provoca un validation_error.
curl -X POST "https://api-pos.zelta.dev/public/v1/contacts" \
-H "Authorization: Bearer zpk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"name": "Distribuidora El Istmo, S.A.",
"kind": "juridica",
"ruc": "155612345-2-2018",
"dv": "47",
"email": "[email protected]",
"phone": "+507 6000-1234",
"type": "client"
}'Ejemplo JS
const res = await fetch('https://api-pos.zelta.dev/public/v1/contacts', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.ZELTA_POS_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'Distribuidora El Istmo, S.A.',
kind: 'juridica',
ruc: '155612345-2-2018',
dv: '47',
email: '[email protected]',
phone: '+507 6000-1234',
type: 'client'
})
});
const data = await res.json();Ejemplo Py
import requests
res = requests.post(
'https://api-pos.zelta.dev/public/v1/contacts',
headers={'Authorization': 'Bearer zpk_live_xxx', 'Content-Type': 'application/json'},
json={
'name': 'Distribuidora El Istmo, S.A.',
'kind': 'juridica',
'ruc': '155612345-2-2018',
'dv': '47',
'email': '[email protected]',
'phone': '+507 6000-1234',
'type': 'client'
}
)
data = res.json()Respuesta
{
"id": "ct_7g6f5d4s3a2x1z9c",
"type": "client",
"name": "Distribuidora El Istmo, S.A.",
"identification": null,
"kind": "juridica",
"ruc": "155612345-2-2018",
"email": "[email protected]",
"phone": "+507 6000-1234",
"createdAt": "2026-06-30T14:21:08.000Z",
"updatedAt": "2026-06-30T14:21:08.000Z"
}| Campo | Tipo | Descripción |
|---|---|---|
id | string | ID del contacto. |
type | string | client o provider. |
name | string | Nombre del contacto. |
identification | string | null | Documento de identidad. |
kind | string | null | natural, juridica o gobierno. |
ruc | string | null | RUC del contacto. |
email | string | null | Correo electrónico. |
phone | string | null | Teléfono. |
createdAt | string | Fecha de creación. |
updatedAt | string | Fecha de última actualización. |
Listar contactos
GET /contactsDevuelve la lista de contactos en un envoltorio { "data": [ ... ] }. Además de los parámetros de paginación y sincronización incremental (start, limit, updatedSince, from/to, metadata, ver ), acepta:
| Parámetro | Tipo | Descripción |
|---|---|---|
type | string | Filtra por client o provider. |
curl "https://api-pos.zelta.dev/public/v1/contacts?type=provider&limit=30" \
-H "Authorization: Bearer zpk_live_xxx"Ejemplo JS
const res = await fetch('https://api-pos.zelta.dev/public/v1/contacts?type=provider&limit=30', {
headers: { 'Authorization': `Bearer ${process.env.ZELTA_POS_API_KEY}` }
});
const data = await res.json();Ejemplo Py
import requests
res = requests.get(
'https://api-pos.zelta.dev/public/v1/contacts',
headers={'Authorization': 'Bearer zpk_live_xxx'},
params={'type': 'provider', 'limit': 30}
)
data = res.json(){
"data": [
{
"id": "ct_7g6f5d4s3a2x1z9c",
"type": "provider",
"name": "Importadora Caribe, S.A.",
"identification": null,
"kind": "juridica",
"ruc": "155698765-2-2015",
"email": "[email protected]",
"phone": "+507 300-5678",
"createdAt": "2026-05-10T09:00:00.000Z",
"updatedAt": "2026-05-10T09:00:00.000Z"
}
]
}Obtener un contacto
GET /contacts/{id}Devuelve un contacto como objeto directo. Responde 404 si no existe. Acepta el query type (client o provider).
curl "https://api-pos.zelta.dev/public/v1/contacts/ct_7g6f5d4s3a2x1z9c?type=client" \
-H "Authorization: Bearer zpk_live_xxx"Ejemplo JS
const res = await fetch('https://api-pos.zelta.dev/public/v1/contacts/ct_7g6f5d4s3a2x1z9c?type=client', {
headers: { 'Authorization': `Bearer ${process.env.ZELTA_POS_API_KEY}` }
});
const data = await res.json();Ejemplo Py
import requests
res = requests.get(
'https://api-pos.zelta.dev/public/v1/contacts/ct_7g6f5d4s3a2x1z9c',
headers={'Authorization': 'Bearer zpk_live_xxx'},
params={'type': 'client'}
)
data = res.json()Actualizar un contacto
PUT /contacts/{id}Actualiza un contacto existente. Responde 404 si no existe. El cuerpo admite los mismos campos opcionales que la creación (envía al menos uno).
WARNING
El type del contacto se indica como query param, no en el cuerpo. Recuerda que dv se acepta en el cuerpo pero no se devuelve en la respuesta.
curl -X PUT "https://api-pos.zelta.dev/public/v1/contacts/ct_7g6f5d4s3a2x1z9c?type=client" \
-H "Authorization: Bearer zpk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"phone": "+507 6000-9999"
}'Ejemplo JS
const res = await fetch('https://api-pos.zelta.dev/public/v1/contacts/ct_7g6f5d4s3a2x1z9c?type=client', {
method: 'PUT',
headers: {
'Authorization': `Bearer ${process.env.ZELTA_POS_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: '[email protected]',
phone: '+507 6000-9999'
})
});
const data = await res.json();Ejemplo Py
import requests
res = requests.put(
'https://api-pos.zelta.dev/public/v1/contacts/ct_7g6f5d4s3a2x1z9c',
headers={'Authorization': 'Bearer zpk_live_xxx', 'Content-Type': 'application/json'},
params={'type': 'client'},
json={
'email': '[email protected]',
'phone': '+507 6000-9999'
}
)
data = res.json()Problemas comunes
| Código | HTTP | Causa probable |
|---|---|---|
validation_error | 400 | Falta name, un campo supera su longitud máxima, o el ruc no existe en el registro de la DGI. |
unauthorized | 401 | API key ausente o inválida. |
forbidden | 403 | La key no tiene acceso al recurso solicitado. |
not_found | 404 | El id del contacto no existe (o no coincide con el type indicado). |
conflict | 409 | Conflicto con un contacto existente. |
rate_limited | 429 | Se superó el límite de peticiones. |
internal_error | 500 | Error interno del servidor. |
Siguientes pasos
- — asocia un cliente a tus ventas.
- — descubre los
idde bodegas y sucursales. - — paginación y sincronización incremental.