Skip to content

Referencia API

Documentación general de la API pública de Zelta CRM: URL base, límites de uso, formato de respuestas y códigos de error.

URL Base

Producción:

https://api-crm.zelta.dev/public/v1

Desarrollo:

https://dev-api-crm.zelta.dev/public/v1

Todas las solicitudes deben usar HTTPS. Las solicitudes HTTP serán rechazadas.

Autenticación

Todas las solicitudes requieren el header:

http
Authorization: Bearer zk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Consulta la para obtener una API Key y conocer los permisos disponibles.

Documentación interactiva

La API expone una interfaz Swagger UI y un documento OpenAPI para explorar y probar los endpoints sin necesidad de configurar un cliente HTTP.

RecursoURLAutenticación
Swagger UI/public/v1/docsNo requerida
OpenAPI JSON/public/v1/docNo requerida

Prueba los endpoints directamente

Accede a https://api-crm.zelta.dev/public/v1/docs desde tu navegador para explorar todos los endpoints, ver los esquemas de datos y enviar solicitudes de prueba sin salir de la documentación.

Límites de uso (Rate Limiting)

La API pública tiene un límite de 60 solicitudes por minuto por API Key. Este límite se aplica de forma independiente para cada clave.

ParámetroValor
Solicitudes permitidas60
Ventana de tiempo60 segundos
Scope del límitePor API Key

Cuando se supera el límite, la API responde con estado 429 y el código de error API_KEY_RATE_LIMITED. Espera unos segundos antes de reintentar.

Sin headers de cuota

La API no incluye headers de cuota restante (X-RateLimit-*) en las respuestas. Si recibes un error 429, implementa un mecanismo de reintentos con espera exponencial en tu cliente.

Endpoints disponibles

MétodoRutaDescripción
GET/contactsListar contactos (paginación por cursor)
POST/contactsCrear un nuevo contacto
GET/contacts/:idObtener un contacto por ID
PUT/contacts/:idActualizar un contacto
DELETE/contacts/:idEliminar un contacto
GET/companiesListar empresas (paginación por cursor)
POST/companiesCrear una nueva empresa
GET/companies/:idObtener una empresa por ID
PUT/companies/:idActualizar una empresa
DELETE/companies/:idEliminar una empresa
GET/dealsListar negocios (paginación por cursor)
POST/dealsCrear un nuevo negocio
GET/deals/:idObtener un negocio por ID
PUT/deals/:idActualizar un negocio
DELETE/deals/:idEliminar un negocio
PATCH/deals/:id/stageMover un negocio de etapa
GET/activitiesListar actividades (paginación por cursor)
POST/activitiesCrear una nueva actividad
GET/activities/:idObtener una actividad por ID
PUT/activities/:idActualizar una actividad
DELETE/activities/:idEliminar una actividad
PATCH/activities/:id/completeMarcar una actividad como completada
GET/productsListar productos (paginación por cursor)
POST/productsCrear un nuevo producto
GET/products/:idObtener un producto por ID
PUT/products/:idActualizar un producto
DELETE/products/:idEliminar un producto
GET/searchBúsqueda global entre todos los recursos

Formato de respuestas

Lista de recursos

Los endpoints de listado devuelven un envelope con paginación por cursor:

json
{
  "data": [
    {
      "id": "abc123",
      "name": "María García",
      "email": "[email protected]"
    }
  ],
  "nextCursor": "eyJjcmVhdGVkQXQiOiIyMDI0LTAxLTE1VDEwOjAwOjAwWiIsImlkIjoiYWJjMTIzIn0=",
  "hasMore": true
}

Recurso individual

Los endpoints que retornan un solo recurso (GET por ID, POST, PUT) devuelven el objeto directamente dentro de data:

json
{
  "data": {
    "id": "abc123",
    "name": "María García",
    "email": "[email protected]",
    "phone": "+507 6000-0000",
    "createdAt": "2024-01-15T10:00:00.000Z"
  }
}

Eliminación exitosa

json
{
  "success": true
}

Respuesta de error

