savrsoft

Documentación de la API

Una API REST sencilla para leer y escribir los datos de tu catering, además de webhooks firmados para eventos en tiempo real. Crea una clave en Developer dentro de la app.

Autenticación

Todas las solicitudes a la API usan una clave de API como token portador (bearer token). Crea una en la app en Developer → API keys. Las claves pueden ser solo lectura o lectura/escritura.

curl https://savrsoft.com/api/v1/events \
  -H "Authorization: Bearer savr_live_your_key_here"

URL base: https://savrsoft.com/api/v1 · Todas las respuestas son JSON. Los errores devuelven { "error": "…" } con un estado 4xx/5xx.

Códigos de estado

CódigoCuándo lo recibes
200Lectura exitosa.
201Creado con éxito. El cuerpo es { "id": 42 } — consulta el registro si necesitas el resto de la información.
400Falta un campo obligatorio, por ejemplo { "error": "name is required" }, o no se pudo leer un cursor de paginación.
401Sin clave de API, una con formato incorrecto, o una clave que ha sido revocada.
403Se utilizó una clave de solo lectura para una escritura. Cree una clave de lectura/escritura en Developer → API keys.
404El registro no existe, o pertenece a otra organización — ambos casos son deliberadamente indistinguibles. También se devuelve para una ruta o método no reconocido.

Alcance de esta API

La API es solo de lectura y creación. No hay DELETE, PUT o PATCH endpoints — una solicitud que use uno de estos devuelve 404 Unknown endpoint, igual que cualquier ruta no reconocida. Eliminar y editar se hace en la aplicación, así que una integración no puede destruir los registros de un catering. Si necesita acceso de escritura más allá de la creación, cuéntenos qué está construyendo.

Paginación

Todos los endpoints de listado están paginados. Pase limit (por defecto 100, máximo 500) y siga next_cursor hasta que has_more sea false:

{
  "data": [ ... ],
  "has_more": true,
  "next_cursor": "eyJuYW1lIjoiQWNtZSIsImlkIjo0Mn0"
}

Pase el cursor tal cual para obtener la siguiente página. Trátelo como opaco — la codificación puede cambiar:

curl "https://savrsoft.com/api/v1/clients?limit=100&cursor=eyJuYW1lIjoiQWNtZSIsImlkIjo0Mn0" \
  -H "Authorization: Bearer savr_live_your_key_here"

La paginación se ancla a la última fila recibida, no a un desplazamiento, de modo que las filas creadas o eliminadas mientras se pagina no provocarán que se salte o repita un registro. Un cursor sigue siendo válido indefinidamente.

ParámetroComportamiento
limit1–500. Si está ausente, es cero, negativo o no numérico, se usa 100 por defecto; cualquier valor superior a 500 se limita a 500.
cursornext_cursor de la página anterior. Omítelo para la primera página. Un cursor que no se pueda leer —corrupto o de un endpoint distinto— devuelve 400 Invalid cursor en lugar de reiniciarse silenciosamente desde el principio.

Orden: /events y /invoices del más reciente al más antiguo; /recipes y /clients por nombre, con empates resueltos por id para que la paginación se mantenga estable cuando los nombres se repiten.

Endpoints

GET/v1/me

Tu organización (id, nombre, moneda).

GET/v1/events

Lista de eventos, del más reciente al más antiguo. Paginado — consulta Paginación arriba.

GET/v1/events/{id}

Un evento con sus platos.

POST/v1/events · requiere lectura/escritura

Crea un evento. Cuerpo:

{ "name": "Acme holiday party", "event_date": "2026-12-18",
  "guests": 120, "price_per_head": 55, "event_type": "corporate" }
GET/v1/recipes · GET/v1/recipes/{id}

Lista de recetas (con alérgenos & indicadores de dieta), o una receta con sus ingredientes. La lista está paginada y ordenada por nombre.

GET/v1/clients · POST/v1/clients

Lista de clientes (paginada, por nombre) o creación de uno nuevo. Cuerpo de creación: { "name": "...", "email": "...", "phone": "...", "company": "..." }

GET/v1/invoices · GET/v1/invoices/{id}

Lista de facturas con totales calculados, de más reciente a más antigua, o una factura con sus líneas de detalle. La lista está paginada.

Webhooks

Registra un endpoint en Developer → Webhooks. Enviamos una solicitud POST con un payload JSON cuando ocurren eventos:

{
  "id": "evt_abc123",
  "type": "event.inquiry",
  "created_at": "2026-07-17T18:20:00.000Z",
  "data": { "id": 42, "name": "Corporate lunch — Dana Ruiz", ... }
}

Tipos de evento

TipoSe activa cuando
event.createdSe crea un evento
event.inquiryLlega una nueva solicitud de catering en línea
invoice.sentUna factura se marca como enviada
invoice.paidUna factura se marca como pagada
proposal.approvedUn cliente aprueba una propuesta
client.createdSe crea un cliente

Verificación de firmas

Cada entrega incluye un encabezado x-savrsoft-signature : el HMAC-SHA256 del cuerpo de la solicitud sin procesar, firmado con tu clave secreta de webhook. Calcula lo mismo y compara:

// Node.js
const crypto = require('crypto');
const sig = crypto.createHmac('sha256', SIGNING_SECRET)
  .update(rawBody).digest('hex');
if (sig !== req.headers['x-savrsoft-signature']) reject();
Privacidad · Seguridad · Términos · ¿Preguntas? savrsoft.com · Crea integraciones de catering en minutos.