Skip to content

Contactos

Gestiona los contactos de tu espacio de trabajo. Los contactos representan personas individuales — prospectos, clientes, proveedores o cualquier persona con la que tu equipo interactúa.

Autenticación

Requiere header Authorization: Bearer {token}. Ver .

Permisos requeridos

Las operaciones sobre contactos requieren los permisos contacts:read, contacts:create, contacts:update o contacts:delete según corresponda. Los usuarios con acceso limitado al ámbito propio (contacts:read:own) solo ven los contactos asignados a ellos.


Listar contactos

http
GET /contacts

Retorna una lista paginada de contactos del espacio de trabajo. Soporta filtros, búsqueda de texto libre y ordenamiento.

Parámetros de consulta

ParámetroTipoRequeridoDescripción
cursorstringNoCursor de paginación. Usa el valor nextCursor de la respuesta anterior
limitintegerNoCantidad de resultados por página. Mínimo 1, máximo 100. Default: 25
sortstringNoCampo por el que ordenar. Valores: created_at, updated_at, first_name, last_name, email, score. Default: created_at
orderstringNoDirección del ordenamiento: asc o desc. Default: desc
searchstringNoBúsqueda de texto libre sobre nombre, email y teléfono
owner_idstringNoFiltra por ID del responsable asignado
sourcestringNoFiltra por ID o handle de la fuente de origen
created_afterstringNoRetorna solo contactos creados después de esta fecha (ISO 8601, ej. 2025-01-01T00:00:00Z)
created_beforestringNoRetorna solo contactos creados antes de esta fecha (ISO 8601)

Ejemplos

bash
curl -X GET "https://api-crm.zelta.dev/public/v1/contacts?limit=10&sort=created_at&order=desc" \
  -H "Authorization: Bearer tu-api-key-aqui"

Ejemplo JS

javascript
const response = await fetch(
  'https://api-crm.zelta.dev/public/v1/contacts?limit=10&sort=created_at&order=desc',
  {
    headers: {
      'Authorization': `Bearer ${process.env.ZELTA_API_KEY}`
    }
  }
);

const data = await response.json();
console.log(data.data); // array de contactos
console.log(data.nextCursor); // cursor para la siguiente página

Ejemplo Py

python
import requests

response = requests.get(
    'https://api-crm.zelta.dev/public/v1/contacts',
    params={
        'limit': 10,
        'sort': 'created_at',
        'order': 'desc'
    },
    headers={
        'Authorization': 'Bearer tu-api-key-aqui'
    }
)

data = response.json()
contacts = data['data']
next_cursor = data.get('nextCursor')

Respuesta exitosa

HTTP 200 OK

json
{
  "data": [
    {
      "id": "cnp_j3k9mxqz7t",
      "firstName": "María",
      "lastName": "González",
      "email": "[email protected]",
      "phone": "+507 6123-4567",
      "mobile": null,
      "companyId": "cmp_r8v2wlnp4s",
      "companyName": "Empresa ABC S.A.",
      "position": "Directora de Compras",
      "sourceId": "src_q1m5tyk8xn",
      "sourceName": "Sitio web",
      "score": 72,
      "ownerId": "usr_b4h7czjp9e",
      "ownerName": "Carlos Rodríguez",
      "tags": [
        {
          "id": "tag_x2f6nsvd3w",
          "label": "Cliente VIP",
          "handle": "cliente-vip",
          "color": "#6366F1"
        }
      ],
      "customData": {},
      "addressCountryId": 171,
      "addressCountryName": "Panamá",
      "addressStateId": 1234,
      "addressStateName": "Panamá",
      "addressCityId": 56789,
      "addressCityName": "Ciudad de Panamá",
      "createdAt": "2025-03-15T10:30:00.000Z",
      "updatedAt": "2025-04-01T08:45:00.000Z"
    }
  ],
  "nextCursor": "eyJjcmVhdGVkQXQiOiIyMDI1LTAzLTE1VDEwOjMwOjAwLjAwMFoiLCJpZCI6ImNucF9qM2s5bXhxejd0In0=",
  "hasMore": true
}

Obtener un contacto

http
GET /contacts/:id

Retorna los datos completos de un contacto específico por su ID.

Ejemplos

bash
curl -X GET "https://api-crm.zelta.dev/public/v1/contacts/cnp_j3k9mxqz7t" \
  -H "Authorization: Bearer tu-api-key-aqui"

Ejemplo JS

javascript
const contactId = 'cnp_j3k9mxqz7t';
const response = await fetch(
  `https://api-crm.zelta.dev/public/v1/contacts/${contactId}`,
  {
    headers: {
      'Authorization': `Bearer ${process.env.ZELTA_API_KEY}`
    }
  }
);

