Skip to content

Productos

Gestiona el catálogo de productos y servicios de tu workspace. Los productos pueden ser físicos, servicios, suscripciones o digitales, y se utilizan en cotizaciones, órdenes y otros módulos de comercio.

Autenticación

Requiere header Authorization: Bearer {token}. Ver .


Listar Productos

http
GET /products

Retorna una lista paginada del catálogo de productos del workspace.

Parámetros de consulta

ParámetroTipoRequeridoDescripción
cursorstringNoCursor de paginación retornado en la respuesta anterior
limitintegerNoResultados por página. Mín: 1, máx: 100. Default: 25
sortstringNoCampo de ordenamiento: created_at, name, base_price. Default: created_at
orderstringNoDirección: asc o desc. Default: desc
searchstringNoBúsqueda por texto en nombre, SKU y descripción
typestringNoTipo de producto: physical, service, subscription, digital
statusstringNoEstado: active, archived, draft
categorystringNoFiltra por categoría exacta
owner_idstringNoFiltra por ID del responsable del producto

Permisos

Requiere permiso products:read. El módulo de Productos debe estar activo en el workspace.

Ejemplo

bash
curl -X GET "https://api-crm.zelta.dev/public/v1/products?type=service&status=active&limit=25" \
  -H "Authorization: Bearer tu-api-token-aqui"

Ejemplo JS

javascript
const params = new URLSearchParams({
  type: 'service',
  status: 'active',
  limit: '25'
});

const response = await fetch(
  `https://api-crm.zelta.dev/public/v1/products?${params}`,
  {
    headers: {
      'Authorization': `Bearer ${process.env.ZELTA_API_TOKEN}`
    }
  }
);

const result = await response.json();
console.log(result.data); // array de productos

Ejemplo Py

python
import requests

response = requests.get(
    'https://api-crm.zelta.dev/public/v1/products',
    params={
        'type': 'service',
        'status': 'active',
        'limit': 25
    },
    headers={
        'Authorization': 'Bearer tu-api-token-aqui'
    }
)

result = response.json()
print(result['data'])

Respuesta exitosa

HTTP 200 OK

json
{
  "data": [
    {
      "id": "pK4nBvCxDyEz",
      "name": "Consultoría de implementación",
      "type": "service",
      "category": "Consultoría",
      "sku": "SRV-IMPL-001",
      "description": "Servicio de implementación y configuración del CRM",
      "basePrice": "1500.00",
      "currency": "USD",
      "taxRate": "7.00",
      "unit": "hora",
      "status": "active",
      "ownerId": "aB3kLmNpQrSt",
      "ownerName": "Carlos Herrera",
      "hasVariants": false,
      "metadata": {},
      "sortOrder": 1,
      "createdAt": "2026-01-15T09:00:00.000Z",
      "updatedAt": "2026-03-10T11:30:00.000Z"
    }
  ],
  "pagination": {
    "nextCursor": "eyJjcmVhdGVkQXQiOiIyMDI2LTAxLTE1VDA5OjAwOjAwLjAwMFoiLCJpZCI6InBLNG5CdkN4RHlFeiJ9",
    "hasMore": false
  }
}

Obtener Producto

http
GET /products/:id

Retorna el detalle completo de un producto, incluyendo sus planes o variantes.

Parámetros de ruta

ParámetroTipoRequeridoDescripción
idstringID del producto

Ejemplo

bash
curl -X GET "https://api-crm.zelta.dev/public/v1/products/pK4nBvCxDyEz" \
  -H "Authorization: Bearer tu-api-token-aqui"

Ejemplo JS

javascript
const id = 'pK4nBvCxDyEz';

const response = await fetch(
  `https://api-crm.zelta.dev/public/v1/products/${id}`,
  {
    headers: {
      'Authorization': `Bearer ${process.env.ZELTA_API_TOKEN}`
    }
  }
);

const result = await response.json();
console.log(result.data);

Ejemplo Py

python
import requests

product_id = 'pK4nBvCxDyEz'

response = requests.get(
    f'https://api-crm.zelta.dev/public/v1/products/{product_id}',
    headers={
        'Authorization': 'Bearer tu-api-token-aqui'
    }
)

result = response.json()
print(result['data'])

Respuesta exitosa

HTTP 200 OK

json
{
  "data": {
    "id": "pK4nBvCxDyEz",
    "name": "Consultoría de implementación",
    "type": "service",
    "category": "Consultoría",
    "sku": "SRV-IMPL-001",
    "description": "Servicio de implementación y configuración del CRM",
    "basePrice": "1500.00",
    "currency": "USD",
    "taxRate": "7.00",
    "unit": "hora",
    "status": "active",
    "ownerId": "aB3kLmNpQrSt",
    "ownerName": "Carlos Herrera",
    "hasVariants": false,
    "metadata": {},
    "sortOrder": 1,
    "plans": [],
    "createdAt": "2026-01-15T09:00:00.000Z",
    "updatedAt": "2026-03-10T11:30:00.000Z"
  }
}

