HookSteadBETA

00 / API reference

HookStead REST API

Everything in the dashboard, over HTTPS and JSON. This page is generated from the same schemas the server validates requests with.

  • Base URL: https://hookstead.dev/api/v1
  • Auth: Authorization: Bearer hw_live_… (Settings → API keys). Keys are scoped to one organization and capped at ADMIN.
  • Errors: application/problem+json with a stable code. Another tenant's resources always answer 404.
  • Retries: send an Idempotency-Key where marked; the same key and body return the stored response for 24 hours.
  • OpenAPI 3.1: /api/openapi.json for code generators and API clients.

Account

GET/me

Who am I

Role: VIEWER

200
The caller: a user, or an API key with its organization and role.

Organizations

GET/organizations

List my organizations

Role: VIEWER

200
Organizations the caller belongs to, with their role.
POST/organizations

Create an organization

The caller becomes OWNER; a default production workspace is created.

Role: VIEWERSigned-in users only

Body

name *string1–80 chars
slug *string2–48 chars
201
The organization.
GET/organizations/{orgId}

Get an organization

Role: VIEWER

200
The organization and the caller's role.
PATCH/organizations/{orgId}

Rename or change the URL of an organization

Role: ADMIN

Body

namestring1–80 chars
slugstring2–48 chars
200
The updated organization.
GET/organizations/{orgId}/members

List members

Role: VIEWER

200
Members with their roles.

Workspaces

GET/organizations/{orgId}/workspaces

List workspaces

Role: VIEWER

200
Workspaces of the organization.
POST/organizations/{orgId}/workspaces

Create a workspace

Counts toward the plan's workspace limit (403 plan_limit_reached).

Role: ADMIN

Body

name *string1–80 chars
slug *string2–48 chars
201
The workspace.
GET/workspaces/{wsId}

Get a workspace

Role: VIEWER

200
The workspace.
PATCH/workspaces/{wsId}

Update a workspace

Role: ADMIN

Body

namestring1–80 chars
slugstring2–48 chars
200
The updated workspace.
DELETE/workspaces/{wsId}

Delete a workspace and everything in it

Role: ADMIN

204
Deleted.

Billing

GET/organizations/{orgId}/billing

Plan, usage and limits

Usage counts ingested events plus replayed deliveries in the current UTC month.

Role: VIEWER

200
{billingEnabled, plan, status, currentPeriodEnd, cancelAtPeriodEnd, entitledPlan, entitledUntil, graceEndsAt, usage, limits}.
POST/organizations/{orgId}/billing/checkout

Start Stripe Checkout for a paid plan

Return URLs are fixed on the server. 409 if a subscription exists (use the portal).

Role: OWNERIdempotency-Key: requiredSigned-in users only

Body

plan *"PRO" | "TEAM"
interval"month" | "year"default "month"
200
{url}: redirect the user there.
POST/organizations/{orgId}/billing/portal

Open the Stripe customer portal

Role: OWNERSigned-in users only

200
{url}: redirect the user there.

Sources

GET/workspaces/{wsId}/sources

List sources

Role: VIEWER

200
Sources with their ingest URLs. Secrets are never returned (hasSecret).
POST/workspaces/{wsId}/sources

Create a source

Senders POST webhooks to the returned ingestUrl. Plan limits apply.

Role: MEMBER

Body

name *string1–80 chars
provider"stripe" | "lemonsqueezy" | "quickbooks" | "paypal" | "shopify" | "github" | "gitlab" | "linear" | "dockerhub" | "vercel" | "aws-sns" | "hubspot" | "openai" | "clerk" | "supabase" | "standard-webhooks" | "custom" | nulldefault null
authType"NONE" | "HMAC_SHA256" | "STRIPE" | "GITHUB" | "SHOPIFY" | "STANDARD_WEBHOOKS" | "BASIC_AUTH" | "HEADER_TOKEN" | "VERCEL" | "HUBSPOT" | "AWS_SNS" | "PAYPAL"default "NONE"
authConfigobjectdefault {}
authSecretstring0–1024 chars
allowedMethods"GET" | "HEAD" | "POST" | "PUT" | "PATCH" | "DELETE"[]
maxBodyBytesinteger1024–9007199254740991
dedupeStrategyobject | nulldefault null
redactionRulesobjectdefault {"headers":[],"keys":[]}
responseStatus200 | 201 | 202 | 204default 202
201
The source, with its ingest URL.
GET/workspaces/{wsId}/sources/{sourceId}

Get a source

Role: VIEWER

200
The source.
PATCH/workspaces/{wsId}/sources/{sourceId}

