Inbound Webhooks

Inklura receives webhooks from external providers at a set of fixed receiver routes under https://manage.inklura.fr/api/webhooks/* in the company-manager app. Each receiver verifies the provider's signature/secret and then enqueues the event for processing.

There is no self-serve webhook-subscription API — you cannot register your own URL and have Inklura call it. The receivers below are the platform's own integrations. For pushing events out of an app, see Outbound.

How a receiver works

Every receiver follows the same shape:

  1. Provider POSTs to the receiver route.
  2. The receiver verifies the request — a provider signature header or a shared secret.
  3. On success it enqueues onto the webhook queue (a company-manager BullMQ/Redis queue; see Events Overview).
provider ──POST──> /api/webhooks/<provider> ──verify──> enqueue(webhook) ──> worker

Verification is per provider — a bad or missing signature is rejected before anything is enqueued.

Payments

Stripe

Route Notes
/api/webhooks/stripe Core Stripe events
/api/webhooks/stripe/magazine Also triggers the ORDER_MINTED journey
/api/webhooks/stripe/classified-ads Classified-ads payments
/api/webhooks/stripe-subscriptions Subscription lifecycle

Auth: the Stripe-Signature header, verified with STRIPE_WEBHOOK_SECRET via stripe.webhooks.constructEvent.

PayPal / crypto / generic

  • /api/webhooks/paypal
  • /api/webhooks/payments
  • /api/webhooks/cryptocurrency

Commerce

WordPress push

/api/webhooks/wordpress — receives post / page / media / product / order / customer / coupon events pushed from a connected WordPress site.

Auth: an HMAC-SHA256 shared secret. The request carries these headers:

Header Meaning
x-cmgr-key Key identifier
x-cmgr-timestamp Request timestamp
x-cmgr-nonce Nonce
x-cmgr-signature hmac_sha256(secret, payload), hex-encoded
x-cmgr-tenant-id Tenant scope
x-cmgr-site-id Site scope

The signature is computed as hmac_sha256(secret, payload) and compared as a hex string.

Storefronts

  • /api/webhooks/woocommerce
  • /api/webhooks/prestashop/[entity] — per-entity PrestaShop events
  • /api/webhooks/shipping/tracking

Email providers

Bounce / open / complaint (and similar) events from a range of email providers. Each verifies that provider's signature, then enqueues:

resend (svix headers) · mailgun · sendgrid · postmark · ses · sparkpost · sendinblue · socketlabs · mandrill · pepipost

The pattern is identical across them: verify provider signature → enqueue.

Delivery

  • /api/webhooks/ubereats
  • /api/webhooks/deliveroo

Social

Platform events (/api/webhooks/<network>) for: facebook · instagram · linkedin · tiktok · twitter · youtube

Other

  • /api/webhooks/twilio/status — SMS/voice delivery status
  • /api/webhooks/google/ucp
  • /api/webhooks/calendar

No self-serve subscription API

To be explicit: Inklura does not offer a way for you to subscribe an arbitrary URL to platform events. The receivers above are the platform's own provider integrations, each wired to a specific verification scheme and to the internal webhook queue. If you need to react to something, do it from inside your app (loaders/actions, a queue worker, or a scheduled job).

Outbound

Two things exist here, and it's important to be precise about them.

Journey WEBHOOK step — a v1 stub

The journeys engine has a WEBHOOK step type, but in v1 it is a non-functional stub: it does not emit an outbound HTTP request. Do not build on it as if it were working outbound webhooks.

Warning

The journey WEBHOOK step does not send anything in v1. Treat it as not-yet-implemented.

App → external shared-secret push

Individual PRISM tools do push outbound to a tenant's own system, but they do so as bespoke integrations, not through a generic webhook service. The pattern is a plain HTTP POST carrying a shared-secret header that the receiving system checks.

Example: the e-Repas "plat-du-jour" publisher POSTs to the store's own WordPress with the header X-Erepas-Secret, whose per-store value is read from KV at pdj-secret:<host>.

await fetch(`https://${host}/wp-json/erepas/v1/pdj`, {
  method: "POST",
  headers: {
    "X-Erepas-Secret": await sdk.kv.get(`pdj-secret:${host}`),
    "content-type": "application/json",
  },
  body: JSON.stringify(payload),
});

This is the pattern to copy for app→external push: your app POSTs the destination directly and authenticates with a secret the destination already knows.

See also