Endpoints and request formats
Everything you need to integrate, manage, and troubleshoot. Project API keys and short-lived control tokens are different credentials.
Webhook delivery API
Project API key authentication.
GET/api/v1/project/Project
Project
Get the project associated with your project API key.
{
"id": "PROJECT_UUID",
"name": "Production",
"slug": "production",
"monthly_event_quota": 1000
}curl -X GET 'https://api.hookstride.com/api/v1/project/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY"const response = await fetch("https://api.hookstride.com/api/v1/project/", {
method: "GET",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"GET", "https://api.hookstride.com/api/v1/project/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
timeout=20,
)
response.raise_for_status()GET/api/v1/usage/Usage
Usage
Return this month's event quota and delivery counters.
{
"period_start": "2026-10-01",
"events_ingested": 125,
"delivery_attempts": 142,
"events_delivered": 120,
"events_failed": 3,
"event_quota": 1000,
"events_remaining": 875
}curl -X GET 'https://api.hookstride.com/api/v1/usage/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY"const response = await fetch("https://api.hookstride.com/api/v1/usage/", {
method: "GET",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"GET", "https://api.hookstride.com/api/v1/usage/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
timeout=20,
)
response.raise_for_status()GET/api/v1/endpoints/List endpoints
List endpoints
List paginated delivery destinations for the current project.
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": "ENDPOINT_UUID",
"name": "Production receiver",
"url": "https://example.com/webhooks",
"is_active": true
}
]
}curl -X GET 'https://api.hookstride.com/api/v1/endpoints/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY"const response = await fetch("https://api.hookstride.com/api/v1/endpoints/", {
method: "GET",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"GET", "https://api.hookstride.com/api/v1/endpoints/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
timeout=20,
)
response.raise_for_status()POST/api/v1/endpoints/Create endpoint
Create endpoint
Register a public HTTPS webhook destination. The signing secret appears only in this response.
{
"name": "Production receiver",
"url": "https://example.com/webhooks"
}{
"id": "ENDPOINT_UUID",
"name": "Production receiver",
"url": "https://example.com/webhooks",
"is_active": true,
"signing_secret": "SECRET_SAVE_ONCE"
}curl -X POST 'https://api.hookstride.com/api/v1/endpoints/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Production receiver","url":"https://example.com/webhooks"}'const response = await fetch("https://api.hookstride.com/api/v1/endpoints/", {
method: "POST",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY","Content-Type":"application/json"},
body: JSON.stringify({"name":"Production receiver","url":"https://example.com/webhooks"}),
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"POST", "https://api.hookstride.com/api/v1/endpoints/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
json=json.loads("{\"name\":\"Production receiver\",\"url\":\"https://example.com/webhooks\"}"),
timeout=20,
)
response.raise_for_status()GET/api/v1/endpoints/{id}/Endpoint details
Endpoint details
Inspect one destination belonging to the authenticated project.
{
"id": "ENDPOINT_UUID",
"name": "Production receiver",
"url": "https://example.com/webhooks",
"is_active": true
}curl -X GET 'https://api.hookstride.com/api/v1/endpoints/{id}/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY"const response = await fetch("https://api.hookstride.com/api/v1/endpoints/{id}/", {
method: "GET",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"GET", "https://api.hookstride.com/api/v1/endpoints/{id}/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
timeout=20,
)
response.raise_for_status()PATCH/api/v1/endpoints/{id}/Update endpoint
Update endpoint
Change a destination's name, URL, or active status.
{
"name": "Updated receiver",
"is_active": true
}{
"id": "ENDPOINT_UUID",
"name": "Updated receiver",
"url": "https://example.com/webhooks",
"is_active": true
}curl -X PATCH 'https://api.hookstride.com/api/v1/endpoints/{id}/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Updated receiver","is_active":true}'const response = await fetch("https://api.hookstride.com/api/v1/endpoints/{id}/", {
method: "PATCH",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY","Content-Type":"application/json"},
body: JSON.stringify({"name":"Updated receiver","is_active":true}),
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"PATCH", "https://api.hookstride.com/api/v1/endpoints/{id}/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
json=json.loads("{\"name\":\"Updated receiver\",\"is_active\":true}"),
timeout=20,
)
response.raise_for_status()POST/api/v1/endpoints/{id}/rotate-secret/Rotate signing secret
Rotate signing secret
Issue a new endpoint signing secret. Rotation takes effect immediately.
{
"endpoint": "ENDPOINT_UUID",
"signing_secret": "NEW_SECRET_SAVE_ONCE"
}curl -X POST 'https://api.hookstride.com/api/v1/endpoints/{id}/rotate-secret/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY"const response = await fetch("https://api.hookstride.com/api/v1/endpoints/{id}/rotate-secret/", {
method: "POST",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"POST", "https://api.hookstride.com/api/v1/endpoints/{id}/rotate-secret/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
timeout=20,
)
response.raise_for_status()GET/api/v1/events/List events
List events
List paginated events. Filter by status, event_type, or endpoint UUID.
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": "EVENT_UUID",
"event_type": "payment.completed",
"status": "delivered",
"attempt_count": 1
}
]
}curl -X GET 'https://api.hookstride.com/api/v1/events/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY"const response = await fetch("https://api.hookstride.com/api/v1/events/", {
method: "GET",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"GET", "https://api.hookstride.com/api/v1/events/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
timeout=20,
)
response.raise_for_status()POST/api/v1/events/Send an event
Send an event
Persist and enqueue a signed webhook. Send an optional Idempotency-Key header to prevent duplicates.
{
"endpoint": "ENDPOINT_UUID",
"event_type": "payment.completed",
"payload": {
"payment_id": "pay_123",
"amount": 250,
"currency": "GHS"
}
}{
"id": "EVENT_UUID",
"endpoint": "ENDPOINT_UUID",
"event_type": "payment.completed",
"status": "pending",
"attempt_count": 0,
"attempts": []
}curl -X POST 'https://api.hookstride.com/api/v1/events/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"endpoint":"ENDPOINT_UUID","event_type":"payment.completed","payload":{"payment_id":"pay_123","amount":250,"currency":"GHS"}}'const response = await fetch("https://api.hookstride.com/api/v1/events/", {
method: "POST",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY","Content-Type":"application/json"},
body: JSON.stringify({"endpoint":"ENDPOINT_UUID","event_type":"payment.completed","payload":{"payment_id":"pay_123","amount":250,"currency":"GHS"}}),
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"POST", "https://api.hookstride.com/api/v1/events/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
json=json.loads("{\"endpoint\":\"ENDPOINT_UUID\",\"event_type\":\"payment.completed\",\"payload\":{\"payment_id\":\"pay_123\",\"amount\":250,\"currency\":\"GHS\"}}"),
timeout=20,
)
response.raise_for_status()GET/api/v1/events/{id}/Event details
Event details
Retrieve an event with delivery attempts, errors, and timing information.
{
"id": "EVENT_UUID",
"event_type": "payment.completed",
"status": "delivered",
"attempt_count": 1,
"attempts": [
{
"attempt_number": 1,
"status_code": 200,
"duration_ms": 110
}
]
}curl -X GET 'https://api.hookstride.com/api/v1/events/{id}/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY"const response = await fetch("https://api.hookstride.com/api/v1/events/{id}/", {
method: "GET",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"GET", "https://api.hookstride.com/api/v1/events/{id}/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
timeout=20,
)
response.raise_for_status()POST/api/v1/events/{id}/replay/Replay event
Replay event
Requeue a delivered or permanently failed event as a new event linked to its original.
{
"id": "NEW_EVENT_UUID",
"replayed_from": "EVENT_UUID",
"status": "pending",
"attempts": []
}curl -X POST 'https://api.hookstride.com/api/v1/events/{id}/replay/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY"const response = await fetch("https://api.hookstride.com/api/v1/events/{id}/replay/", {
method: "POST",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"POST", "https://api.hookstride.com/api/v1/events/{id}/replay/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
timeout=20,
)
response.raise_for_status()GET/api/v1/stats/Delivery statistics
Delivery statistics
Retrieve totals, successful deliveries, failures, pending events, and success rate.
{
"project": "PROJECT_UUID",
"events": {
"total": 100,
"delivered": 92,
"failed": 3,
"pending": 5,
"success_rate": 92
}
}curl -X GET 'https://api.hookstride.com/api/v1/stats/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY"const response = await fetch("https://api.hookstride.com/api/v1/stats/", {
method: "GET",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"GET", "https://api.hookstride.com/api/v1/stats/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
timeout=20,
)
response.raise_for_status()Incoming webhook gateway
Optional signature verification and routing.
GET/api/v1/sources/List connected sources
List connected sources
Retrieve your project's external and custom webhook sources.
{
"results": [
{
"id": "SOURCE_UUID",
"name": "Shared provider",
"provider": "custom",
"routing": "rules"
}
]
}curl -X GET 'https://api.hookstride.com/api/v1/sources/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY"const response = await fetch("https://api.hookstride.com/api/v1/sources/", {
method: "GET",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"GET", "https://api.hookstride.com/api/v1/sources/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
timeout=20,
)
response.raise_for_status()POST/api/v1/sources/Connect a webhook source
Connect a webhook source
Register a signed sender. Copy the returned ingress URL into its webhook settings.
{
"name": "Shared sender",
"provider": "custom",
"routing": "rules"
}{
"id": "SOURCE_UUID",
"name": "Shared sender",
"ingest_url": "https://example.com/ingest/v1/SOURCE_UUID/",
"signing_secret": "ONE_TIME_SECRET"
}curl -X POST 'https://api.hookstride.com/api/v1/sources/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Shared sender","provider":"custom","routing":"rules"}'const response = await fetch("https://api.hookstride.com/api/v1/sources/", {
method: "POST",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY","Content-Type":"application/json"},
body: JSON.stringify({"name":"Shared sender","provider":"custom","routing":"rules"}),
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"POST", "https://api.hookstride.com/api/v1/sources/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
json=json.loads("{\"name\":\"Shared sender\",\"provider\":\"custom\",\"routing\":\"rules\"}"),
timeout=20,
)
response.raise_for_status()PATCH/api/v1/sources/{id}/Update source
Update source
Pause or rename an existing incoming source.
{
"is_active": false
}{
"id": "SOURCE_UUID",
"name": "Shared sender",
"is_active": false
}curl -X PATCH 'https://api.hookstride.com/api/v1/sources/{id}/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"is_active":false}'const response = await fetch("https://api.hookstride.com/api/v1/sources/{id}/", {
method: "PATCH",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY","Content-Type":"application/json"},
body: JSON.stringify({"is_active":false}),
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"PATCH", "https://api.hookstride.com/api/v1/sources/{id}/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
json=json.loads("{\"is_active\":false}"),
timeout=20,
)
response.raise_for_status()POST/api/v1/sources/{id}/rotate-secret/Rotate source secret
Rotate source secret
Replace the stored source signing secret; sender updates must be coordinated.
{}{
"id": "SOURCE_UUID",
"rotated": true,
"signing_secret": "ONE_TIME_SECRET_FOR_CUSTOM"
}curl -X POST 'https://api.hookstride.com/api/v1/sources/{id}/rotate-secret/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'const response = await fetch("https://api.hookstride.com/api/v1/sources/{id}/rotate-secret/", {
method: "POST",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY","Content-Type":"application/json"},
body: JSON.stringify({}),
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"POST", "https://api.hookstride.com/api/v1/sources/{id}/rotate-secret/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
json=json.loads("{}"),
timeout=20,
)
response.raise_for_status()POST/api/v1/routes/Create event routing rule
Create event routing rule
Forward signed events to a project-owned destination matching an event type and optional field.
{
"source": "SOURCE_UUID",
"endpoint": "ENDPOINT_UUID",
"event_pattern": "order.*"
}{
"id": "RULE_UUID",
"source": "SOURCE_UUID",
"endpoint": "ENDPOINT_UUID"
}curl -X POST 'https://api.hookstride.com/api/v1/routes/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"source":"SOURCE_UUID","endpoint":"ENDPOINT_UUID","event_pattern":"order.*"}'const response = await fetch("https://api.hookstride.com/api/v1/routes/", {
method: "POST",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY","Content-Type":"application/json"},
body: JSON.stringify({"source":"SOURCE_UUID","endpoint":"ENDPOINT_UUID","event_pattern":"order.*"}),
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"POST", "https://api.hookstride.com/api/v1/routes/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
json=json.loads("{\"source\":\"SOURCE_UUID\",\"endpoint\":\"ENDPOINT_UUID\",\"event_pattern\":\"order.*\"}"),
timeout=20,
)
response.raise_for_status()GET/api/v1/routes/List event routing rules
List event routing rules
Review subscriptions controlling inbound fan-out.
{
"results": []
}curl -X GET 'https://api.hookstride.com/api/v1/routes/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY"const response = await fetch("https://api.hookstride.com/api/v1/routes/", {
method: "GET",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"GET", "https://api.hookstride.com/api/v1/routes/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
timeout=20,
)
response.raise_for_status()POST/api/v1/reference-bindings/Register trusted reference
Register trusted reference
Bind an external reference to one destination before the external event is created.
{
"source": "SOURCE_UUID",
"endpoint": "ENDPOINT_UUID",
"reference": "ORDER-123"
}{
"id": "BINDING_UUID",
"reference": "ORDER-123"
}curl -X POST 'https://api.hookstride.com/api/v1/reference-bindings/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"source":"SOURCE_UUID","endpoint":"ENDPOINT_UUID","reference":"ORDER-123"}'const response = await fetch("https://api.hookstride.com/api/v1/reference-bindings/", {
method: "POST",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY","Content-Type":"application/json"},
body: JSON.stringify({"source":"SOURCE_UUID","endpoint":"ENDPOINT_UUID","reference":"ORDER-123"}),
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"POST", "https://api.hookstride.com/api/v1/reference-bindings/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
json=json.loads("{\"source\":\"SOURCE_UUID\",\"endpoint\":\"ENDPOINT_UUID\",\"reference\":\"ORDER-123\"}"),
timeout=20,
)
response.raise_for_status()GET/api/v1/reference-bindings/List trusted references
List trusted references
View pre-registered event ownership bindings.
{
"results": []
}curl -X GET 'https://api.hookstride.com/api/v1/reference-bindings/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY"const response = await fetch("https://api.hookstride.com/api/v1/reference-bindings/", {
method: "GET",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"GET", "https://api.hookstride.com/api/v1/reference-bindings/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
timeout=20,
)
response.raise_for_status()GET/api/v1/inbound-events/Incoming event history
Incoming event history
Inspect accepted upstream events without exposing their payload by default.
{
"results": [
{
"id": "MESSAGE_UUID",
"event_type": "order.created",
"route_count": 1
}
]
}curl -X GET 'https://api.hookstride.com/api/v1/inbound-events/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY"const response = await fetch("https://api.hookstride.com/api/v1/inbound-events/", {
method: "GET",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"GET", "https://api.hookstride.com/api/v1/inbound-events/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
timeout=20,
)
response.raise_for_status()POST/api/v1/inbound-events/{id}/redispatch/Redispatch an incoming event
Redispatch an incoming event
Send a stored upstream event to newly matching destinations without duplicating prior deliveries.
{
"id": "MESSAGE_UUID",
"routed": 1,
"duplicate": false
}curl -X POST 'https://api.hookstride.com/api/v1/inbound-events/{id}/redispatch/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY"const response = await fetch("https://api.hookstride.com/api/v1/inbound-events/{id}/redispatch/", {
method: "POST",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"POST", "https://api.hookstride.com/api/v1/inbound-events/{id}/redispatch/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
timeout=20,
)
response.raise_for_status()GET/api/v1/ingress-stats/Incoming event statistics
Incoming event statistics
Monitor received, unmatched and delivered events in your project.
{
"sources": 1,
"received": 120,
"unrouted": 2,
"outbound_deliveries": 118
}curl -X GET 'https://api.hookstride.com/api/v1/ingress-stats/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY"const response = await fetch("https://api.hookstride.com/api/v1/ingress-stats/", {
method: "GET",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"GET", "https://api.hookstride.com/api/v1/ingress-stats/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
timeout=20,
)
response.raise_for_status()POST/api/v1/reference-registration-keys/Create a limited registration key
Create a limited registration key
Issue a one-time key for exactly one external source and one destination. Store it only on that app's backend.
{
"source": "SOURCE_UUID",
"endpoint": "DESTINATION_UUID",
"name": "Voting app"
}{
"id": "KEY_UUID",
"masked_key": "whrr_...abcd",
"token": "ONE_TIME_RESTRICTED_KEY",
"expires_at": "2027-01-28T00:00:00Z"
}curl -X POST 'https://api.hookstride.com/api/v1/reference-registration-keys/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"source":"SOURCE_UUID","endpoint":"DESTINATION_UUID","name":"Voting app"}'const response = await fetch("https://api.hookstride.com/api/v1/reference-registration-keys/", {
method: "POST",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY","Content-Type":"application/json"},
body: JSON.stringify({"source":"SOURCE_UUID","endpoint":"DESTINATION_UUID","name":"Voting app"}),
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"POST", "https://api.hookstride.com/api/v1/reference-registration-keys/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
json=json.loads("{\"source\":\"SOURCE_UUID\",\"endpoint\":\"DESTINATION_UUID\",\"name\":\"Voting app\"}"),
timeout=20,
)
response.raise_for_status()GET/api/v1/reference-registration-keys/List limited registration keys
List limited registration keys
View masked, expiring credentials for each app without exposing token values.
{
"results": [
{
"id": "KEY_UUID",
"name": "Voting app",
"masked_key": "whrr_...abcd"
}
]
}curl -X GET 'https://api.hookstride.com/api/v1/reference-registration-keys/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY"const response = await fetch("https://api.hookstride.com/api/v1/reference-registration-keys/", {
method: "GET",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"GET", "https://api.hookstride.com/api/v1/reference-registration-keys/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
timeout=20,
)
response.raise_for_status()POST/api/v1/reference-registration-keys/{id}/revoke/Revoke a limited registration key
Revoke a limited registration key
Immediately disable one app's registration access without affecting other destinations.
{
"id": "KEY_UUID",
"is_active": false
}curl -X POST 'https://api.hookstride.com/api/v1/reference-registration-keys/{id}/revoke/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY"const response = await fetch("https://api.hookstride.com/api/v1/reference-registration-keys/{id}/revoke/", {
method: "POST",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"POST", "https://api.hookstride.com/api/v1/reference-registration-keys/{id}/revoke/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
timeout=20,
)
response.raise_for_status()POST/ingest/v1/register-reference/Register an application reference
Register an application reference
Use the app's limited token to claim its own order, transaction or subscription reference before the provider emits an event. No source or destination ID needed.
{
"reference": "ORDER-APP-123"
}{
"id": "BINDING_UUID",
"reference": "ORDER-APP-123"
}curl -X POST 'https://api.hookstride.com/ingest/v1/register-reference/' \
-H "Authorization: Bearer $HOOKSTRIDE_CONTROL_TOKEN" \
-H "Content-Type: application/json" \
-d '{"reference":"ORDER-APP-123"}'const response = await fetch("https://api.hookstride.com/ingest/v1/register-reference/", {
method: "POST",
headers: {"Authorization":"Bearer YOUR_CONTROL_TOKEN","Content-Type":"application/json"},
body: JSON.stringify({"reference":"ORDER-APP-123"}),
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"POST", "https://api.hookstride.com/ingest/v1/register-reference/",
headers={"Authorization":"Bearer YOUR_CONTROL_TOKEN"},
json=json.loads("{\"reference\":\"ORDER-APP-123\"}"),
timeout=20,
)
response.raise_for_status()GET/api/v1/destinations/{id}/delivery/Inspect destination delivery format
Inspect destination delivery format
See how a destination receives JSON and which authentication mode is configured. Secrets are never returned.
{
"endpoint": "DESTINATION_UUID",
"payload_format": "envelope",
"field_map": {},
"auth_mode": "signed",
"credential_configured": false
}curl -X GET 'https://api.hookstride.com/api/v1/destinations/{id}/delivery/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY"const response = await fetch("https://api.hookstride.com/api/v1/destinations/{id}/delivery/", {
method: "GET",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"GET", "https://api.hookstride.com/api/v1/destinations/{id}/delivery/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
timeout=20,
)
response.raise_for_status()PUT/api/v1/destinations/{id}/delivery/Configure destination delivery
Configure destination delivery
Choose standard envelope, original JSON or bounded field mapping; optionally add an encrypted Bearer token or X-Api-Key. Every delivery still carries the destination's HMAC signature.
{
"payload_format": "mapped",
"field_map": {
"transaction.reference": "payload.data.reference",
"transaction.event": "event.type",
"app": {
"const": "my-application"
}
},
"auth_mode": "bearer",
"credential": "DESTINATION_TOKEN"
}{
"endpoint": "DESTINATION_UUID",
"payload_format": "mapped",
"field_map": {
"transaction.reference": "payload.data.reference",
"transaction.event": "event.type",
"app": {
"const": "my-application"
}
},
"auth_mode": "bearer",
"credential_configured": true
}curl -X PUT 'https://api.hookstride.com/api/v1/destinations/{id}/delivery/' \
-H "Authorization: Bearer $HOOKSTRIDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"payload_format":"mapped","field_map":{"transaction.reference":"payload.data.reference","transaction.event":"event.type","app":{"const":"my-application"}},"auth_mode":"bearer","credential":"DESTINATION_TOKEN"}'const response = await fetch("https://api.hookstride.com/api/v1/destinations/{id}/delivery/", {
method: "PUT",
headers: {"Authorization":"Bearer YOUR_PROJECT_API_KEY","Content-Type":"application/json"},
body: JSON.stringify({"payload_format":"mapped","field_map":{"transaction.reference":"payload.data.reference","transaction.event":"event.type","app":{"const":"my-application"}},"auth_mode":"bearer","credential":"DESTINATION_TOKEN"}),
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"PUT", "https://api.hookstride.com/api/v1/destinations/{id}/delivery/",
headers={"Authorization":"Bearer YOUR_PROJECT_API_KEY"},
json=json.loads("{\"payload_format\":\"mapped\",\"field_map\":{\"transaction.reference\":\"payload.data.reference\",\"transaction.event\":\"event.type\",\"app\":{\"const\":\"my-application\"}},\"auth_mode\":\"bearer\",\"credential\":\"DESTINATION_TOKEN\"}"),
timeout=20,
)
response.raise_for_status()Account Control API
Workspace and project administration with a separate control token.
POST/control/v1/auth/email/start/Request an email sign-in code
Request an email sign-in code
Send a single-use, 10-minute code. Optionally set a workspace name when registering; passwords are not supported.
{
"email": "dev@example.com",
"workspace_name": "Acme"
}{
"challenge": "EMAIL_CHALLENGE_UUID",
"expires_in": 600
}curl -X POST 'https://api.hookstride.com/control/v1/auth/email/start/' \
-H "Content-Type: application/json" \
-d '{"email":"dev@example.com","workspace_name":"Acme"}'const response = await fetch("https://api.hookstride.com/control/v1/auth/email/start/", {
method: "POST",
headers: {},
body: JSON.stringify({"email":"dev@example.com","workspace_name":"Acme"}),
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"POST", "https://api.hookstride.com/control/v1/auth/email/start/",
headers={},
json=json.loads("{\"email\":\"dev@example.com\",\"workspace_name\":\"Acme\"}"),
timeout=20,
)
response.raise_for_status()POST/control/v1/auth/email/verify/Verify a one-time email code
Verify a one-time email code
Complete email verification. Privileged members must additionally complete MFA; the Next.js flow receives a 202 challenge, never a privileged token from email verification alone.
{
"challenge": "EMAIL_CHALLENGE_UUID",
"code": "ABCD2345"
}{
"requires_mfa": true,
"enrollment_required": true,
"challenge": "MFA_CHALLENGE",
"expires_in": 600
}curl -X POST 'https://api.hookstride.com/control/v1/auth/email/verify/' \
-H "Content-Type: application/json" \
-d '{"challenge":"EMAIL_CHALLENGE_UUID","code":"ABCD2345"}'const response = await fetch("https://api.hookstride.com/control/v1/auth/email/verify/", {
method: "POST",
headers: {},
body: JSON.stringify({"challenge":"EMAIL_CHALLENGE_UUID","code":"ABCD2345"}),
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"POST", "https://api.hookstride.com/control/v1/auth/email/verify/",
headers={},
json=json.loads("{\"challenge\":\"EMAIL_CHALLENGE_UUID\",\"code\":\"ABCD2345\"}"),
timeout=20,
)
response.raise_for_status()POST/control/v1/auth/google/verify/Verify a Google sign-in identity token
Verify a Google sign-in identity token
Verify a Google OIDC ID token using Google's JWKS and the configured client audience and one-time nonce. Privileged users receive an MFA challenge instead of a bearer token.
{
"id_token": "GOOGLE_OIDC_ID_TOKEN",
"nonce": "OAUTH_ONE_TIME_NONCE"
}{
"requires_mfa": true,
"enrollment_required": false,
"challenge": "MFA_CHALLENGE",
"expires_in": 600
}curl -X POST 'https://api.hookstride.com/control/v1/auth/google/verify/' \
-H "Content-Type: application/json" \
-d '{"id_token":"GOOGLE_OIDC_ID_TOKEN","nonce":"OAUTH_ONE_TIME_NONCE"}'const response = await fetch("https://api.hookstride.com/control/v1/auth/google/verify/", {
method: "POST",
headers: {},
body: JSON.stringify({"id_token":"GOOGLE_OIDC_ID_TOKEN","nonce":"OAUTH_ONE_TIME_NONCE"}),
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"POST", "https://api.hookstride.com/control/v1/auth/google/verify/",
headers={},
json=json.loads("{\"id_token\":\"GOOGLE_OIDC_ID_TOKEN\",\"nonce\":\"OAUTH_ONE_TIME_NONCE\"}"),
timeout=20,
)
response.raise_for_status()POST/control/v1/auth/logout/Sign out
Sign out
Revoke the current control token. Returns no response body.
204 No Contentcurl -X POST 'https://api.hookstride.com/control/v1/auth/logout/' \
-H "Authorization: Bearer $HOOKSTRIDE_CONTROL_TOKEN"const response = await fetch("https://api.hookstride.com/control/v1/auth/logout/", {
method: "POST",
headers: {"Authorization":"Bearer YOUR_CONTROL_TOKEN"},
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"POST", "https://api.hookstride.com/control/v1/auth/logout/",
headers={"Authorization":"Bearer YOUR_CONTROL_TOKEN"},
timeout=20,
)
response.raise_for_status()GET/control/v1/me/Your profile
Your profile
Retrieve the authenticated user and their account memberships.
{
"user": {
"id": 1,
"email": "dev@example.com"
},
"memberships": [
{
"account_name": "Acme",
"role": "owner"
}
]
}curl -X GET 'https://api.hookstride.com/control/v1/me/' \
-H "Authorization: Bearer $HOOKSTRIDE_CONTROL_TOKEN"const response = await fetch("https://api.hookstride.com/control/v1/me/", {
method: "GET",
headers: {"Authorization":"Bearer YOUR_CONTROL_TOKEN"},
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"GET", "https://api.hookstride.com/control/v1/me/",
headers={"Authorization":"Bearer YOUR_CONTROL_TOKEN"},
timeout=20,
)
response.raise_for_status()GET/control/v1/projects/List projects
List projects
List projects accessible to your account.
[
{
"id": "PROJECT_UUID",
"name": "Production",
"role": "owner",
"monthly_event_quota": 1000
}
]curl -X GET 'https://api.hookstride.com/control/v1/projects/' \
-H "Authorization: Bearer $HOOKSTRIDE_CONTROL_TOKEN"const response = await fetch("https://api.hookstride.com/control/v1/projects/", {
method: "GET",
headers: {"Authorization":"Bearer YOUR_CONTROL_TOKEN"},
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"GET", "https://api.hookstride.com/control/v1/projects/",
headers={"Authorization":"Bearer YOUR_CONTROL_TOKEN"},
timeout=20,
)
response.raise_for_status()POST/control/v1/projects/Create project
Create project
Create an additional project within an account where you have admin access.
{
"account_id": "ACCOUNT_UUID",
"name": "Staging",
"slug": "staging"
}{
"id": "PROJECT_UUID",
"name": "Staging",
"slug": "staging",
"role": "owner"
}curl -X POST 'https://api.hookstride.com/control/v1/projects/' \
-H "Authorization: Bearer $HOOKSTRIDE_CONTROL_TOKEN" \
-H "Content-Type: application/json" \
-d '{"account_id":"ACCOUNT_UUID","name":"Staging","slug":"staging"}'const response = await fetch("https://api.hookstride.com/control/v1/projects/", {
method: "POST",
headers: {"Authorization":"Bearer YOUR_CONTROL_TOKEN","Content-Type":"application/json"},
body: JSON.stringify({"account_id":"ACCOUNT_UUID","name":"Staging","slug":"staging"}),
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"POST", "https://api.hookstride.com/control/v1/projects/",
headers={"Authorization":"Bearer YOUR_CONTROL_TOKEN"},
json=json.loads("{\"account_id\":\"ACCOUNT_UUID\",\"name\":\"Staging\",\"slug\":\"staging\"}"),
timeout=20,
)
response.raise_for_status()GET/control/v1/projects/{project_id}/Project details
Project details
Read the project configuration and subscription summary.
{
"id": "PROJECT_UUID",
"name": "Production",
"monthly_event_quota": 1000,
"subscription": {
"plan_code": "free",
"status": "active"
}
}curl -X GET 'https://api.hookstride.com/control/v1/projects/{project_id}/' \
-H "Authorization: Bearer $HOOKSTRIDE_CONTROL_TOKEN"const response = await fetch("https://api.hookstride.com/control/v1/projects/{project_id}/", {
method: "GET",
headers: {"Authorization":"Bearer YOUR_CONTROL_TOKEN"},
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"GET", "https://api.hookstride.com/control/v1/projects/{project_id}/",
headers={"Authorization":"Bearer YOUR_CONTROL_TOKEN"},
timeout=20,
)
response.raise_for_status()GET/control/v1/projects/{project_id}/usage/Project usage history
Project usage history
Get current usage, up to 12 months of history, and subscription details.
{
"current": {
"events_ingested": 125,
"event_quota": 1000
},
"history": [],
"subscription": {
"plan_code": "free",
"status": "active"
}
}curl -X GET 'https://api.hookstride.com/control/v1/projects/{project_id}/usage/' \
-H "Authorization: Bearer $HOOKSTRIDE_CONTROL_TOKEN"const response = await fetch("https://api.hookstride.com/control/v1/projects/{project_id}/usage/", {
method: "GET",
headers: {"Authorization":"Bearer YOUR_CONTROL_TOKEN"},
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"GET", "https://api.hookstride.com/control/v1/projects/{project_id}/usage/",
headers={"Authorization":"Bearer YOUR_CONTROL_TOKEN"},
timeout=20,
)
response.raise_for_status()GET/control/v1/projects/{project_id}/subscription/Subscription details
Subscription details
Read the project's current subscription status.
{
"provider": "direct",
"plan_code": "free",
"status": "active"
}curl -X GET 'https://api.hookstride.com/control/v1/projects/{project_id}/subscription/' \
-H "Authorization: Bearer $HOOKSTRIDE_CONTROL_TOKEN"const response = await fetch("https://api.hookstride.com/control/v1/projects/{project_id}/subscription/", {
method: "GET",
headers: {"Authorization":"Bearer YOUR_CONTROL_TOKEN"},
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"GET", "https://api.hookstride.com/control/v1/projects/{project_id}/subscription/",
headers={"Authorization":"Bearer YOUR_CONTROL_TOKEN"},
timeout=20,
)
response.raise_for_status()GET/control/v1/projects/{project_id}/api-keys/List API keys
List API keys
List masked keys for a project. The raw secret is never returned again.
[
{
"id": "KEY_UUID",
"name": "Production server",
"masked_key": "whrk_••••",
"is_active": true
}
]curl -X GET 'https://api.hookstride.com/control/v1/projects/{project_id}/api-keys/' \
-H "Authorization: Bearer $HOOKSTRIDE_CONTROL_TOKEN"const response = await fetch("https://api.hookstride.com/control/v1/projects/{project_id}/api-keys/", {
method: "GET",
headers: {"Authorization":"Bearer YOUR_CONTROL_TOKEN"},
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"GET", "https://api.hookstride.com/control/v1/projects/{project_id}/api-keys/",
headers={"Authorization":"Bearer YOUR_CONTROL_TOKEN"},
timeout=20,
)
response.raise_for_status()POST/control/v1/projects/{project_id}/api-keys/Issue API key
Issue API key
Create a project-scoped key. Store the raw key securely: it is shown only at issuance.
{
"name": "Production server",
"expires_days": 90
}{
"api_key": {
"id": "KEY_UUID",
"name": "Production server"
},
"key": "whrk_••••"
}curl -X POST 'https://api.hookstride.com/control/v1/projects/{project_id}/api-keys/' \
-H "Authorization: Bearer $HOOKSTRIDE_CONTROL_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Production server","expires_days":90}'const response = await fetch("https://api.hookstride.com/control/v1/projects/{project_id}/api-keys/", {
method: "POST",
headers: {"Authorization":"Bearer YOUR_CONTROL_TOKEN","Content-Type":"application/json"},
body: JSON.stringify({"name":"Production server","expires_days":90}),
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"POST", "https://api.hookstride.com/control/v1/projects/{project_id}/api-keys/",
headers={"Authorization":"Bearer YOUR_CONTROL_TOKEN"},
json=json.loads("{\"name\":\"Production server\",\"expires_days\":90}"),
timeout=20,
)
response.raise_for_status()DELETE/control/v1/projects/{project_id}/api-keys/{key_id}/Revoke API key
Revoke API key
Immediately revoke a key. Revoked credentials cannot access the data API.
204 No Contentcurl -X DELETE 'https://api.hookstride.com/control/v1/projects/{project_id}/api-keys/{key_id}/' \
-H "Authorization: Bearer $HOOKSTRIDE_CONTROL_TOKEN"const response = await fetch("https://api.hookstride.com/control/v1/projects/{project_id}/api-keys/{key_id}/", {
method: "DELETE",
headers: {"Authorization":"Bearer YOUR_CONTROL_TOKEN"},
});
if (!response.ok) throw new Error("Request failed: "+response.status);import json
import requests
response = requests.request(
"DELETE", "https://api.hookstride.com/control/v1/projects/{project_id}/api-keys/{key_id}/",
headers={"Authorization":"Bearer YOUR_CONTROL_TOKEN"},
timeout=20,
)
response.raise_for_status()No matching endpoints. Try a different method, path or keyword.
Errors & limits
Predictable HTTP responses help integrations recover safely.
| Status | Meaning | Action |
|---|---|---|
| 400 | Invalid request or parameters | Correct the body, filter or URL. |
| 401 | Invalid or expired credentials | Check your bearer token or API key. |
| 403 | Insufficient permissions | Use an appropriately authorized role. |
| 404 | Unknown or inaccessible resource | Check the ID and project scope. |
| 409 | Idempotency conflict | Use new idempotency data or replay a terminal event. |
| 429 | Quota or rate limit exceeded | Wait for reset or review plan usage. |
Examples are illustrative and never contain real API keys.Read the signing and retry guide →