Crear Producto

http
POST /products

Crea un nuevo producto en el catálogo del workspace.

Cuerpo de la solicitud

CampoTipoRequeridoDescripción
namestringNombre del producto. Máx: 200 caracteres
typestringTipo de producto: physical, service, subscription, digital
categorystringNoCategoría del producto. Máx: 100 caracteres
skustringNoCódigo de referencia interno (SKU). Máx: 50 caracteres
descriptionstringNoDescripción completa del producto
basePricestringNoPrecio base en formato decimal. Ej: "99.99"
currencystringNoCódigo de moneda ISO 4217. Ej: "USD", "MXN". Default: moneda del workspace
taxRatestringNoTasa de impuesto en formato decimal. Ej: "7.00" para 7%
unitstringNoUnidad de medida o venta. Máx: 20 caracteres. Ej: "hora", "unidad", "mes"
statusstringNoEstado inicial: active, archived, draft. Default: active
ownerIdstringNoID del usuario responsable. Default: el usuario de la API key
hasVariantsbooleanNoIndica si el producto físico tiene variantes/planes. Default: false. Solo aplica para tipo physical
metadataobjectNoDatos adicionales en formato clave-valor libre
sortOrderintegerNoOrden de aparición en listados. Default: 0

Tipos de producto y variantes

  • physical: Productos físicos con inventario. Soporta variantes cuando hasVariants: true.
  • service: Servicios por hora o proyecto. Siempre muestra la sección de planes.
  • subscription: Servicios recurrentes con ciclo de facturación. Siempre muestra planes.
  • digital: Descargas, licencias o accesos digitales. Siempre muestra planes.

Ejemplo

bash
curl -X POST "https://api-crm.zelta.dev/public/v1/products" \
  -H "Authorization: Bearer tu-api-token-aqui" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Plan CRM Profesional",
    "type": "subscription",
    "category": "Software",
    "sku": "CRM-PRO-MES",
    "description": "Acceso completo al CRM con hasta 10 usuarios y soporte prioritario.",
    "basePrice": "299.00",
    "currency": "USD",
    "taxRate": "7.00",
    "unit": "mes",
    "status": "active"
  }'

Ejemplo JS

javascript
const response = await fetch('https://api-crm.zelta.dev/public/v1/products', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.ZELTA_API_TOKEN}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'Plan CRM Profesional',
    type: 'subscription',
    category: 'Software',
    sku: 'CRM-PRO-MES',
    description: 'Acceso completo al CRM con hasta 10 usuarios y soporte prioritario.',
    basePrice: '299.00',
    currency: 'USD',
    taxRate: '7.00',
    unit: 'mes',
    status: 'active'
  })
});

const result = await response.json();
console.log(result.data.id);

Ejemplo Py

python
import requests

response = requests.post(
    'https://api-crm.zelta.dev/public/v1/products',
    headers={
        'Authorization': 'Bearer tu-api-token-aqui',
        'Content-Type': 'application/json'
    },
    json={
        'name': 'Plan CRM Profesional',
        'type': 'subscription',
        'category': 'Software',
        'sku': 'CRM-PRO-MES',
        'description': 'Acceso completo al CRM con hasta 10 usuarios y soporte prioritario.',
        'basePrice': '299.00',
        'currency': 'USD',
        'taxRate': '7.00',
        'unit': 'mes',
        'status': 'active'
    }
)

result = response.json()
print(result['data']['id'])

Respuesta exitosa

HTTP 201 Created

json
{
  "data": {
    "id": "qL5oCwDyEzFa",
    "name": "Plan CRM Profesional",
    "type": "subscription",
    "category": "Software",
    "sku": "CRM-PRO-MES",
    "description": "Acceso completo al CRM con hasta 10 usuarios y soporte prioritario.",
    "basePrice": "299.00",
    "currency": "USD",
    "taxRate": "7.00",
    "unit": "mes",
    "status": "active",
    "ownerId": "aB3kLmNpQrSt",
    "ownerName": "Carlos Herrera",
    "hasVariants": false,
    "metadata": {},
    "sortOrder": 0,
    "createdAt": "2026-04-09T10:00:00.000Z",
    "updatedAt": "2026-04-09T10:00:00.000Z"
  }
}

Actualizar Producto

http
PUT /products/:id

Actualiza los campos de un producto existente. Todos los campos son opcionales — solo se modifican los campos enviados.

Parámetros de ruta

ParámetroTipoRequeridoDescripción
idstringID del producto

Cuerpo de la solicitud

Los mismos campos que en , todos opcionales.