const contact = await response.json();

Ejemplo Py

python
import requests

contact_id = 'cnp_j3k9mxqz7t'
response = requests.get(
    f'https://api-crm.zelta.dev/public/v1/contacts/{contact_id}',
    headers={'Authorization': 'Bearer tu-api-key-aqui'}
)

contact = response.json()

Respuesta exitosa

HTTP 200 OK

Retorna el objeto completo del contacto con todos sus campos. Ver .


Crear un contacto

http
POST /contacts

Crea un nuevo contacto en el espacio de trabajo.

Cuerpo de la solicitud

CampoTipoRequeridoDescripción
firstNamestringNombre del contacto. Máximo 100 caracteres
lastNamestringApellido del contacto. Máximo 100 caracteres
emailstringNoCorreo electrónico. Debe ser un email válido
phonestringNoTeléfono principal (incluir código de país, ej. +507 6123-4567)
mobilestringNoTeléfono móvil alternativo
companyIdstringNoID de la empresa a la que pertenece el contacto
positionstringNoCargo o puesto del contacto en su empresa
sourceIdstringNoID de la fuente de origen del contacto (ej. sitio web, referido)
ownerIdstringNoID del usuario responsable del contacto. Si se omite, se asigna al usuario que realiza la solicitud
tagIdsstring[]NoArray de IDs de etiquetas a asignar al contacto
customDataobjectNoDatos de campos personalizados definidos en el espacio de trabajo
addressCountryIdintegerNoID del país (tabla de referencia geográfica)
addressStateIdintegerNoID del estado o provincia
addressCityIdintegerNoID de la ciudad

Campos personalizados

Los campos en customData deben coincidir con los campos personalizados configurados en Ajustes > Campos personalizados para la entidad contacto. Los campos con isRequired: true son obligatorios.

Ejemplos

bash
curl -X POST "https://api-crm.zelta.dev/public/v1/contacts" \
  -H "Authorization: Bearer tu-api-key-aqui" \
  -H "Content-Type: application/json" \
  -d '{
    "firstName": "María",
    "lastName": "González",
    "email": "[email protected]",
    "phone": "+507 6123-4567",
    "companyId": "cmp_r8v2wlnp4s",
    "position": "Directora de Compras",
    "tagIds": ["tag_x2f6nsvd3w"],
    "addressCountryId": 171,
    "addressStateId": 1234,
    "addressCityId": 56789
  }'

Ejemplo JS

javascript
const response = await fetch('https://api-crm.zelta.dev/public/v1/contacts', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.ZELTA_API_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    firstName: 'María',
    lastName: 'González',
    email: '[email protected]',
    phone: '+507 6123-4567',
    companyId: 'cmp_r8v2wlnp4s',
    position: 'Directora de Compras',
    tagIds: ['tag_x2f6nsvd3w'],
    addressCountryId: 171,
    addressStateId: 1234,
    addressCityId: 56789
  })
});

const contact = await response.json();
console.log(contact.id); // ID del nuevo contacto

Ejemplo Py

python
import requests

response = requests.post(
    'https://api-crm.zelta.dev/public/v1/contacts',
    headers={
        'Authorization': 'Bearer tu-api-key-aqui',
        'Content-Type': 'application/json'
    },
    json={
        'firstName': 'María',
        'lastName': 'González',
        'email': '[email protected]',
        'phone': '+507 6123-4567',
        'companyId': 'cmp_r8v2wlnp4s',
        'position': 'Directora de Compras',
        'tagIds': ['tag_x2f6nsvd3w'],
        'addressCountryId': 171,
        'addressStateId': 1234,
        'addressCityId': 56789
    }
)

contact = response.json()
print(contact['id'])

Respuesta exitosa

HTTP 201 Created

Retorna el objeto completo del contacto recién creado.


Actualizar un contacto

http
PUT /contacts/:id

Actualiza los campos de un contacto existente. Solo se actualizan los campos incluidos en el cuerpo — los campos omitidos conservan su valor actual.

Cuerpo de la solicitud

Todos los campos son opcionales. Ver la tabla de para las definiciones de cada campo.

Ejemplos

bash
curl -X PUT "https://api-crm.zelta.dev/public/v1/contacts/cnp_j3k9mxqz7t" \
  -H "Authorization: Bearer tu-api-key-aqui" \
  -H "Content-Type: application/json" \
  -d '{
    "position": "Gerente General",
    "phone": "+507 6999-0001"
  }'

Ejemplo JS

