Everything about your endpoints lives on one page: Configure Settings → Integrations → Webhooks. You need the Manage Webhooks permission to open it (see Who can manage webhooks). While the page is open it refreshes itself every 30 seconds, so a replay's result or an endpoint's recovery shows up without a reload.
Each endpoint is one row:
| Column | Shows |
|---|---|
| Endpoint | The URL, its description, and Failing since … when deliveries are failing. |
| Events | The event types it receives. |
| Enabled | An on/off switch; see Enable or disable an endpoint. |
| Last success / Last failure | When it last answered 2xx, and when an attempt last failed. |
| (actions) | Test, Edit, Rotate secret and Delete. |
An organization can have up to 20 endpoints. Give each consuming system its own endpoint rather than sharing one: each gets its own secret, its own queue and its own health alerts, so one slow consumer never holds up another.
Click New endpoint, fill in Endpoint URL, an optional Description and the Events, then Create. The signing secret is shown once, straight afterwards. The Quickstart walks through it step by step.
The URL must:
https:// and be at most 2,048 characters;10.x, 192.168.x, …), loopback (127.0.0.1, ::1), link-local or cloud-metadata (169.254.169.254) address are refused, whatever name points at them.DevStride checks this when you save and again before every delivery, because DNS can change.
Click Edit to open Edit Webhook Endpoint, change the URL, description or events, and Save.
Use the Enabled switch in the endpoint's row.
| While disabled | When you enable it again | |
|---|---|---|
| New changes | Not queued for this endpoint at all. | Delivered from that moment on. |
| Deliveries already queued | Parked with the status dead; not retried. | Stay dead until you replay them. |
| Secret, events, delivery log | Kept. | Unchanged. |
Disable an endpoint for planned maintenance on the receiving side, or to stop traffic to a system you are retiring without losing its configuration. Remember that changes made while it was disabled are never sent: catch up on that window with the API if you need to.
Test sends a signed ping event to the endpoint right away and shows the answer under its row (for example Responded 204 in 143 ms). It works whether or not the endpoint is enabled, writes nothing to the delivery log and is never retried. See Send a test event for what each result means.
Rotate a secret on a schedule, when someone who knew it leaves, or at once if it may have leaked.
For those 24 hours DevStride signs every delivery with both secrets (two v1 values in X-DevStride-Signature), so the receiver verifies with whichever it has and no delivery fails while you switch. See Secret rotation.
Delete asks you to confirm in Delete Webhook Endpoint. Deleting removes the endpoint, its event choices and its whole delivery log. Pending deliveries are dropped. This cannot be undone. To stop traffic but keep the history, disable the endpoint instead.
Below the endpoint list, the Delivery log shows one row per event per endpoint, newest first:
| Column | Shows |
|---|---|
| (arrow) | Expand the row to see its details. |
| Time | When the delivery was queued. |
| Endpoint | The endpoint's host (hover for the full URL). |
| Event | The event type. |
| Status | pending, succeeded, failed or dead; see the life of a delivery. |
| Attempts | How many times it has been sent. |
| Last response | The HTTP status of the last attempt, when one arrived. |
| Next attempt | When a pending delivery will be tried again. |
| (action) | Replay, on failed and dead rows. |
Filter it with Every endpoint, Any status (where dead reads dead (endpoint disabled)), Any event and Since (a date, with an optional time). Load more fetches older rows.
Expanding a row shows:
status): the first 1 KB of the body your endpoint returned on its last failed attempt; orDeliveries stay in the log for at least 30 days.
A replay puts a failed or dead delivery back in its endpoint's queue. It keeps the same event id and its original place in the queue: it goes out ahead of anything newer still waiting, and your receiver sees an id it may already know, so deduplication keeps working. The payload is never rebuilt; the same envelope is sent.
Click Replay on a failed or dead row; Delivery put back in its queue confirms it. It is sent as soon as nothing older is waiting on that endpoint. If it fails again it waits out its retries at the head of the queue, holding newer deliveries behind it, like any other delivery.
You cannot replay a delivery that is pending or succeeded, or one whose endpoint is disabled: enable the endpoint first.
After a partner fixes an outage, replay the whole gap in one go:
Every failed and dead delivery queued at or after that moment goes back in its queue, oldest first, with the same ids and in its original order. The dialog then reports how many were put back. One replay handles up to 1,000 deliveries; if more remain, it says how many, and you click Replay again to continue. Deliveries of disabled endpoints are left alone and counted as remaining until you enable the endpoint.
Every action on the page is also an API route under https://api.devstride.com/v1/organizations/{organizationId}. Authenticate with an API key belonging to a member who holds Manage Webhooks; the key acts with its owner's permissions. Requests count against the organization's API rate limit; webhook deliveries themselves never do.
| Method | Path | Does |
|---|---|---|
GET | /webhook-endpoints | List the endpoints, with their events and health. Never includes a secret. |
POST | /webhook-endpoints | Create an endpoint. The response includes its secret, once. |
GET | /webhook-endpoints/{endpointId} | Read one endpoint. |
PATCH | /webhook-endpoints/{endpointId} | Change url, description (null clears it), status (active or disabled) or eventTypes (replaced as a whole set). |
DELETE | /webhook-endpoints/{endpointId} | Delete the endpoint, its events and its delivery log. |
POST | /webhook-endpoints/{endpointId}/rotate-secret | Issue a new secret (in the response, once); the previous one stays valid for 24 hours. |
POST | /webhook-endpoints/{endpointId}/test | Send a signed ping now and return ok, status, durationMs and error. |
GET | /webhook-deliveries | The delivery log, newest first. |
GET | /webhook-deliveries/{deliveryId} | One delivery, with its payload, lastResponseExcerpt and lastError. |
POST | /webhook-deliveries/{deliveryId}/replay | Replay one failed or dead delivery. |
POST | /webhook-deliveries/replay-failed | Replay every failed and dead delivery since a time. |
The full schemas are in the API reference under Webhooks.
curl -X POST "https://api.devstride.com/v1/organizations/$ORG_ID/webhook-endpoints" \
-u "$DEVSTRIDE_API_KEY:$DEVSTRIDE_API_SECRET" \
-H "Content-Type: application/json" \
-d '{
"url": "https://hooks.example.com/devstride/webhooks",
"description": "CRM ticket sync",
"eventTypes": ["item.created", "item.status_changed", "comment.created"]
}'
{
"data": {
"id": "3b0d2b8e-7f6a-4a46-9a3f-7a2c0f1a2b3c",
"dateAdded": "2026-10-17T14:00:02.611Z",
"dateUpdated": "2026-10-17T14:00:02.611Z",
"url": "https://hooks.example.com/devstride/webhooks",
"description": "CRM ticket sync",
"status": "active",
"eventTypes": ["comment.created", "item.created", "item.status_changed"],
"failingSince": null,
"lastSuccessAt": null,
"lastFailureAt": null,
"secretRotatedUntil": null,
"createdByUsername": "jordan.lee",
"secret": "whsec_…"
}
}
Store secret now: no other response ever contains it. The endpoint object's fields:
| Field | Description |
|---|---|
id, dateAdded, dateUpdated | Identity and timestamps. |
url, description | As you set them (description may be null). |
status | active or disabled. |
eventTypes | The subscribed event types, sorted alphabetically. |
failingSince | When it started failing; null while healthy. |
lastSuccessAt, lastFailureAt | The last 2xx, and the last failed attempt. |
secretRotatedUntil | While set, the previous secret is still accepted, until this time. |
createdByUsername | Who created it. |
Invalid input is refused with 400: a URL that is not https://, does not resolve or resolves to a refused address (the message says why), an empty or unknown event type, or a 21st endpoint.
curl "https://api.devstride.com/v1/organizations/$ORG_ID/webhook-deliveries?status=failed&since=2026-10-17T06:00:00Z&limit=100" \
-u "$DEVSTRIDE_API_KEY:$DEVSTRIDE_API_SECRET"
| Query parameter | Description |
|---|---|
endpointId | Only this endpoint's deliveries. |
status | pending, succeeded, failed or dead. |
eventType | For example comment.created. |
since, until | Only deliveries queued in this window (ISO-8601, for example 2026-10-17T06:00:00Z). |
limit | Rows per page: default 50, at most 100. |
cursor | The meta.cursor of the previous page; meta.hasMoreData says whether there is one. |
Each row has id, endpointId, eventId (the envelope id your receiver saw), eventType, status, seq (its place in the endpoint's queue), attempts, nextAttemptAt, lastAttemptAt, lastResponseStatus, succeededAt and dateAdded (when it was queued). The single-delivery read adds payload, lastResponseExcerpt (up to 1 KB of the last failed response) and lastError.
curl -X POST "https://api.devstride.com/v1/organizations/$ORG_ID/webhook-deliveries/replay-failed" \
-u "$DEVSTRIDE_API_KEY:$DEVSTRIDE_API_SECRET" \
-H "Content-Type: application/json" \
-d '{ "since": "2026-10-17T06:00:00Z", "endpointId": "3b0d2b8e-7f6a-4a46-9a3f-7a2c0f1a2b3c" }'
{ "data": { "replayed": 412, "remaining": 0, "endpointsWoken": 1 } }
replayed is how many deliveries went back in their queues by this call (at most 1,000), and remaining how many matching failed or dead deliveries are left: those over the per-call limit (call again) and those of disabled endpoints (enable, then call again). Leave out endpointId to replay across every endpoint.
Replaying a single delivery that is pending or succeeded, or whose endpoint is disabled, returns 409. An id from another organization returns 404, and a key whose member lacks Manage Webhooks gets 403.
The DevStride MCP server has no webhook tools of its own, but your AI assistant can reach every webhook route except two through its API gateway tools: list_api_operations finds them (search for "webhook"), describe_api_operation shows the input, and invoke_api_operation calls them. The operations are findWebhookEndpoints, getWebhookEndpoint, updateWebhookEndpoint, deleteWebhookEndpoint, testWebhookEndpoint, findWebhookDeliveries, getWebhookDelivery, replayWebhookDelivery and replayFailedWebhookDeliveries.
That makes questions like these work in plain language:
createWebhookEndpoint and rotateWebhookEndpointSecret return a signing secret, and a secret must never end up in an AI conversation's transcript. Create endpoints and rotate secrets in Configure Settings → Integrations → Webhooks, or with the REST API from your own tooling.Delivery, Retries & Ordering
What counts as a successful webhook delivery, the request time limits, the ten-attempt retry schedule over about 24 hours, per-endpoint ordering, at-least-once delivery, failing and recovered alerts, and how long the delivery log keeps each delivery.
Troubleshooting & Best Practices
Build a webhook receiver that never loses or double-counts an event: acknowledge fast, verify first, deduplicate by event id, cope with ordering, keep secrets safe, and fix the common failures: signature mismatches, clock skew, redirects, timeouts and refused URLs.