Update a source

Changing authType, authConfig, authSecret or redactionRules needs ADMIN.

Role: MEMBER

Body

namestring1–80 chars
provider"stripe" | "lemonsqueezy" | "quickbooks" | "paypal" | "shopify" | "github" | "gitlab" | "linear" | "dockerhub" | "vercel" | "aws-sns" | "hubspot" | "openai" | "clerk" | "supabase" | "standard-webhooks" | "custom" | null
authType"NONE" | "HMAC_SHA256" | "STRIPE" | "GITHUB" | "SHOPIFY" | "STANDARD_WEBHOOKS" | "BASIC_AUTH" | "HEADER_TOKEN" | "VERCEL" | "HUBSPOT" | "AWS_SNS" | "PAYPAL"
authConfigobject
authSecretstring0–1024 chars
allowedMethods"GET" | "HEAD" | "POST" | "PUT" | "PATCH" | "DELETE"[]
maxBodyBytesinteger1024–9007199254740991
dedupeStrategyobject | null
redactionRulesobject
responseStatus200 | 201 | 202 | 204
enabledboolean
200
The updated source.
DELETE/workspaces/{wsId}/sources/{sourceId}

Delete a source

Its ingest URL stops working immediately.

Role: MEMBER

204
Deleted.
POST/workspaces/{wsId}/sources/{sourceId}/rotate-token

Rotate the ingest URL

The old URL returns 404 immediately.

Role: ADMIN

200
The source with its new ingest URL.

Destinations

GET/workspaces/{wsId}/destinations

List destinations

Role: VIEWER

200
Destinations with health. Header values are masked.
POST/workspaces/{wsId}/destinations

Create a destination

The response contains the signing secret (whsec_…) once. Plan limits apply.

Role: MEMBER

Body

name *string1–80 chars
url *string1–2048 chars
method"POST" | "PUT" | "PATCH"default "POST"
headersobject
timeoutMsinteger1000–9007199254740991
maxAttemptsinteger1–9007199254740991
backoffBaseMsinteger1000–3600000, default 30000
backoffMaxMsinteger1000–86400000, default 21600000
retryOn4xxbooleandefault false
maxConcurrencyinteger1–100, default 10
201
The destination and its signingSecret.
GET/workspaces/{wsId}/destinations/{destinationId}

Get a destination

Role: VIEWER

200
The destination.
PATCH/workspaces/{wsId}/destinations/{destinationId}

Update a destination

Role: MEMBER

Body

namestring1–80 chars
urlstring1–2048 chars
method"POST" | "PUT" | "PATCH"
headersobject
timeoutMsinteger1000–9007199254740991
maxAttemptsinteger1–9007199254740991
backoffBaseMsinteger1000–3600000
backoffMaxMsinteger1000–86400000
retryOn4xxboolean
maxConcurrencyinteger1–100
200
The updated destination.
DELETE/workspaces/{wsId}/destinations/{destinationId}

Delete a destination

Pending deliveries to it are cancelled.

Role: MEMBER

204
Deleted.
POST/workspaces/{wsId}/destinations/{destinationId}/pause

Pause deliveries

New deliveries are held until resumed.

Role: MEMBER

200
The destination.
POST/workspaces/{wsId}/destinations/{destinationId}/resume

Resume deliveries

Role: MEMBER

200
The destination.
POST/workspaces/{wsId}/destinations/{destinationId}/rotate-signing-secret

Rotate the signing secret

During overlapHours both secrets sign every delivery.

Role: ADMIN

Body

overlapHoursinteger0–72, default 0
200
The destination and its new signingSecret (shown once).
GET/workspaces/{wsId}/destinations/{destinationId}/health

Health and hourly stats

Role: VIEWER

Query parameters

fromstring
tostring
granularity"hour" | "day"
200
Current health and an hourly series of attempts.

Connections

GET/workspaces/{wsId}/connections

List connections

Role: VIEWER

200
Source → destination connections.
POST/workspaces/{wsId}/connections

Connect a source to a destination

Role: MEMBER

Body

sourceId *string
destinationId *string
201
The connection.
PATCH/workspaces/{wsId}/connections/{connectionId}

Enable or disable a connection

Role: MEMBER

Body

enabled *boolean
200
The connection.
DELETE/workspaces/{wsId}/connections/{connectionId}

Delete a connection

Role: MEMBER

204
Deleted.

Events

GET/workspaces/{wsId}/events

Search events

Newest first, keyset pagination (cursor).

Role: VIEWER

Query parameters

