Inbound Webhooks
Inbound webhooks let you receive events from external services, verify their signatures, transform payloads, and fan out to your endpoints. Mittr ships 130+ platform presets with automatic signature verification.
How it works
Section titled “How it works”- Create an inbound endpoint with a unique path and select a platform preset
- Copy the generated URL and register it as the webhook in the source platform
- The source posts webhooks to
https://app.mittr.io/inbound/{path} - Mittr verifies the source signature using the preset’s verification mode
- Optionally transforms the payload
- Fans out to configured destination endpoints
Create an inbound endpoint
Section titled “Create an inbound endpoint”curl -X POST https://app.mittr.io/api/v1/inbound-endpoints \ -H "X-API-Key: mtr_your_key" \ -H "Content-Type: application/json" \ -d '{ "name": "GitHub Webhooks", "pathSuffix": "github-prod", "source": "github", "sourceConfig": { "secret": "your-github-webhook-secret" }, "destinationIds": ["endpoint-uuid-1", "endpoint-uuid-2"], "eventTypeMapping": "$.headers.X-GitHub-Event" }'The webhook URL becomes: https://app.mittr.io/inbound/github-prod
Register the URL with the source platform
Section titled “Register the URL with the source platform”Creating the inbound endpoint only sets up the receiver. The source service won’t send anything until you tell it where to post — so copy the generated URL and add it as the webhook URL in the source platform’s developer / webhook settings. Depending on the platform it may be called the webhook, listener, notification, or Connect URL.
| Platform | Where to add the URL (wording varies by version) |
|---|---|
| DocuSign | Settings → Connect → Add Configuration → URL to Publish to |
| GitHub | Repo or Org → Settings → Webhooks → Payload URL |
| Stripe | Developers → Webhooks → Add endpoint → Endpoint URL |
| Shopify | Settings → Notifications → Webhooks |
Paste the exact URL Mittr generated (e.g. https://app.mittr.io/inbound/github-prod). If the platform lets you choose which events to send, pick the ones you need — Mittr accepts them all. Many platforms send a test/verification ping when you save; that shows up as your first inbound event.
See incoming events
Section titled “See incoming events”Prerequisite: the inbound endpoint must have at least one destination wired (see Destination forwarding). Inbound webhooks only become events by fanning out to those destinations — with none configured, nothing appears here even though the request was received and verified.
Once the source starts posting (and a destination is set), watch them arrive in the dashboard:
- Events — each forwarded event, newest first. Click a row for the payload, headers, and per-destination delivery attempts.
- Attempts — each forward to your destination endpoints with its HTTP status code and response body.
Events appear under the same project the inbound endpoint belongs to. If the list looks empty, confirm the project switcher matches the endpoint’s project and widen the time-range filter.
Nothing showing up? The most common cause is a signature mismatch — the source’s secret/key doesn’t match the
sourceConfigon the endpoint, so Mittr rejects the request before it becomes an event. Re-check the verification credentials, or temporarily set the mode tononeto confirm delivery, then turn verification back on.
Source doesn’t support webhooks?
Section titled “Source doesn’t support webhooks?”Inbound only works if the source can push — Mittr doesn’t poll external services for you. If a source has no webhooks, bridge it with a small scheduled job (cron / serverless function) that polls the source’s API and posts each new record to Mittr’s event API:
curl -X POST https://app.mittr.io/api/v1/events \ -H "X-API-Key: mtr_your_key" \ -H "X-Idempotency-Key: paynecta-inv-1a2b3c" \ -H "Content-Type: application/json" \ -d '{ "eventType": "invoice.paid", "payload": { "id": "inv_123", "amount": 4200 } }'X-Idempotency-Keyis required and must be deterministic (see below). A repeat key returns the original event (HTTP 409) instead of creating a new one, so overlapping poll runs or retries can’t duplicate.- Provide
eventTypeto fan out to subscribed endpoints, ordestination(a URL) for direct one-off delivery. One of the two is required, alongside a non-emptypayload. - For a poll that returns many new records at once,
POST /api/v1/events/batchaccepts up to 100 direct-delivery events in a single call.
Choosing the idempotency key
Section titled “Choosing the idempotency key”The same source record must always produce the same key — never a random value — so a re-poll or retry dedups instead of duplicating. In order of preference:
- The source record’s stable ID, namespaced:
paynecta:inv_123
- ID + state, if the same record produces multiple events as it changes — include the status/version so each transition is its own event but each transition is still dedup’d:
paynecta:inv_123:paid, then laterpaynecta:inv_123:refunded- DocuSign:
docusign:{envelopeId}:{status}(e.g....:completed)
- No stable ID at all → synthesize one deterministically by hashing the meaningful fields:
key = sha256(stableJSON({...the fields that define this event...}))- Same content → same hash → same key. Exclude volatile fields (fetch time, pagination cursors) or you’ll defeat dedup.
From there Mittr handles signing, retries, and delivery exactly as it does for inbound — you’re just supplying the events yourself instead of receiving a webhook.
Platform presets
Section titled “Platform presets”Mittr ships 130+ pre-configured platform presets. Each preset knows the correct verification mode, header names, and signature format. Browse all presets:
curl https://app.mittr.io/api/v1/inbound-presets \ -H "X-API-Key: mtr_your_key"Verification modes
Section titled “Verification modes”| Mode | How it works | Example platforms |
|---|---|---|
hmac | HMAC-SHA256 signature in a header | GitHub, Stripe, Shopify, Twilio, SendGrid |
basic_auth | Username/password in Authorization header | Jira, Bitbucket |
api_key | Static key in a header | Datadog, PagerDuty |
ed25519 | Ed25519 signature verification | Svix, Discord |
rsa | RSA signature verification | DocuSign |
none | No verification (trusted sources) | Internal services |
Credential fields per mode
Section titled “Credential fields per mode”Each mode requires different credentials:
- hmac:
secret(signing secret) - basic_auth:
username,password - api_key:
api_key - ed25519:
public_key(hex-encoded) - rsa:
public_key_pem(PEM format) - none: no credentials needed
Event type mapping
Section titled “Event type mapping”Map incoming webhooks to event types for fan-out routing:
{ "eventTypeMapping": "$.headers.X-GitHub-Event"}Supports JSONPath expressions:
$.headers.X-GitHub-Event— extract from request header$.body.type— extract from request bodyorder.created— literal string (all events get this type)
Payload transformation
Section titled “Payload transformation”Transform inbound payloads before fan-out:
{ "transformation": "return { event: payload.action, repo: payload.repository.full_name }"}Destination forwarding
Section titled “Destination forwarding”An inbound endpoint forwards to one or more outbound endpoints, set via destinationIds:
{ "destinationIds": ["endpoint-uuid-1", "endpoint-uuid-2"]}At least one destination is required for an inbound webhook to produce anything. Mittr always verifies the incoming request, but it only creates events by fanning out to the destinationIds you configure — if none are set, the request is verified and then dropped (no event, nothing to view). So create the outbound endpoint(s) you want the data delivered to first, then add them as destinations here before pointing a source at the inbound URL.
Want a destination just to inspect what a source sends while you build? Point one outbound endpoint at a request-bin style URL (e.g.
webhook.site) and add it as a destination — the payload then flows through and is visible in Events / Attempts.
Dashboard
Section titled “Dashboard”The dashboard provides a visual interface for creating inbound endpoints:
- Searchable platform picker with 130+ presets
- Dynamic credential fields based on verification mode
- Destination endpoint checkbox selector
- Event type mapping with JSONPath help text