fluyio.
Webhooks (próximamente)

Webhooks: visión general (borrador)

Borrador técnico en inglés del modelo previsto de webhooks. No es un servicio operativo.

Borrador técnico en inglés · no operativo

Los webhooks salientes todavía no entregan eventos. El cuerpo en inglés que sigue conserva una propuesta técnica: no es un contrato publicado ni una guía para activar una función disponible. No implementes una integración de producción contra estos ejemplos. La API pública actual ofrece suscriptores; consulta la hoja de ruta.

Webhooks let Fluyio push events to your server the moment something happens in your account — a subscriber is created, a campaign is sent, a WhatsApp message is delivered. Instead of polling the API every few seconds, you give us a URL and we deliver a signed HTTP POST whenever a matching event occurs.

If you have ever integrated Stripe or Twilio webhooks, the model is identical: register an endpoint, subscribe to a list of event types, verify the signature on each delivery, and respond with 2xx.

How it works

┌──────────────┐    event happens    ┌──────────────┐    HTTPS POST    ┌──────────────┐
│   Fluyio     │ ──────────────────▶ │   Delivery   │ ───────────────▶ │ Your server  │
│   backend    │                     │    queue     │  (signed JSON)   │   /webhooks  │
└──────────────┘                     └──────────────┘                  └──────────────┘
                                            ▲                                  │
                                            │      retry on non-2xx            │
                                            └──────────────────────────────────┘
  1. Something happens in Fluyio — a subscriber is added to a list, a campaign finishes sending, a flow step fails.
  2. Fluyio enqueues a delivery for every endpoint that is subscribed to that event type.
  3. We sign the payload with your endpoint secret and POST it to your URL.
  4. Your server returns 200 OK. If it doesn't, we retry with exponential backoff for up to ~37 hours.

Webhooks complement the API — they don't replace it. Use the API to fetch state on demand, and webhooks to react to changes as they happen.

Setup in 4 steps

Create an endpoint on your server

Expose an HTTPS URL that accepts POST requests with a JSON body. Keep the handler fast: respond 200 OK immediately and process the payload asynchronously.

// pages/api/webhooks/fluyio.ts (Next.js)
export default function handler(req, res) {
  // verify and enqueue, then:
  res.status(200).send('ok');
}

Register the endpoint with Fluyio

Open Webhooks in the dashboard and click Add endpoint. Pick the events you care about — avoid subscribing to * unless you really need every event. There is no public API for managing endpoints yet; it is on the roadmap.

The dashboard shows the endpoint secret (it starts with whsec_) exactly once. Store it in your environment — you cannot retrieve it again, only rotate it.

Verify the signature on every delivery

Each request includes a Fluyio-Signature header. Compute an HMAC SHA-256 of ${timestamp}.${raw_body} with your endpoint secret and compare it with the v1 value in the header. See verifying signatures for the full algorithm.

Respond 200 OK within 10 seconds

Any non-2xx response (or a timeout over 10s) is treated as a failure and will be retried. Defer heavy work to a background queue — the webhook handler should only verify, persist, and acknowledge.

Payload structure

Every webhook body has the same envelope:

{
  "id": "evt_whk_01H8YQK7Z6N6P3K4M9C1RG2X4T",
  "type": "subscriber.created",
  "created": 1715000000,
  "api_version": "2026-05-15",
  "data": {
    "object": {
      "id": "sub_01H8YQK7Z6N6P3K4M9C1RG2X4T",
      "email": "[email protected]",
      "first_name": "Ada",
      "last_name": "Lovelace",
      "created_at": "2026-05-15T12:00:00Z"
    }
  }
}
FieldTypeDescription
idstringUnique event ID. Prefixed evt_whk_. Use it for idempotency.
typestringEvent name in resource.action form. See the events catalog.
createdintegerUnix timestamp (seconds) when the event was emitted by Fluyio.
api_versionstringAPI version that shaped the data payload.
data.objectobjectThe resource that changed, in its current state.

data.object will follow the API version current when delivery ships (2026-05-15 today). Per-endpoint version pinning is not available yet.

Quick receivers

A minimal receiver in your language of choice. Each example skips signature verification for brevity — production code must verify every request.

import express from 'express';
const app = express();

app.post(
  '/webhooks/fluyio',
  express.raw({ type: 'application/json' }),
  (req, res) => {
    const event = JSON.parse(req.body.toString());

    switch (event.type) {
      case 'subscriber.created':
        console.log('new subscriber', event.data.object.email);
        break;
      case 'campaign.message.bounced':
        console.log('bounce', event.data.object);
        break;
    }

    res.status(200).send('ok');
  },
);

app.listen(3000);

Local development

The internet can't POST to localhost. Use a tunneling tool while developing:

  • ngrok — ngrok http 3000 gives you a public HTTPS URL you can paste into the dashboard.
  • Cloudflared — free alternative.
  • webhook.site — inspect raw deliveries without writing any code.

Once delivery is active, point a temporary endpoint at the tunnel URL to inspect real payloads.

Where to next

En esta página