Para que tu CRM, tu TPV o tu programa de clínica hable con StarIA: consultar la agenda, crear y mover reservas, dar de alta clientes y enterarse al momento de lo que pasa.
Si tienes un negocio: qué es esto y a quién se lo pasas
Una API es una puerta para que dos programas se entiendan solos. Si ya usas otro programa (un CRM, un TPV, el programa de tu clínica o tu propia web) y quieres que las reservas que coge StarIA aparezcan allí, o que lo que se apunta allí llegue a StarIA, esta es la forma.
No tienes que entender lo que viene después. Pásale esta página a tu informático o a la empresa que te lleva el programa. Solo necesitan dos cosas que sacas tú del panel:
Una clave de acceso
Como una llave: quien la tenga entra en los datos de tu negocio. Puedes darla «solo para consultar» o «para consultar y hacer cambios», y retirarla cuando quieras.
Los avisos (opcional)
Si tu informático te da una dirección web, StarIA avisará ahí al momento cada vez que entre, se mueva o se anule una reserva, o cuando el agente atienda una llamada.
Dónde se crean: en tu panel de StarIA, entra en Configuración → Integraciones → Conectar otros programas. Pulsa «Crear clave», ponle un nombre (por ejemplo «TPV») y copia la clave que aparece: solo se enseña una vez. Solo el dueño o un administrador del negocio puede crearlas.
¿Usas Zapier o Make? Con ellos conectas StarIA con cientos de programas (Holded, Mailchimp, HubSpot, Google Sheets…) sin programar: solo pegas la clave. Mira Zapier y Make.
¿No tienes informático o tu programa no se puede conectar? Escríbenos a ayuda@staria.es y te decimos cómo lo hacemos.
Empezar
API REST con JSON. Todas las rutas cuelgan de esta URL base y solo se aceptan peticiones por HTTPS:
Los nombres de campos van en inglés y snake_case. Los importes, en euros. Los identificadores son UUID. La descripción completa en OpenAPI 3.1 está en /openapi.json.
Autenticación y permisos
Cada petición lleva la clave en la cabecera Authorization. Cada clave pertenece a un único negocio y solo ve sus datos.
Producción. Lo que se crea es real y el cliente recibe sus confirmaciones.
sk_test_…
Pruebas. Trabaja con los datos reales del negocio, pero lo que se crea queda marcado como prueba (test: true) y no se avisa a ningún cliente.
Permiso
Qué puede hacer
read
Solo consultar (peticiones GET). Cualquier cambio devuelve 403 forbidden.
write
Consultar y además crear o cambiar reservas y clientes (POST, PATCH).
La clave se guarda cifrada (solo su huella): si se pierde no se puede recuperar; se retira en el panel y se crea otra. No la pongas nunca en código que se ejecute en el navegador o en una app móvil.
Límites y errores
Límite: 120 peticiones por minuto y clave. Al pasarlo se responde 429 con la cabecera Retry-After (segundos que faltan para el minuto siguiente).
Todos los errores tienen la misma forma:
{
"error": {
"code": "slot_unavailable",
"message": "Ese hueco ya no está libre."
}
}
HTTP
code
Cuándo
400
invalid_request
Falta un dato o no tiene el formato correcto. El mensaje dice cuál.
401
unauthorized
Falta la clave, no es válida o se ha retirado.
403
forbidden
La clave es de solo lectura y la petición intenta cambiar algo.
404
not_found
No existe (o no es de este negocio).
409
slot_unavailable
El hueco ya no está libre. Consulta /availability y ofrece otra hora.
429
rate_limited
Más de 120 peticiones por minuto. Espera los segundos de Retry-After.
500
internal_error
Error nuestro. Reintenta; si se repite, escribe a ayuda@staria.es.
503
unavailable
Servicio no disponible por ahora. Reintenta en unos minutos.
Fechas y paginación
Las fechas con hora van en ISO 8601 con el desfase de Madrid (Europe/Madrid), por ejemplo 2026-10-06T17:30:00+02:00; en invierno el desfase es +01:00. Los días sueltos van como YYYY-MM-DD y se entienden en hora de Madrid.
Las listas se paginan con limit (máximo 100) y un cursor. Cada respuesta trae next_cursor; pásalo como cursor para la página siguiente. Cuando es null, no hay más.
Los profesionales del negocio y los recursos reservables (mesas, cabinas, boxes…). En un restaurante, las mesas son recursos con su capacidad y su zona.
start (por defecto, por hora de la cita) · -created_at (las últimas que han entrado) · -updated_at (las últimas que han cambiado). Con -created_at o -updated_at y sin from/to no se filtra por fechas.
Crea una reserva. La hora se da con start (ISO 8601) o con date + time (hora de Madrid). El cliente, con customer_id o con los datos de customer (se reutiliza la ficha si el teléfono ya existe). Si el hueco ya no está libre responde 409 slot_unavailable. El cliente recibe la confirmación habitual (salvo con claves sk_test_).
Cuerpo (JSON)
Nombre
Tipo
Obligatorio
Descripción
service_id
uuid
Sí (no en restaurantes)
Servicio reservado.
start
ISO 8601
Uno de los dos
Inicio, p. ej. 2026-10-06T17:30:00+02:00.
date + time
YYYY-MM-DD + HH:mm
Uno de los dos
Alternativa a start, en hora de Madrid.
customer_id
uuid
Uno de los dos
Cliente ya existente.
customer
objeto
Uno de los dos
{ name, phone, email? } para un cliente nuevo o sin id.
professional_id
uuid
No
Profesional concreto. Si no se indica, se asigna uno libre.
{
"data": [
{
"id": "6f5e4d3c-2b1a-4098-8765-43210fedcba9",
"customer_name": "Luis Pardo",
"customer_phone": "+34699111222",
"message": "Que le llamen para cambiar la cita del jueves.",
"channel": "voice",
"created_at": "2026-09-29T12:15:40+02:00",
"done": false
}
],
"next_cursor": null
}
POST/webhookspermiso write
Suscribe una dirección a los avisos sin pasar por el panel (lo que hacen Zapier y Make al encender una automatización: «REST hooks»). Los avisos llegan igual que a las direcciones del panel. La respuesta trae el secret para comprobar la firma: solo se enseña esta vez. Con una clave sk_test_ solo llegan avisos de reservas de prueba, y con una sk_live_ nunca llegan. Si se retira la clave, la suscripción deja de recibir avisos. Como mucho 50 por negocio.
Cuerpo (JSON)
Nombre
Tipo
Obligatorio
Descripción
url
texto
Sí
Dirección https:// pública que recibirá los avisos.
events
lista de texto
No
Eventos a recibir (ver la tabla de avisos). Vacía o sin enviar = todos.
source
texto
No
zapier · make · api (por defecto). El negocio lo ve en su panel.
Las suscripciones creadas por API con claves del mismo tipo (reales o de pruebas), sin su secreto. Las direcciones que el negocio añadió a mano en el panel no salen aquí.
Borra una suscripción creada por API (lo que hacen Zapier y Make al apagar la automatización). Las direcciones creadas en el panel no se pueden borrar desde aquí.
Servicio reservado (puede faltar en restaurantes).
professional
{ id, name } | null
Profesional asignado.
resource
{ id, name } | null
Recurso (mesa, cabina…).
party_size
entero | null
Comensales (restaurantes).
customer
{ id, name, phone, email }
Cliente.
notes
texto | null
Notas.
deposit
{ status, amount } | null
Señal: estado (pending, paid, expired…) e importe en euros.
test
boolean
true si se creó con una clave de pruebas.
created_at / updated_at
ISO 8601
Alta y último cambio.
Customer (cliente)
Campo
Tipo
Descripción
id
uuid
Identificador.
first_name / last_name / name
texto
Nombre, apellidos y nombre completo.
phone
texto
Teléfono en formato internacional (+34…).
email
texto | null
Email.
notes
texto | null
Notas internas.
marketing_opt_in
boolean
Acepta promociones.
do_not_contact
boolean
Pidió que no se le contacte: no le mandes nada.
total_bookings
entero
Reservas que ha hecho.
created_at / updated_at
ISO 8601
Alta y último cambio.
Call (llamada)
Campo
Tipo
Descripción
id
uuid
Identificador.
direction
texto
inbound · outbound
caller_phone
texto | null
Teléfono de quien llama.
duration_seconds
entero
Duración.
outcome
texto | null
Resultado (reserva hecha, recado, información…).
summary
texto | null
Resumen de la llamada.
booking_id / customer_id
uuid | null
Reserva y cliente relacionados, si los hay.
started_at / ended_at
ISO 8601
Inicio y fin.
Message (recado)
Campo
Tipo
Descripción
id
uuid
Identificador.
customer_name / customer_phone
texto
Quién deja el recado y dónde devolverle la llamada.
message
texto
El recado.
channel
texto
phone · whatsapp
created_at
ISO 8601
Cuándo se tomó.
done
boolean
Si el negocio ya lo ha atendido.
Avisos (webhooks)
StarIA hace un POST con JSON a la dirección que el negocio configure en el panel cada vez que pasa algo, venga de donde venga el cambio (web, teléfono, WhatsApp, panel o la propia API). Se puede elegir a qué eventos suscribirse; sin elegir, llegan todos.
Evento
Cuándo
data
booking.created
Reserva nueva.Entra una reserva por cualquier canal.
Booking
booking.rescheduled
Reserva movida.Cambia la fecha o la hora de una reserva.
Booking
booking.cancelled
Reserva anulada.El cliente o el negocio anula una reserva.
Booking
booking.confirmed
Reserva confirmada.Una reserva pendiente pasa a confirmada.
Booking
booking.completed
Cita realizada.La cita se marca como hecha.
Booking
booking.no_show
No se presentó.El cliente no vino.
Booking
payment.succeeded
Señal pagada.El cliente paga la señal de su reserva.
Booking
customer.created
Cliente nuevo.Se crea un cliente en StarIA.
Customer
call.completed
Llamada atendida.El agente de voz termina una llamada.
Call
message.taken
Recado apuntado.El agente toma un recado para el negocio.
Message
ping
Aviso de prueba.Lo manda el botón «Probar» del panel.
{ message }
Qué llega
Un sobre común { id, event, created_at, test, data } y tres cabeceras: StarIA-Event (el evento), StarIA-Delivery (id del aviso, el mismo que id) y StarIA-Signature (la firma). test es true en los avisos de prueba y en lo creado con claves sk_test_.
Al crear la dirección, el panel enseña una vez su clave de firma (whsec_…). Cada aviso lleva StarIA-Signature: t=<segundos>,v1=<hex>, donde v1 es el HMAC-SHA256, con esa clave, de "<t>.<cuerpo tal cual>" en hexadecimal. Para darlo por bueno:
Calcula el HMAC sobre el cuerpo crudo, antes de parsear el JSON.
Compáralo con v1 en tiempo constante.
Rechaza el aviso si t se aleja más de 300 segundos de tu hora actual (evita que alguien reenvíe un aviso viejo).
Node.js (Express)
import crypto from 'node:crypto'
import express from 'express'
const app = express()
const SECRETO = process.env.STARIA_WEBHOOK_SECRET // whsec_…
// Ojo: la firma se calcula sobre el cuerpo TAL CUAL llega (sin parsear).
app.post('/avisos-staria', express.raw({ type: 'application/json' }), (req, res) => {
const cabecera = req.get('StarIA-Signature') ?? ''
const partes = Object.fromEntries(cabecera.split(',').map((p) => p.trim().split('=')))
const t = Number(partes.t)
if (!t || Math.abs(Date.now() / 1000 - t) > 300) return res.sendStatus(400)
const cuerpo = req.body.toString('utf8')
const esperado = crypto.createHmac('sha256', SECRETO).update(`${t}.${cuerpo}`).digest('hex')
const a = Buffer.from(esperado)
const b = Buffer.from(partes.v1 ?? '')
if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) return res.sendStatus(400)
const aviso = JSON.parse(cuerpo)
// Si ya procesaste aviso.id, no lo repitas: contesta 200 igualmente.
res.sendStatus(200) // contesta rápido y procesa después (cola, tarea en segundo plano…)
})
Contesta con cualquier 2xx en menos de 10 segundos. Si tienes que hacer algo largo, guarda el aviso y procésalo después.
Si no contestas o contestas otra cosa, se reintenta tras 1 min, 5 min, 30 min, 2 h, 6 h y 12 h (7 intentos en total). Después se da por fallido.
Tras 50 fallos seguidos la dirección se pausa sola y el negocio lo ve en el panel; al reactivarla se pone el contador a cero.
Los avisos pueden llegar desordenados o repetidos. Guarda los id ya procesados y descarta los duplicados; para saber el estado actual de una reserva, fíate de su updated_at o pídela con GET /bookings/{id}.
Solo se admiten direcciones https:// públicas (no IP privadas, localhost ni redes internas).
El panel enseña los últimos 20 avisos de cada dirección con su estado, para depurar.
Suscribirse por API (REST hooks)
Además del panel, un programa puede darse de alta él solo con POST /webhooks y darse de baja con DELETE /webhooks/{id} (ver Endpoints). Es lo que hacen Zapier y Make. El negocio las ve en su panel con el nombre de quien las creó y puede pausarlas o borrarlas.
Zapier y Make
StarIA tiene conector propio para Zapier y para Make. Con ellos, cuando entra una reserva, se anula, el agente atiende una llamada o toma un recado, puedes mandarlo a Holded, Mailchimp, HubSpot, Google Sheets, Slack… y al revés: crear reservas o clientes en StarIA desde otro programa.
Qué incluye
Disparadores
Reserva nueva, movida, anulada, confirmada o completada; no se presentó; cliente nuevo; llamada atendida; recado tomado. Llegan al momento (avisos), no cada 15 minutos.
Acciones
Crear una reserva; mover, anular, confirmar o cerrar una reserva; crear o actualizar un cliente.
Búsquedas
Buscar un cliente (por teléfono, email o nombre) y buscar una reserva.
Crea una clave en el panel (Configuración → Integraciones → Conectar otros programas). Si la automatización va a crear o cambiar cosas, elige «consultar y hacer cambios»; para los disparadores también hace falta, porque la suscripción a los avisos es un cambio.
En Zapier o en Make, añade StarIA, elige «Conectar» y pega la clave.
Para probar sin tocar la agenda real, usa una clave sk_test_: lo que crees será de prueba y solo recibirás avisos de reservas de prueba.
De momento los conectores se comparten por invitación: pídela a ayuda@staria.es. Por dentro usan esta misma API (/me para comprobar la clave, /webhooks para los avisos y los listados con sort=-created_at para enseñar ejemplos).