sourceIdstring
fromstring
tostring
deliveryStatus"PENDING" | "SCHEDULED" | "IN_FLIGHT" | "SUCCEEDED" | "DEAD" | "CANCELLED"[]
errorClassstring[]
httpStatusinteger100–599
qstring3–200 chars
headerstring[]
jsonPathstring0–600 chars
cursorstring
limitinteger1–100, default 50
200
{data, nextCursor}; bodies and headers are the redacted copies.
GET/workspaces/{wsId}/events/{eventId}

Get an event

Role: VIEWER

200
The event (redacted) and its deliveries.
GET/workspaces/{wsId}/events/{eventId}/raw

Get the original request (decrypted)

ADMIN only; every view is audit-logged.

Role: ADMIN

200
Original headers and body, as received.
POST/workspaces/{wsId}/events/{eventId}/replay

Replay an event

Creates new deliveries (to the connected destinations, or destinationIds). Counts toward the monthly quota; rate limited.

Role: MEMBERIdempotency-Key: required

Body

destinationIdsstring[]
202
{deliveries: [{id, destinationId}]}.

Deliveries

GET/workspaces/{wsId}/deliveries

Search deliveries

Role: VIEWER

Query parameters

status"PENDING" | "SCHEDULED" | "IN_FLIGHT" | "SUCCEEDED" | "DEAD" | "CANCELLED"[]
destinationIdstring
sourceIdstring
eventIdstring
errorClassstring[]
httpStatusinteger100–599
trigger"INITIAL" | "MANUAL_RETRY" | "REPLAY"
fromstring
tostring
cursorstring
limitinteger1–100, default 50
200
{data, nextCursor}.
GET/workspaces/{wsId}/deliveries/{deliveryId}

Get a delivery and its attempts

Role: VIEWER

200
The delivery with every attempt's request and response (headers masked).
POST/workspaces/{wsId}/deliveries/{deliveryId}/retry

Retry a delivery now

409 while it's in flight or after it succeeded (replay the event instead).

Role: MEMBERIdempotency-Key: required

202
The delivery, queued.
POST/workspaces/{wsId}/deliveries/{deliveryId}/cancel

Cancel a pending delivery

Role: MEMBER

200
The delivery.
POST/workspaces/{wsId}/deliveries/bulk-retry

Retry many deliveries

Up to 1,000 matching deliveries, as a background job. dryRun only counts.

Role: MEMBERIdempotency-Key: required

Body

filterobjectdefault {}
dryRunbooleandefault false
200
Dry run: {jobId: null, matched, capped}.
202
{jobId, matched, capped}.
GET/workspaces/{wsId}/jobs/{jobId}

Bulk job progress

Role: VIEWER

200
The job's status and counts.

Monitoring

GET/workspaces/{wsId}/metrics

Workspace metrics

Role: VIEWER

Query parameters

fromstring
tostring
granularity"hour" | "day"
200
Totals and an hourly or daily series of events, attempts and latency.
GET/workspaces/{wsId}/alert-rules

List alert rules

Role: VIEWER

200
Alert rules.
POST/workspaces/{wsId}/alert-rules

Create an alert rule

Recipients must be members of the organization.

Role: MEMBER

Body

name *string1–80 chars
type *"FAILURE_RATE" | "CONSECUTIVE_FAILURES" | "DEAD_DELIVERIES" | "SOURCE_INACTIVE"
subjectIdstring (uuid) | nulldefault null
threshold *number0–1000000
windowSec *integer60–604800
minSamplesinteger1–100000, default 10
cooldownSecinteger0–604800, default 3600
recipients *string (email)[]
enabledbooleandefault true
201
The rule.
GET/workspaces/{wsId}/alert-rules/{ruleId}

Get an alert rule

Role: VIEWER

200
The rule.
PATCH/workspaces/{wsId}/alert-rules/{ruleId}

Update an alert rule

Role: MEMBER

Body

namestring1–80 chars
subjectIdstring (uuid) | null
thresholdnumber0–1000000
windowSecinteger60–604800
minSamplesinteger1–100000
cooldownSecinteger0–604800
recipientsstring (email)[]
enabledboolean
200
The rule.
DELETE/workspaces/{wsId}/alert-rules/{ruleId}

Delete an alert rule

Its open incidents close without email.

Role: MEMBER

204
Deleted.
GET/workspaces/{wsId}/incidents

List incidents

Role: VIEWER

Query parameters

state"OPEN" | "RESOLVED"
cursorstring
limitinteger1–100, default 50
200
{data, nextCursor}.
POST/workspaces/{wsId}/incidents/{incidentId}/acknowledge

Acknowledge an incident

Role: MEMBER

200
The incident.