What a subscription is
One subscription binds three things together: where events go (your URL), which events go there (the event types you select), and how each delivery is signed (a secret generated for that subscription alone).
You can have several. Two subscriptions in the same account are fully independent — separate URLs, separate event selections, separate secrets. Rotating or leaking one does not touch the other.
Creating one
A create takes a name, a URL, and the event types you want. The response is the only time you will see the signing secret.
curl -X POST https://api.mesh.locate2u.app/api/subscriptions \
-H "Authorization: Bearer $MESH_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "fulfilment-service",
"webhook_url": "https://example.com/webhooks/mesh",
"event_types": ["stop.completed", "stop.failed", "package.delivered"]
}'
The create response contains signing_secret in cleartext. No later read returns it — GET on the subscription omits it entirely. Store it when you receive it. If you lose it, rotate rather than recreate.
The signing secret
Every delivery carries an X-Mesh-Signature header computed with this secret, so your endpoint can prove a request genuinely came from Mesh. Checking it is optional but strongly worth it for an endpoint that acts on what it receives.
Rotation issues a new secret and returns it once, on the same terms as create. The full explanation — what the header contains, what is signed, and worked verification code — is on Verifying webhook signatures.
Authenticating to your endpoint
Separately from signing, you can tell Mesh how to authenticate to your endpoint. This is the credential we present when calling you:
| Type | What Mesh sends |
|---|---|
| none | No credentials. Correct for an endpoint that accepts anything — and the case where checking the signature matters most. |
| bearer | An Authorization: Bearer header with a token you supply. |
| basic | HTTP basic auth with a username and password you supply. |
| api_key_header | A header name and value you choose. |
| oauth2_client_credentials | A token Mesh fetches with the client credentials grant and refreshes as needed. |
Destination auth is how we prove ourselves to you. The signature is how you verify us. They are independent, and every delivery is signed regardless of which destination auth you pick — including none.
Listing, updating, revoking
| Call | Does |
|---|---|
| GET /api/subscriptions | Lists your subscriptions, cursor-paginated. Never includes secrets. |
| GET /api/subscriptions/{id} | Fetches one. Returns the destination auth type and config, never its secret. |
| PATCH /api/subscriptions/{id} | Updates the URL, the event types, the destination auth, or the active flag. |
| POST /api/subscriptions/{id}/rotate-secret | Issues a new signing secret and returns it once. |
| DELETE /api/subscriptions/{id} | Revokes the subscription. Deliveries stop. |
Pausing rather than deleting is usually what you want during maintenance: set the subscription inactive with a PATCH, and turn it back on when your endpoint is healthy. Deleting is permanent and loses the secret with it.
Before you go live
- Return 2xx quickly. Acknowledge, then process out of band. See how delivery works.
- Deduplicate on event_id. Delivery is at-least-once and you will receive the same event twice eventually.
- Compare version, not timestamps, when deciding whether an event is newer than your stored state.
- Tolerate unknown event types. New types are added over time; ignore what you do not recognise rather than failing the request, which would dead-letter it.
- Read the raw body before parsing if you verify signatures — a re-serialised object will not match.