Endpoints
All public endpoints live under https://bridge.envara.ae/api/public.
POST /api/public/ingest/{source}/{event}
The single endpoint you'll use 99% of the time. Accepts any signed event for any source/event combination.
Path parameters
{source}— platform identifier (woocommerce,shopify,generic, or your own).{event}— dotted event name (order.created,user.signup, etc.).
Headers
bash
Content-Type: application/jsonX-Envara-Site-Key: ec_live_xxxxxxxx...X-Envara-Signature: sha256=<hex hmac>X-Envara-Timestamp: 1731234567X-Envara-Idempotency-Key: order:1042:created # optionalX-Envara-Mode: test # optional: dry-run onlyBody
Any JSON. See Event envelope for the recommended shape.
Response — 200 OK
json
{ "ok": true, "event": "order.created", "event_id": "8a3f...c1", "order_id": "uuid-or-null", "whatsapp": "sent", "bindings_run": 1, "recipients_sent": 1, "recipients_failed": 0}The whatsapp field is one of:
sent— all recipients delivered to Meta successfully.partial— some succeeded, some failed.failed— all failed.no_bindings— event accepted but no binding is configured (set up one in the dashboard).skipped_no_phone— no recipient phone could be resolved.skipped_no_config— WhatsApp Cloud credentials not configured.
Response — error
json
{ "error": "Invalid signature" }See Errors for the full list.
Dry-run mode
With X-Envara-Mode: test, the endpoint returns a previews array showing exactly which bindings would fire, the recipients resolved, and the slot values — without calling Meta.
json
{ "ok": true, "event": "order.created", "event_id": "8a3f...c1", "whatsapp": "skipped_no_config", "bindings_run": 1, "dry_run": true, "previews": [ { "binding_id": "uuid", "template": "order_confirmation_v1", "language": "en", "recipients": ["+9715XXXXXXXX"], "slots": { "header": ["Acme"], "body": ["Ada", "1042", "AED 199.00"], "buttonUrl": [] }, "resolved": true } ]}OPTIONS /api/public/ingest/{source}/{event}
CORS preflight. Returns 204 with permissive headers. You should not need to call this directly — browsers do it automatically.
GET /api/public/health
Returns 200 with a small JSON body. Use it for uptime probes — no auth required.
