Artículos sobre: Inteligencia artificial (IA)
Este artículo también está disponible en:

Webhooks salientes

Los webhooks te permiten conectar Fotostudio a herramientas externas como Make, Zapier, n8n o tu propio backend. En cada evento importante (nuevo contacto, factura pagada, contrato firmado...), Fotostudio envía automáticamente los datos a la URL de tu elección.



Configurar un webhook


Ve a Módulos → Webhooks salientes y haz clic en Nuevo webhook.


Completa los siguientes campos:


Campo

Descripción

Etiqueta

Un nombre para orientarte (ej: "Make – facturas")

URL de destino

La URL HTTPS proporcionada por tu herramienta (Make, Zapier...)

Eventos

Los eventos a escuchar (puedes marcar varios)


Un secreto se genera automáticamente al crear. Cópialo inmediatamente: no se mostrará de nuevo. Sirve para verificar que las llamadas vienen de Fotostudio.



Eventos disponibles


Evento

Se activa cuando...

contact.created

Se crea un nuevo contacto

contact.updated

Se modifica un contacto (datos, información...)

project.created

Se crea una nueva sesión

project.status_changed

Cambia el estado de una sesión

project.confirmed

Se confirma una sesión

invoice.created

Se crea una factura

invoice.paid

Se marca una factura como pagada

payment.created

Se registra un pago

estimate.accepted

Un presupuesto es aceptado por el cliente

estimate.refused

Un presupuesto es rechazado por el cliente

contract.signed

Se firma un contrato



Formato de los datos enviados


Cada llamada es un POST en JSON con la siguiente estructura:


{
"event": "invoice.paid",
"timestamp": "2026-06-12T10:30:00Z",
"data": {
...
}
}


Encabezados HTTP


Header

Valor

Content-Type

application/json

X-FS-Event

Nombre del evento (ej: invoice.paid)

X-FS-Signature

sha256=<hmac> (firma HMAC-SHA256 del body)

X-FS-Delivery-Id

Identificador único de la entrega


Verificar la firma


La firma en X-FS-Signature se calcula así:


HMAC-SHA256(secret, body_json)


En Node.js por ejemplo:


const crypto = require('crypto')
const sig = 'sha256=' + crypto.createHmac('sha256', SECRET).update(rawBody).digest('hex')
if (sig !== req.headers['x-fs-signature']) throw new Error('Firma inválida')



Detalle de los datos por evento


contact.created / contact.updated


{
"id": 123,
"firstname": "Marie",
"lastname": "Dupont",
"email": "marie@example.com",
"phone": "+33 6 12 34 56 78",
"company": "Studio Photo",
"street": "12 rue de la Paix",
"zipcode": "75001",
"city": "Paris",
"country": "France",
"created_at": "2026-01-15T09:00:00Z",
"url": "https://www.fotostudio.io/app/contacts/123"
}


project.created / project.status_changed / project.confirmed


{
"id": 456,
"name": "Boda Dupont",
"start_time": "2026-07-20T14:00:00Z",
"end_time": "2026-07-20T18:00:00Z",
"project_type": "Boda",
"status": "Confirmado",
"validated": true,
"location": "Castillo de Versalles",
"contact_id": 123,
"created_at": "2026-01-15T09:00:00Z",
"url": "https://www.fotostudio.io/app/projects/456"
}


invoice.created / invoice.paid


{
"id": 789,
"numero": "F2026-042",
"title": "Boda Dupont",
"invoice_date": "2026-06-01",
"total_price": 1500.00,
"amount_to_pay": 750.00,
"paid": false,
"draft": false,
"contact_id": 123,
"project_id": 456,
"created_at": "2026-06-01T10:00:00Z",
"url": "https://www.fotostudio.io/app/invoices/789"
}


amount_to_pay es el saldo pendiente de pago (total - pagos ya recibidos).


payment.created


{
"id": 101,
"amount": 750.00,
"payment_date": "2026-06-10",
"payment_type": "Transferencia",
"invoice_id": 789,
"contact_id": 123,
"created_at": "2026-06-10T14:00:00Z"
}


estimate.accepted / estimate.refused


{
"id": 202,
"numero": "D2026-018",
"title": "Boda Dupont",
"total_price": 1500.00,
"accepted": true,
"refused": false,
"accepted_at": "2026-06-05T16:00:00Z",
"contact_id": 123,
"project_id": 456,
"created_at": "2026-05-20T09:00:00Z",
"url": "https://www.fotostudio.io/app/estimates/202"
}


contract.signed


{
"id": 303,
"title": "Contrato Boda Dupont",
"signed_at": "2026-06-08T11:30:00Z",
"project_id": 456,
"contact_id": 123,
"created_at": "2026-05-25T10:00:00Z",
"url": "https://www.fotostudio.io/app/contracts/303"
}



Historial de entregas


En la ficha de cada webhook, la pestaña Logs muestra el historial de llamadas con:


  • la fecha y hora
  • el evento activado
  • el estado (éxito / fallo)
  • el código HTTP de respuesta
  • el mensaje de error en caso de fallo


En caso de fallo, Fotostudio reintenta automáticamente hasta 3 veces con un retraso exponencial. También puedes relanzar manualmente una llamada desde los logs.



Usar con Make


  1. En Make, crea un nuevo escenario y añade un módulo Webhooks → Custom webhook.
  2. Copia la URL generada por Make.
  3. En Fotostudio, crea un webhook con esa URL y selecciona los eventos que quieras recibir.
  4. Activa un evento de prueba desde Fotostudio (por ejemplo, crea un contacto).
  5. Make recibirá los datos. Después podrás crear tu automatización.



Usar con Zapier


  1. En Zapier, crea un nuevo Zap y elige Webhooks by Zapier → Catch Hook como desencadenante.
  2. Copia la URL proporcionada por Zapier.
  3. En Fotostudio, crea un webhook con esa URL.
  4. Activa un evento de prueba. Zapier detectará automáticamente la estructura de los datos.
  5. Configura la acción que desees (Google Sheets, Notion, Slack, etc.).



Preguntas frecuentes


¿Qué ocurre si mi servidor no está disponible?
Fotostudio vuelve a intentarlo 3 veces con un intervalo cada vez mayor. Después de 3 intentos, la entrega se marca como fallida, pero permanece registrada en los logs. Puedes volver a enviarla manualmente.


¿En cuánto tiempo debe responder mi webhook?
Tu endpoint debe responder en un plazo de 10 segundos. Si tarda más, la solicitud se considera fallida.


¿Puedo tener varios webhooks?
Sí. Puedes crear tantos webhooks como quieras, cada uno con sus propios eventos y su propia URL.


¿Cómo puedo desactivar temporalmente un webhook?
En la lista de webhooks, utiliza el interruptor para activar o desactivar un webhook sin necesidad de eliminarlo.

Actualizado el: 29/06/2026

¿Este artículo te resultó útil?

Comparte tu opinión

Cancelar

¡Gracias!