Ejemplo

bash
curl -X PUT "https://api-crm.zelta.dev/public/v1/products/qL5oCwDyEzFa" \
  -H "Authorization: Bearer tu-api-token-aqui" \
  -H "Content-Type: application/json" \
  -d '{
    "basePrice": "349.00",
    "description": "Acceso completo al CRM con hasta 10 usuarios, soporte prioritario y módulo de automatizaciones."
  }'

Ejemplo JS

javascript
const id = 'qL5oCwDyEzFa';

const response = await fetch(`https://api-crm.zelta.dev/public/v1/products/${id}`, {
  method: 'PUT',
  headers: {
    'Authorization': `Bearer ${process.env.ZELTA_API_TOKEN}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    basePrice: '349.00',
    description: 'Acceso completo al CRM con hasta 10 usuarios, soporte prioritario y módulo de automatizaciones.'
  })
});

const result = await response.json();

Ejemplo Py

python
import requests

product_id = 'qL5oCwDyEzFa'

response = requests.put(
    f'https://api-crm.zelta.dev/public/v1/products/{product_id}',
    headers={
        'Authorization': 'Bearer tu-api-token-aqui',
        'Content-Type': 'application/json'
    },
    json={
        'basePrice': '349.00',
        'description': 'Acceso completo al CRM con hasta 10 usuarios, soporte prioritario y módulo de automatizaciones.'
    }
)

result = response.json()

Respuesta exitosa

HTTP 200 OK — Retorna el producto con los campos actualizados.


Eliminar Producto

http
DELETE /products/:id

Elimina un producto del catálogo (soft delete). El producto deja de aparecer en listados pero los registros históricos vinculados se conservan.

Parámetros de ruta

ParámetroTipoRequeridoDescripción
idstringID del producto

Ejemplo

bash
curl -X DELETE "https://api-crm.zelta.dev/public/v1/products/qL5oCwDyEzFa" \
  -H "Authorization: Bearer tu-api-token-aqui"

Ejemplo JS

javascript
const id = 'qL5oCwDyEzFa';

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

const result = await response.json();
console.log(result.success); // true

Ejemplo Py

python
import requests

product_id = 'qL5oCwDyEzFa'

response = requests.delete(
    f'https://api-crm.zelta.dev/public/v1/products/{product_id}',
    headers={
        'Authorization': 'Bearer tu-api-token-aqui'
    }
)

result = response.json()
print(result['success'])  # True

Respuesta exitosa

HTTP 200 OK

json
{
  "success": true
}

Eliminación y cotizaciones activas

Si el producto está referenciado en cotizaciones, suscripciones u órdenes activas, la eliminación no afecta esos registros existentes. Sin embargo, el producto ya no podrá seleccionarse en nuevos documentos.


Campos de la respuesta

CampoTipoDescripción
idstringIdentificador único del producto (nanoid)
namestringNombre del producto
typestringTipo: physical, service, subscription, digital
categorystring | nullCategoría del producto
skustring | nullCódigo de referencia interno (SKU)
descriptionstring | nullDescripción completa
basePricestring | nullPrecio base en formato decimal como string
currencystring | nullCódigo de moneda ISO 4217
taxRatestring | nullTasa de impuesto en formato decimal como string
unitstring | nullUnidad de medida o venta
statusstringEstado actual: active, archived, draft
ownerIdstring | nullID del responsable
ownerNamestring | nullNombre completo del responsable (resuelto por JOIN)
hasVariantsbooleanSi el producto físico tiene variantes o planes
metadataobjectDatos personalizados adicionales
sortOrderintegerOrden de aparición en listados
createdAtstringFecha de creación (ISO 8601)
updatedAtstringFecha de última actualización (ISO 8601)

Problemas comunes

ErrorCausaSolución
401 UnauthorizedToken ausente, inválido o expiradoVerifica tu API token en Configuración > API Keys
403 ForbiddenSin permiso products:read/create/update/deleteRevisa los permisos de la API key en tu workspace
403 ForbiddenMódulo de Productos no activoActiva el módulo en Configuración > Módulos
404 Not FoundEl producto no existe o fue eliminadoVerifica que el ID sea correcto y pertenezca a tu workspace
400name requeridoSe omitió el nombre en la creaciónIncluye un name de hasta 200 caracteres
400type inválidoSe envió un tipo no reconocidoUsa uno de: physical, service, subscription, digital
400status inválidoSe envió un estado no reconocidoUsa uno de: active, archived, draft
400basePrice inválidoFormato de precio incorrectoEnvía el precio como string decimal, ej: "299.00"

Siguientes pasos

  • — Usa productos en cotizaciones para clientes
  • — Gestiona suscripciones vinculadas a productos
  • — Encuentra productos con el buscador unificado

Documentación oficial de Zelta