Webhooks

Managing Endpoints

Edit, enable, disable, test and delete webhook endpoints, rotate signing secrets with a 24-hour overlap, read the delivery log, and replay one or all failed deliveries, from Settings → Webhooks, the REST API or the DevStride MCP server.

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.

The endpoint list

Each endpoint is one row:

ColumnShows
EndpointThe URL, its description, and Failing since … when deliveries are failing.
EventsThe event types it receives.
EnabledAn on/off switch; see Enable or disable an endpoint.
Last success / Last failureWhen 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.

Create an endpoint

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:

  • start with https:// and be at most 2,048 characters;
  • resolve, when DevStride looks it up, to a public internet address. Hosts that resolve to a private network (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.

Edit an endpoint

Click Edit to open Edit Webhook Endpoint, change the URL, description or events, and Save.

  • A new URL is checked exactly as on create. Deliveries already queued go to the new URL.
  • A new set of events applies to changes from now on. Deliveries already queued for an event type you removed are still sent.

Enable or disable an endpoint

Use the Enabled switch in the endpoint's row.

While disabledWhen you enable it again
New changesNot queued for this endpoint at all.Delivered from that moment on.
Deliveries already queuedParked with the status dead; not retried.Stay dead until you replay them.
Secret, events, delivery logKept.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 an endpoint

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 the signing secret

Rotate a secret on a schedule, when someone who knew it leaves, or at once if it may have leaked.

  1. Click Rotate secret. The Rotate Signing Secret dialog explains that the previous secret keeps working for 24 hours.
  2. Click Rotate. The New signing secret dialog shows the new secret, once. Copy it.
  3. Deploy the new secret to your receiver within 24 hours.

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 an endpoint

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.

The delivery log

Below the endpoint list, the Delivery log shows one row per event per endpoint, newest first:

ColumnShows
(arrow)Expand the row to see its details.
TimeWhen the delivery was queued.
EndpointThe endpoint's host (hover for the full URL).
EventThe event type.
Statuspending, succeeded, failed or dead; see the life of a delivery.
AttemptsHow many times it has been sent.
Last responseThe HTTP status of the last attempt, when one arrived.
Next attemptWhen 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:

  • Payload: the JSON envelope exactly as stored, which a replay sends again. It is shown formatted for reading, so do not copy it to test a signature: the bytes on the wire are compact.
  • Last failed response (status): the first 1 KB of the body your endpoint returned on its last failed attempt; or
  • No response: the reason no answer arrived, such as a timeout or a refused address.

Deliveries stay in the log for at least 30 days.

Replay deliveries

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.

Replay one delivery

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.

Replay everything that failed since a time

After a partner fixes an outage, replay the whole gap in one go:

  1. Click Replay all failed since… above the delivery log, or Replay failed in the red failure banner (which pre-selects that endpoint).
  2. In Replay failed deliveries, set Failed since to when the outage began. A date on its own means the start of that day; add a time to be more precise.
  3. Choose an Endpoint, or leave it empty for every enabled endpoint.
  4. Click Replay.

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.

Manage webhooks through the REST API

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.

MethodPathDoes
GET/webhook-endpointsList the endpoints, with their events and health. Never includes a secret.
POST/webhook-endpointsCreate 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-secretIssue a new secret (in the response, once); the previous one stays valid for 24 hours.
POST/webhook-endpoints/{endpointId}/testSend a signed ping now and return ok, status, durationMs and error.
GET/webhook-deliveriesThe delivery log, newest first.
GET/webhook-deliveries/{deliveryId}One delivery, with its payload, lastResponseExcerpt and lastError.
POST/webhook-deliveries/{deliveryId}/replayReplay one failed or dead delivery.
POST/webhook-deliveries/replay-failedReplay every failed and dead delivery since a time.

The full schemas are in the API reference under Webhooks.

Create an endpoint

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:

FieldDescription
id, dateAdded, dateUpdatedIdentity and timestamps.
url, descriptionAs you set them (description may be null).
statusactive or disabled.
eventTypesThe subscribed event types, sorted alphabetically.
failingSinceWhen it started failing; null while healthy.
lastSuccessAt, lastFailureAtThe last 2xx, and the last failed attempt.
secretRotatedUntilWhile set, the previous secret is still accepted, until this time.
createdByUsernameWho 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.

Read the delivery log

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 parameterDescription
endpointIdOnly this endpoint's deliveries.
statuspending, succeeded, failed or dead.
eventTypeFor example comment.created.
since, untilOnly deliveries queued in this window (ISO-8601, for example 2026-10-17T06:00:00Z).
limitRows per page: default 50, at most 100.
cursorThe 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.

Replay failed deliveries

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.

Manage webhooks with the DevStride MCP server

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:

  • "Which webhook deliveries failed today, and what did the endpoint answer?"
  • "Send a test event to our CRM webhook."
  • "The partner was down from 6 AM to 9 AM; replay every failed delivery to their endpoint since 6 AM."
  • "Disable the webhook pointing at the old analytics server."