Negocios
Gestiona los negocios (oportunidades de venta) de tu espacio de trabajo. Los negocios representan oportunidades comerciales que avanzan a través de las etapas de un pipeline hasta cerrarse como ganados o perdidos.
Autenticación
Requiere header Authorization: Bearer {token}. Ver .
Permisos requeridos
Las operaciones sobre negocios requieren los permisos deals:read, deals:create, deals:update o deals:delete según corresponda. Los usuarios con acceso limitado al ámbito propio (deals:read:own) solo ven los negocios asignados a ellos.
Listar negocios
GET /dealsRetorna una lista paginada de negocios del espacio de trabajo. Soporta filtros por pipeline, etapa, responsable, empresa, estado y prioridad.
Parámetros de consulta
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
cursor | string | No | Cursor de paginación. Usa el valor nextCursor de la respuesta anterior |
limit | integer | No | Cantidad de resultados por página. Mínimo 1, máximo 100. Default: 25 |
sort | string | No | Campo por el que ordenar. Valores: created_at, updated_at, title, value, probability, expected_close_date. Default: created_at |
order | string | No | Dirección del ordenamiento: asc o desc. Default: desc |
search | string | No | Búsqueda de texto libre sobre el título del negocio |
pipeline_id | string | No | Filtra por ID del pipeline |
stage_id | string | No | Filtra por ID de la etapa dentro del pipeline |
owner_id | string | No | Filtra por ID del responsable asignado |
company_id | string | No | Filtra por ID de la empresa asociada |
status | string | No | Filtra por estado del negocio. Valores: open, won, lost |
priority | string | No | Filtra por prioridad. Valores: low, medium, high, urgent |
Ejemplos
curl -X GET "https://api-crm.zelta.dev/public/v1/deals?status=open&pipeline_id=pip_k7n2qsxm9p&limit=25" \
-H "Authorization: Bearer tu-api-key-aqui"Ejemplo JS
const params = new URLSearchParams({
status: 'open',
pipeline_id: 'pip_k7n2qsxm9p',
sort: 'value',
order: 'desc',
limit: '25'
});
const response = await fetch(
`https://api-crm.zelta.dev/public/v1/deals?${params}`,
{
headers: {
'Authorization': `Bearer ${process.env.ZELTA_API_KEY}`
}
}
);
const data = await response.json();
console.log(data.data); // array de negocios
console.log(data.nextCursor); // cursor para la siguiente páginaEjemplo Py
import requests
response = requests.get(
'https://api-crm.zelta.dev/public/v1/deals',
params={
'status': 'open',
'pipeline_id': 'pip_k7n2qsxm9p',
'sort': 'value',
'order': 'desc',
'limit': 25
},
headers={
'Authorization': 'Bearer tu-api-key-aqui'
}
)
data = response.json()
deals = data['data']Respuesta exitosa
HTTP 200 OK
{
"data": [
{
"id": "deal_w5p8yznc1v",
"title": "Contrato de mantenimiento anual",
"pipelineId": "pip_k7n2qsxm9p",
"pipelineName": "Pipeline de ventas",
"stageId": "stg_h3t6rxmb7q",
"stageName": "Propuesta enviada",
"contactId": "cnp_j3k9mxqz7t",
"contactName": "María González",
"companyId": "cmp_r8v2wlnp4s",
"companyName": "Constructora del Pacífico S.A.",
"ownerId": "usr_b4h7czjp9e",
"ownerName": "Carlos Rodríguez",
"value": 24000,
"currency": "USD",
"probability": 60,
"priority": "high",
"status": "open",
"expectedCloseDate": "2025-06-30T00:00:00.000Z",
"tags": [],
"customData": {},
"description": "Incluye soporte técnico y actualizaciones de software.",
"createdAt": "2025-04-01T11:00:00.000Z",
"updatedAt": "2025-04-08T09:30:00.000Z"
}
],
"nextCursor": "eyJjcmVhdGVkQXQiOiIyMDI1LTA0LTAxVDExOjAwOjAwLjAwMFoiLCJpZCI6ImRlYWxfdzVwOHl6bmMxdiJ9",
"hasMore": false
}Obtener un negocio
GET /deals/:idRetorna los datos completos de un negocio específico por su ID.
Ejemplos
curl -X GET "https://api-crm.zelta.dev/public/v1/deals/deal_w5p8yznc1v" \
-H "Authorization: Bearer tu-api-key-aqui"Ejemplo JS
const dealId = 'deal_w5p8yznc1v';
const response = await fetch(
`https://api-crm.zelta.dev/public/v1/deals/${dealId}`,
{
headers: {
'Authorization': `Bearer ${process.env.ZELTA_API_KEY}`
}
}
);
const deal = await response.json();Ejemplo Py
import requests
deal_id = 'deal_w5p8yznc1v'
response = requests.get(
f'https://api-crm.zelta.dev/public/v1/deals/{deal_id}',
headers={'Authorization': 'Bearer tu-api-key-aqui'}
)
deal = response.json()Respuesta exitosa
HTTP 200 OK
Retorna el objeto completo del negocio con todos sus campos. Ver .
Crear un negocio
POST /dealsCrea un nuevo negocio en el espacio de trabajo y lo posiciona en la etapa inicial del pipeline indicado.
Cuerpo de la solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
title | string | Sí | Título del negocio. Máximo 200 caracteres |
pipelineId | string | Sí | ID del pipeline al que pertenece el negocio |
stageId | string | Sí | ID de la etapa inicial dentro del pipeline |
contactId | string | No | ID del contacto principal asociado al negocio |
companyId | string | No | ID de la empresa asociada al negocio |
ownerId | string | No | ID del usuario responsable. Si se omite, se asigna al usuario que realiza la solicitud |
value | integer | No | Valor económico del negocio en la moneda indicada |
currency | string | No | Código ISO 4217 de la moneda para el valor (ej. USD, MXN). Default: moneda del workspace |
probability | integer | No | Probabilidad de cierre del 0 al 100. Si la etapa tiene probabilidad definida, este valor la sobreescribe |
priority | string | No | Prioridad del negocio. Valores: low, medium, high, urgent. Default: medium |
expectedCloseDate | string | No | Fecha esperada de cierre en formato ISO 8601 (ej. 2025-06-30T00:00:00.000Z) |
tags | string[] | No | Array de IDs de etiquetas a asignar al negocio |
customData | object | No | Datos de campos personalizados definidos en el espacio de trabajo |
description | string | No | Descripción o notas adicionales sobre el negocio |
Pipeline y etapas
Para obtener los IDs de pipelines y etapas disponibles, consulta el endpoint GET /deals/pipelines desde la interfaz de Zelta CRM o la referencia de la API interna. Cada pipeline tiene sus propias etapas con probabilidades predefinidas.
Ejemplos
curl -X POST "https://api-crm.zelta.dev/public/v1/deals" \
-H "Authorization: Bearer tu-api-key-aqui" \
-H "Content-Type: application/json" \
-d '{
"title": "Contrato de mantenimiento anual",
"pipelineId": "pip_k7n2qsxm9p",
"stageId": "stg_a1b2cdef3g",
"contactId": "cnp_j3k9mxqz7t",
"companyId": "cmp_r8v2wlnp4s",
"value": 24000,
"currency": "USD",
"probability": 40,
"priority": "high",
"expectedCloseDate": "2025-06-30T00:00:00.000Z",
"description": "Incluye soporte técnico y actualizaciones de software."
}'Ejemplo JS
const response = await fetch('https://api-crm.zelta.dev/public/v1/deals', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.ZELTA_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
title: 'Contrato de mantenimiento anual',
pipelineId: 'pip_k7n2qsxm9p',
stageId: 'stg_a1b2cdef3g',
contactId: 'cnp_j3k9mxqz7t',
companyId: 'cmp_r8v2wlnp4s',
value: 24000,
currency: 'USD',
probability: 40,
priority: 'high',
expectedCloseDate: '2025-06-30T00:00:00.000Z',
description: 'Incluye soporte técnico y actualizaciones de software.'
})
});
const deal = await response.json();
console.log(deal.id); // ID del nuevo negocioEjemplo Py
import requests
response = requests.post(
'https://api-crm.zelta.dev/public/v1/deals',
headers={
'Authorization': 'Bearer tu-api-key-aqui',
'Content-Type': 'application/json'
},
json={
'title': 'Contrato de mantenimiento anual',
'pipelineId': 'pip_k7n2qsxm9p',
'stageId': 'stg_a1b2cdef3g',
'contactId': 'cnp_j3k9mxqz7t',
'companyId': 'cmp_r8v2wlnp4s',
'value': 24000,
'currency': 'USD',
'probability': 40,
'priority': 'high',
'expectedCloseDate': '2025-06-30T00:00:00.000Z',
'description': 'Incluye soporte técnico y actualizaciones de software.'
}
)
deal = response.json()
print(deal['id'])Respuesta exitosa
HTTP 201 Created
Retorna el objeto completo del negocio recién creado.
Actualizar un negocio
PUT /deals/:idActualiza los datos de un negocio existente. Solo se actualizan los campos incluidos en el cuerpo — los campos omitidos conservan su valor actual.
Cambiar de etapa
Para mover un negocio a una etapa diferente y registrar el historial de cambios, usa el endpoint dedicado . El campo stageId en PUT actualiza la etapa sin registrar historial.
Cuerpo de la solicitud
Todos los campos son opcionales. Ver la tabla de para las definiciones de cada campo.
Ejemplos
curl -X PUT "https://api-crm.zelta.dev/public/v1/deals/deal_w5p8yznc1v" \
-H "Authorization: Bearer tu-api-key-aqui" \
-H "Content-Type: application/json" \
-d '{
"value": 28000,
"probability": 75,
"priority": "urgent"
}'Ejemplo JS
const dealId = 'deal_w5p8yznc1v';
const response = await fetch(
`https://api-crm.zelta.dev/public/v1/deals/${dealId}`,
{
method: 'PUT',
headers: {
'Authorization': `Bearer ${process.env.ZELTA_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
value: 28000,
probability: 75,
priority: 'urgent'
})
}
);
const updated = await response.json();Ejemplo Py
import requests
deal_id = 'deal_w5p8yznc1v'
response = requests.put(
f'https://api-crm.zelta.dev/public/v1/deals/{deal_id}',
headers={
'Authorization': 'Bearer tu-api-key-aqui',
'Content-Type': 'application/json'
},
json={
'value': 28000,
'probability': 75,
'priority': 'urgent'
}
)
updated = response.json()Respuesta exitosa
HTTP 200 OK
Retorna el objeto completo del negocio con los campos actualizados.
Eliminar un negocio
DELETE /deals/:idElimina un negocio de forma lógica (soft delete). El negocio queda inaccesible desde la API y la interfaz, pero sus datos no se borran permanentemente.
Ejemplos
curl -X DELETE "https://api-crm.zelta.dev/public/v1/deals/deal_w5p8yznc1v" \
-H "Authorization: Bearer tu-api-key-aqui"Ejemplo JS
const dealId = 'deal_w5p8yznc1v';
const response = await fetch(
`https://api-crm.zelta.dev/public/v1/deals/${dealId}`,
{
method: 'DELETE',
headers: {
'Authorization': `Bearer ${process.env.ZELTA_API_KEY}`
}
}
);
const result = await response.json();
// { "success": true }Ejemplo Py
import requests
deal_id = 'deal_w5p8yznc1v'
response = requests.delete(
f'https://api-crm.zelta.dev/public/v1/deals/{deal_id}',
headers={'Authorization': 'Bearer tu-api-key-aqui'}
)
result = response.json()
# {'success': True}Respuesta exitosa
HTTP 200 OK
{
"success": true
}Mover etapa del negocio
PATCH /deals/:id/stageMueve un negocio a una etapa diferente dentro de su pipeline y registra el cambio en el historial de etapas. Este endpoint es la forma recomendada de avanzar un negocio en el pipeline, ya que preserva la trazabilidad del proceso comercial.
Historial automático
Cada llamada a este endpoint registra un evento en el historial de etapas del negocio con la etapa anterior, la nueva etapa, el usuario que realizó el cambio y la fecha. Este historial es visible en la vista de detalle del negocio en Zelta CRM.
Cuerpo de la solicitud
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
stageId | string | Sí | ID de la nueva etapa a la que se mueve el negocio. Debe pertenecer al mismo pipeline del negocio |
Ejemplos
curl -X PATCH "https://api-crm.zelta.dev/public/v1/deals/deal_w5p8yznc1v/stage" \
-H "Authorization: Bearer tu-api-key-aqui" \
-H "Content-Type: application/json" \
-d '{
"stageId": "stg_h3t6rxmb7q"
}'Ejemplo JS
const dealId = 'deal_w5p8yznc1v';
const response = await fetch(
`https://api-crm.zelta.dev/public/v1/deals/${dealId}/stage`,
{
method: 'PATCH',
headers: {
'Authorization': `Bearer ${process.env.ZELTA_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
stageId: 'stg_h3t6rxmb7q'
})
}
);
const deal = await response.json();
console.log(deal.stageName); // nueva etapa del negocioEjemplo Py
import requests
deal_id = 'deal_w5p8yznc1v'
response = requests.patch(
f'https://api-crm.zelta.dev/public/v1/deals/{deal_id}/stage',
headers={
'Authorization': 'Bearer tu-api-key-aqui',
'Content-Type': 'application/json'
},
json={
'stageId': 'stg_h3t6rxmb7q'
}
)
deal = response.json()
print(deal['stageName'])Respuesta exitosa
HTTP 200 OK
Retorna el objeto completo del negocio con la nueva etapa reflejada en stageId y stageName.
Campos de la respuesta
| Campo | Tipo | Descripción |
|---|---|---|
id | string | Identificador único del negocio |
title | string | Título del negocio |
pipelineId | string | ID del pipeline al que pertenece |
pipelineName | string | Nombre del pipeline (resuelto por JOIN) |
stageId | string | ID de la etapa actual |
stageName | string | Nombre de la etapa actual (resuelto por JOIN) |
contactId | string | null | ID del contacto principal asociado |
contactName | string | null | Nombre completo del contacto (resuelto por JOIN) |
companyId | string | null | ID de la empresa asociada |
companyName | string | null | Nombre de la empresa (resuelto por JOIN) |
ownerId | string | null | ID del responsable asignado |
ownerName | string | null | Nombre completo del responsable (resuelto por JOIN) |
value | integer | null | Valor económico del negocio |
currency | string | null | Código ISO 4217 de la moneda del valor |
probability | integer | Probabilidad de cierre del 0 al 100 |
priority | string | Prioridad: low, medium, high o urgent |
status | string | Estado: open, won o lost |
expectedCloseDate | string | null | Fecha esperada de cierre en formato ISO 8601 |
tags | array | Etiquetas asignadas al negocio |
tags[].id | string | ID de la etiqueta |
tags[].label | string | Nombre visible de la etiqueta |
tags[].handle | string | Identificador slug de la etiqueta |
tags[].color | string | Color hex de la etiqueta |
customData | object | Valores de campos personalizados |
description | string | null | Descripción o notas adicionales |
createdAt | string | Fecha de creación en formato ISO 8601 |
updatedAt | string | Fecha de última actualización en formato ISO 8601 |
Problemas comunes
| Error | Causa | Solución |
|---|---|---|
401 Unauthorized | API Key inválida o ausente | Verifica que el header Authorization incluya un token válido |
403 Forbidden | Sin permisos suficientes | El rol de tu API Key no tiene el permiso deals:read o deals:create |
404 Not Found | Negocio no encontrado | Verifica que el ID pertenezca al espacio de trabajo del token |
422 Unprocessable Entity | Error de validación | Revisa los campos requeridos (title, pipelineId, stageId) |
400 — stageId inválido | La etapa no pertenece al pipeline | El stageId debe ser una etapa del pipeline indicado en pipelineId |
400 — probability fuera de rango | Valor inválido | probability debe ser un entero entre 0 y 100 |
400 — priority inválido | Valor no reconocido | Usa uno de: low, medium, high, urgent |
400 — status de negocio cerrado | El negocio ya fue cerrado | Los negocios marcados como won o lost no se pueden mover de etapa. Usa la interfaz para reabrirlos |
Negocios cerrados
Un negocio marcado como ganado (won) o perdido (lost) no puede ser movido de etapa mediante el endpoint PATCH /deals/:id/stage. Para reabrir un negocio cerrado, usa la opción Reabrir desde la interfaz de Zelta CRM.
Siguientes pasos
- — Administra los contactos asociados a negocios
- — Administra las empresas vinculadas a negocios
- — Cómo generar y usar tu API Key