Categoría opcional
Los productos se crean sin categoría por defecto. Envía category como texto de hasta 80 caracteres para asignarla; los espacios de los extremos se eliminan. En la web puedes seleccionar una categoría existente o escribir una nueva al crear o editar. Las categorías se obtienen de los productos del propio dueño.
{
"name": "Servicio mensual",
"price": 10,
"productType": "service",
"currency": "USD",
"category": "Soporte"
}PUT /v1/products/PRODUCT_ID también acepta category. Si se omite, se conserva; si se envía una cadena vacía, se elimina la categoría. Los listados incluyen el campo category.
API de Productos
Tu catálogo de productos y servicios en Pabilo: un recurso propio con CRUD completo, que puedes consultar y mantener desde tu sistema.
Un producto es simplemente un ítem con nombre, precio y tipo, asociado a tu cuenta. Vive por sí solo: puedes crearlo, listarlo, buscarlo y actualizarlo sin que participe en ningún cobro, y usarlo como fuente de verdad de tu catálogo desde el POS, el e-commerce o el back-office que tengas.
Endpoints
Todos requieren autenticación (Authorization: Bearer o el header appKey).
| Método | Ruta | Para qué |
|---|---|---|
| POST | /v1/products/create | Crear un producto |
| GET | /v1/products/myproducts | Listar todos, sin paginar |
| POST | /me/products | Listar paginado y con búsqueda |
| PUT | /v1/products/:productId | Actualizar nombre y precio |
El objeto Producto
{
"id": "6a662432d95326f46d526271",
"created_at": "2026-08-01T12:00:00Z",
"updated_at": "2026-08-01T12:00:00Z",
"name": "Plan Premium",
"price": 25,
"currency": "USD",
"productType": "service",
"ownerId": "685725869e6febc736848bf1"
}Moneda del producto
currency al crear, se asume VEF. La moneda se usa al convertir precios cuando se cobra a través de un link de pago o suscripción que esté en otra moneda. No existe un campo description: si lo envías, se ignora.Crear un Producto
curl -X POST https://api.pabilo.app/v1/products/create \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TU_API_KEY" \
-d '{
"name": "Plan Premium",
"price": 25,
"productType": "service",
"currency": "USD"
}'Body de la Petición
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
| name | string | ✅ Sí | Nombre visible del producto |
| price | number | ✅ Sí | Monto sin moneda. Admite decimales |
| productType | string | ✅ Sí | service o product. Sin otro valor válido |
| currency | string | ❌ Opcional | VEF (default), USD, EUR o USDT |
productType es obligatorio y no tiene default
400 con BAD_REQUEST y el mensaje bad request: invalid product type: error creating product. Es el error más común al integrar.Respuesta de Ejemplo
{
"message": "product created successfully",
"product": {
"id": "6a662432d95326f46d526271",
"created_at": "2026-08-01T12:00:00Z",
"updated_at": "2026-08-01T12:00:00Z",
"name": "Plan Premium",
"price": 25,
"currency": "USD",
"productType": "service",
"ownerId": "685725869e6febc736848bf1"
}
}Listar Productos
Hay dos formas. /v1/products/myproducts devuelve todo de una, útil para llenar un selector. /me/products pagina y busca, útil para una tabla.
curl -X GET https://api.pabilo.app/v1/products/myproducts \
-H "Authorization: Bearer TU_API_KEY"{
"message": "fetched all products successfully",
"products": [
{
"id": "…",
"name": "Plan Premium",
"price": 25,
"currency": "USD",
"productType": "service",
"ownerId": "…"
}
]
}Versión paginada
curl -X POST "https://api.pabilo.app/me/products?page=1&limit=10&search=premium" \
-H "Authorization: Bearer TU_API_KEY"El método declarado es QUERY, pero el servidor lo registra como POST, así que ambos funcionan. Los parámetros van en la query string o en un body JSON, indistintamente.
Parámetros
| Parámetro | Tipo | Descripción |
|---|---|---|
| page | integer | Número de página (default: 1) |
| limit | integer | Resultados por página (default: 10) |
| search | string | Filtrar por nombre |
{
"message": "Products fetched successfully",
"products": [ … ],
"total": 1,
"page": 1,
"limit": 10
}Actualizar un Producto
curl -X PUT https://api.pabilo.app/v1/products/6a662432d95326f46d526271 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TU_API_KEY" \
-d '{
"name": "Plan Premium Anual",
"price": 250,
"currency": "USD"
}'No es una actualización parcial (excepto currency)
name y price se sobreescriben siempre, con lo que venga en el body. Si omites uno, queda vacío ("") o en cero. Manda siempre los dos campos, incluso los que no cambian. productType no se puede modificar.currency es la excepción: si no se envía, no cambia la moneda.Respuesta de Ejemplo
{
"message": "product updated successfully",
"product": {
"id": "…",
"name": "Plan Premium Anual",
"price": 250,
"currency": "USD",
"productType": "service",
"ownerId": "…"
}
}Actualizar un producto de otra cuenta devuelve 403 con FORBIDDEN. Ver Errores de la API.
Dónde se usan los productos
El catálogo es tuyo y no está atado a ningún flujo: la mayoría de las integraciones lo usan como fuente de verdad de precios y lo consultan con GET /v1/products/myproducts para armar un selector, una caja o un checkout propio. Que un producto exista no implica que se esté cobrando.
Dentro de Pabilo, hoy el único módulo que lo consume directamente son las suscripciones: al crear una puedes referenciar un producto del catálogo con branchProductId en vez de repetir nombre y precio. Eso te deja cambiar el precio en un solo lugar y que aplique a todos los cobros que lo referencian.
{
"branchProductId": "6a662432d95326f46d526271"
}
// o, sin tocar el catálogo:
{
"uniqueProduct": { "productName": "Plan Premium", "productPrice": 25 }
}El detalle completo está en API de Suscripciones. Para cobros de una sola vez, mira Enlaces de Pago.
Cobros, clientes y productos
Usa el mismo client_id para identificar al comprador, tenga o no credenciales B2B2B. Asócialo en Betaserio, enlaces y suscripciones para consultar lo cobrado por cliente y descargar reportes.
Ver parámetros, ejemplos y API de reportes JSON / CSV