javascript
const contactId = 'cnp_j3k9mxqz7t';
const response = await fetch(
  `https://api-crm.zelta.dev/public/v1/contacts/${contactId}`,
  {
    method: 'PUT',
    headers: {
      'Authorization': `Bearer ${process.env.ZELTA_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      position: 'Gerente General',
      phone: '+507 6999-0001'
    })
  }
);

const updated = await response.json();

Ejemplo Py

python
import requests

contact_id = 'cnp_j3k9mxqz7t'
response = requests.put(
    f'https://api-crm.zelta.dev/public/v1/contacts/{contact_id}',
    headers={
        'Authorization': 'Bearer tu-api-key-aqui',
        'Content-Type': 'application/json'
    },
    json={
        'position': 'Gerente General',
        'phone': '+507 6999-0001'
    }
)

updated = response.json()

Respuesta exitosa

HTTP 200 OK

Retorna el objeto completo del contacto con los campos actualizados.


Eliminar un contacto

http
DELETE /contacts/:id

Elimina un contacto de forma lógica (soft delete). El contacto no se borra permanentemente — queda inaccesible desde la API y la interfaz, pero puede recuperarse contactando al soporte.

Ejemplos

bash
curl -X DELETE "https://api-crm.zelta.dev/public/v1/contacts/cnp_j3k9mxqz7t" \
  -H "Authorization: Bearer tu-api-key-aqui"

Ejemplo JS

javascript
const contactId = 'cnp_j3k9mxqz7t';
const response = await fetch(
  `https://api-crm.zelta.dev/public/v1/contacts/${contactId}`,
  {
    method: 'DELETE',
    headers: {
      'Authorization': `Bearer ${process.env.ZELTA_API_KEY}`
    }
  }
);

const result = await response.json();
// { "success": true }

Ejemplo Py

python
import requests

contact_id = 'cnp_j3k9mxqz7t'
response = requests.delete(
    f'https://api-crm.zelta.dev/public/v1/contacts/{contact_id}',
    headers={'Authorization': 'Bearer tu-api-key-aqui'}
)

result = response.json()
# {'success': True}

Respuesta exitosa

HTTP 200 OK

json
{
  "success": true
}

Campos de la respuesta

CampoTipoDescripción
idstringIdentificador único del contacto
firstNamestringNombre del contacto
lastNamestringApellido del contacto
emailstring | nullCorreo electrónico
phonestring | nullTeléfono principal
mobilestring | nullTeléfono móvil alternativo
companyIdstring | nullID de la empresa asociada
companyNamestring | nullNombre de la empresa (resuelto por JOIN)
positionstring | nullCargo del contacto
sourceIdstring | nullID de la fuente de origen
sourceNamestring | nullNombre de la fuente (resuelto por JOIN)
scoreintegerPuntuación del contacto (0–100)
ownerIdstring | nullID del responsable asignado
ownerNamestring | nullNombre completo del responsable (resuelto por JOIN)
tagsarrayEtiquetas asignadas al contacto
tags[].idstringID de la etiqueta
tags[].labelstringNombre visible de la etiqueta
tags[].handlestringIdentificador slug de la etiqueta
tags[].colorstringColor hex de la etiqueta
customDataobjectValores de campos personalizados
addressCountryIdinteger | nullID del país
addressCountryNamestring | nullNombre del país
addressStateIdinteger | nullID del estado o provincia
addressStateNamestring | nullNombre del estado o provincia
addressCityIdinteger | nullID de la ciudad
addressCityNamestring | nullNombre de la ciudad
createdAtstringFecha de creación en formato ISO 8601
updatedAtstringFecha de última actualización en formato ISO 8601

Problemas comunes

ErrorCausaSolución
401 UnauthorizedAPI Key inválida o ausenteVerifica que el header Authorization incluya un token válido
403 ForbiddenSin permisos suficientesEl rol asociado a tu API Key no tiene el permiso contacts:read o contacts:create
404 Not FoundContacto no encontradoVerifica que el ID sea correcto y pertenezca al espacio de trabajo del token
422 Unprocessable EntityError de validaciónRevisa los campos requeridos (firstName, lastName) y el formato del email
400companyId inválidoLa empresa no existeVerifica que el companyId sea correcto y no esté eliminado
400ownerId inválidoEl usuario no pertenece al workspaceUsa solo IDs de miembros activos del espacio de trabajo

Límite de resultados

El parámetro limit acepta un máximo de 100 registros por página. Para conjuntos de datos grandes, itera usando el campo nextCursor hasta que hasMore sea false.


Siguientes pasos

  • — Asocia contactos a empresas
  • — Vincula contactos a oportunidades de venta
  • — Cómo generar y usar tu API Key

Documentación oficial de Zelta