Recetas

Recetas de API (clientes, tareas, acciones, webhooks) y cómo modelar una barbería, estética, clínica, restaurante y entregas.

Actualizado:

Recetas de API

Todas usan $WAGEND_KEY como en el inicio rápido.

Crear un cliente y reservarle de una vez

Necesita customers:write y bookings:write. El teléfono es el identificador único del cliente: si ya existe, la API responde 409 customer_exists.

curl -X POST https://api.fiuit.com/v1/customers \
  -H "Authorization: Bearer $WAGEND_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Marina", "phone": "+5521988887777", "locale": "pt", "tags": ["vip"],
        "address": { "street": "Rua das Flores", "number": "120", "city": "Rio de Janeiro", "formatted": "Rua das Flores 120, Rio de Janeiro" } }'

curl -X POST https://api.fiuit.com/v1/bookings \
  -H "Authorization: Bearer $WAGEND_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{ "service_id": "svc_corte", "start": "2026-10-15T09:45:00-03:00",
        "customer": { "name": "Marina", "phone": "+5521988887777" } }'

POST /bookings hace la pre-reserva y la confirmación en una sola llamada.

Leer lo que toca hoy

Necesita bookings:read. GET /work-items es la misma consulta que usa la pantalla Hoy.

curl "https://api.fiuit.com/v1/work-items?view=today&limit=50" \
  -H "Authorization: Bearer $WAGEND_KEY"

# Solo lo que nadie tomó todavía
curl "https://api.fiuit.com/v1/work-items?unassigned=true&limit=50" \
  -H "Authorization: Bearer $WAGEND_KEY"

Cada tarea trae su stage y sus available_actions.

Asignar y cerrar una entrega con acciones

Necesita bookings:write. Las acciones llevan el nombre que les da la configuración de etapas del negocio (con el modelo de entregas: atribuir, soltar, iniciar, concluir, nao_estava). Consultalas en GET /stage-config o en available_actions de la tarea.

# Asignar la entrega a un repartidor (resource_id es el recurso del repartidor)
curl -X POST https://api.fiuit.com/v1/bookings/$TASK_ID/actions/atribuir \
  -H "Authorization: Bearer $WAGEND_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{ "data": {}, "resource_id": "'$COURIER_ID'" }'

# Cerrarla como completada
curl -X POST https://api.fiuit.com/v1/bookings/$TASK_ID/actions/concluir \
  -H "Authorization: Bearer $WAGEND_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{ "data": {} }'

Si dos personas toman la misma tarea a la vez, gana una y la otra recibe 409 already_claimed. La acción "Aceptar entrega" (aceitar) es para el personal desde el panel o Telegram: toma la tarea con el recurso de quien la ejecuta.

Recibir avisos por webhook

Registrá un endpoint (ver Webhooks) y verificá la firma antes de procesar. Ejemplo mínimo con Express:

import express from 'express'
import { verifyWagend } from './verify' // la función de la página de Webhooks

const app = express()
app.post('/wagend', express.raw({ type: 'application/json' }), (req, res) => {
  const raw = req.body.toString('utf8')
  if (!verifyWagend(raw, req.header('Wagend-Signature') ?? '', process.env.WAGEND_WEBHOOK_SECRET!)) {
    return res.sendStatus(400)
  }
  const event = JSON.parse(raw)
  if (event.type === 'booking.confirmed') console.log('Nueva reserva', event.data.booking.id)
  res.sendStatus(200) // respondé 2xx rápido; los duplicados se descartan por event.id
})
app.listen(3000)

Modelos por negocio

Cada receta corresponde a un modelo listo que elegís en el onboarding.

Barbería

Cada barbero es un recurso staff exclusive con su propio horario. Un grupo, customer_choice con round_robin como alternativa.

{
  "name": "Corte",
  "duration_min": 30,
  "step_min": 15,
  "buffer_after_min": 5,
  "price_cents": 5000,
  "requirements": [{ "resource_group_id": "grp_barbers", "units": 1 }]
}

Estética

Profesionales, máquinas y cabinas son recursos separados. El servicio pide los tres al mismo tiempo, así que el más escaso (casi siempre la máquina) limita la agenda.

{
  "name": "Depilación láser",
  "duration_min": 45,
  "buffer_after_min": 10,
  "price_cents": 18000,
  "deposit_cents": 5000,
  "requirements": [
    { "resource_group_id": "grp_professionals", "units": 1 },
    { "resource_group_id": "grp_lasers", "units": 1 },
    { "resource_group_id": "grp_rooms", "units": 1 }
  ]
}

Clínica

Médico más consultorio, por sede (un workspace por sede). Los datos de salud son sensibles: el asistente nunca pregunta síntomas y el formulario pide solo lo necesario para reservar.

{
  "name": "Consulta",
  "duration_min": 30,
  "buffer_after_min": 10,
  "intake_form": { "type": "object", "properties": { "obra_social": { "type": "string" } } },
  "requirements": [
    { "resource_group_id": "grp_doctors", "units": 1 },
    { "resource_group_id": "grp_offices", "units": 1 }
  ]
}

Restaurante

El salón es un recurso pooled con 40 unidades (cubiertos) por turno. La duración crece con el tamaño del grupo, y los grupos grandes pagan seña.

{
  "name": "Mesa",
  "step_min": 30,
  "duration_by_units": [
    { "max_units": 2, "duration_min": 90 },
    { "max_units": 4, "duration_min": 120 },
    { "max_units": 20, "duration_min": 150 }
  ],
  "requirements": [{ "resource_group_id": "grp_dining_room", "units": "party_size" }]
}

El modo mesas (mesas puntuales con tamaño mínimo y máximo, y combinaciones) está en el roadmap.

Entregas

Cada zona es un recurso pooled con capacidad por ventana de 2 horas. La zona se elige por código postal, y una regla de corte cierra las ventanas del mismo día al mediodía.

{
  "name": "Entrega",
  "window_mode": true,
  "duration_min": 120,
  "cutoff_rule": { "same_day_until": "12:00" },
  "intake_form": { "type": "object", "required": ["address", "postal_code"] },
  "requirements": [{ "resource_group_id": "grp_zones", "units": 1, "select_by": "postal_code" }]
}