json
{
  "error": {
    "code": "CONTACT_NOT_FOUND",
    "message": "Contacto no encontrado"
  }
}

Error de validación

Cuando los datos enviados no cumplen con las validaciones requeridas, la respuesta incluye detalles por campo:

json
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Error de validación",
    "details": [
      {
        "field": "email",
        "message": "Formato de correo electrónico inválido"
      }
    ]
  }
}

Paginación

La API utiliza paginación por cursor en todos los endpoints de listado. Este método es más eficiente que la paginación por número de página para conjuntos de datos grandes o que cambian frecuentemente.

Parámetros de consulta

ParámetroTipoDefaultDescripción
cursorstringCursor opaco retornado por la respuesta anterior
limitinteger25Número de resultados por página (mínimo 1, máximo 100)

Campos de respuesta

CampoTipoDescripción
dataarrayResultados de la página actual
nextCursorstring | nullCursor para obtener la siguiente página. null cuando no hay más resultados
hasMorebooleantrue si existen más resultados después de la página actual

Ejemplo de paginación:

bash
# Primera página
curl "https://api-crm.zelta.dev/public/v1/contacts?limit=10" \
  -H "Authorization: Bearer $ZELTA_API_KEY"

# Siguiente página usando el cursor retornado
curl "https://api-crm.zelta.dev/public/v1/contacts?limit=10&cursor=eyJjcmVhdGVkQXQiOi4uLn0=" \
  -H "Authorization: Bearer $ZELTA_API_KEY"

Cuándo parar de paginar

Cuando hasMore sea false o nextCursor sea null, has llegado al final del conjunto de resultados.

Campos sanitizados

Por seguridad y privacidad, los siguientes campos nunca se incluyen en las respuestas de la API pública, aunque existan internamente:

Campo omitidoRazón
tenantIdDato interno de aislamiento multi-tenant
deletedAtCampo de borrado lógico interno
deletedByCampo de auditoría interna
searchVectorÍndice de texto completo interno (PostgreSQL tsvector)
searchTsvÍndice de texto completo interno (PostgreSQL tsvector)

Códigos de estado HTTP

CódigoEstadoDescripción
200OKSolicitud exitosa
201CreatedRecurso creado exitosamente
400Bad RequestDatos inválidos, faltantes o formato incorrecto
401UnauthorizedAPI Key ausente, inválida, expirada o revocada
403ForbiddenLa API Key no tiene permisos para esta operación
404Not FoundEl recurso solicitado no existe
423LockedEl espacio de trabajo está suspendido
429Too Many RequestsSe superó el límite de solicitudes por minuto
500Internal Server ErrorError interno del servidor — contacta a soporte

Códigos de error

CódigoHTTPDescripción
INVALID_API_KEY401La API Key no existe o el formato es incorrecto
API_KEY_EXPIRED401La API Key superó su fecha de expiración
API_KEY_REVOKED401La API Key fue revocada manualmente
API_KEY_RATE_LIMITED429Se superó el límite de 60 solicitudes por minuto
API_KEY_FORBIDDEN403La API Key no tiene permiso para esta operación
TENANT_NOT_FOUND401El espacio de trabajo asociado a la clave no existe
TENANT_SUSPENDED423El espacio de trabajo está suspendido
CONTACT_NOT_FOUND404El contacto solicitado no existe o fue eliminado
COMPANY_NOT_FOUND404La empresa solicitada no existe o fue eliminada
DEAL_NOT_FOUND404El negocio solicitado no existe o fue eliminado
ACTIVITY_NOT_FOUND404La actividad solicitada no existe o fue eliminada
PRODUCT_NOT_FOUND404El producto solicitado no existe o fue eliminado
VALIDATION_ERROR400Los datos enviados no cumplen con las validaciones requeridas
INTERNAL_ERROR500Error interno del servidor

Siguientes pasos

  • — Cómo obtener y usar una API Key
  • — Listar, crear y gestionar contactos por API
  • — Listar, crear y gestionar empresas por API

Documentación oficial de Zelta