Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
title: Anyhook Net Apps API
version: 1.0.0
description: 'Operations tagged Apps across 2 of this provider''s published API definitions: openapi.json, anyhook-net-openapi.json. Each path carries the servers of the definition it was published in.'
servers:
- url: https://anyhook.net
description: Management API
- url: https://in.anyhook.net
description: Ingress (webhook receiver)
security:
- ApiKeyAuth: []
tags:
- name: Apps
paths:
/api/v1/apps:
get:
operationId: listApps
summary: List all apps
description: Returns all webhook relay apps for the authenticated user.
security:
- ApiKeyAuth: []
responses:
'200':
description: List of apps
content:
application/json:
schema:
type: object
properties:
apps:
type: array
items:
$ref: '#/components/schemas/App'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
tags:
- Apps
post:
operationId: createApp
summary: Create a new webhook relay app
description: 'Creates a webhook relay app and returns its inbound URL, to paste into the sender''s webhook settings.
Required: name (string). Optional: destination_url (your server endpoint; without one the app logs events without forwarding them), source (default ''auto'').'
security:
- ApiKeyAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- name
properties:
name:
type: string
description: Human-readable name for this app.
destination_url:
type: string
format: uri
description: Your server's endpoint URL that will receive forwarded webhooks.
source:
type: string
enum:
- auto
- stripe
- github
- shopify
- lemonsqueezy
- paddle
- sentry
- sendgrid
- svix
- clerk
- resend
- slack
- line
- twilio
- intercom
- linear
- vercel
- discord
- hubspot
- woocommerce
- paypal
- generic
default: auto
responses:
'201':
description: App created
content:
application/json:
schema:
type: object
properties:
app:
$ref: '#/components/schemas/App'
'401':
description: Unauthorized
'429':
description: Plan limit reached (app count or daily event cap)
tags:
- Apps
servers:
- url: https://anyhook.net
description: Management API
- url: https://in.anyhook.net
description: Ingress (webhook receiver)
/api/v1/apps/{slug}:
patch:
operationId: updateApp
summary: Update an app
description: Updates destination URLs or toggles the app active state.
security:
- ApiKeyAuth: []
parameters:
- name: slug
in: path
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
type: object
properties:
destinations:
type: array
description: 'Replaces the whole list. Each item: url (required), enabled, headers (object), event_types, rate_limit, delay_seconds. The three controls are Pro+ and answer 403 on Free unless unchanged from what is stored.'
items:
type: object
properties:
url:
type: string
format: uri
enabled:
type: boolean
headers:
type: object
additionalProperties:
type: string
event_types:
type: array
items:
type: string
rate_limit:
type: integer
minimum: 1
maximum: 1000
delay_seconds:
type: integer
minimum: 1
maximum: 86400
required:
- url
is_active:
type: boolean
responses:
'200':
description: App updated
content:
application/json:
schema:
type: object
properties:
app:
$ref: '#/components/schemas/App'
'401':
description: Unauthorized
'404':
description: App not found
tags:
- Apps
delete:
operationId: deleteApp
summary: Delete an app
description: 'Permanently deletes a relay app and immediately stops accepting inbound webhooks.
Event history is preserved (app_id set to null on existing events).
Use this to clean up temporary apps created for one-time tasks.'
security:
- ApiKeyAuth: []
parameters:
- name: slug
in: path
required: true
schema:
type: string
responses:
'200':
description: App deleted
content:
application/json:
schema:
type: object
properties:
deleted:
type: boolean
'401':
description: Unauthorized
'404':
description: App not found
tags:
- Apps
servers:
- url: https://anyhook.net
description: Management API
- url: https://in.anyhook.net
description: Ingress (webhook receiver)
/api/v1/apps/{slug}/destinations/{index}/rotate-secret:
post:
operationId: rotateDestinationSecret
summary: Rotate destination signing secret
description: Rotates the HMAC signing secret for a specific destination. If no secret is provided in the request body, a new random secret is generated. Returns the new signing secret.
security:
- ApiKeyAuth: []
parameters:
- name: slug
in: path
required: true
schema:
type: string
- name: index
in: path
required: true
schema:
type: integer
description: Zero-based index of the destination in the app's destinations array.
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
secret:
type: string
description: Custom signing secret. If omitted, a random secret is generated.
responses:
'200':
description: Secret rotated
content:
application/json:
schema:
type: object
properties:
destination_index:
type: integer
signing_secret:
type: string
'400':
description: Invalid request (e.g. index out of range)
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Unauthorized
'404':
description: App not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: Rate limit exceeded. Check Retry-After header.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
tags:
- Apps
servers:
- url: https://anyhook.net
description: Management API
- url: https://in.anyhook.net
description: Ingress (webhook receiver)
/api/v1/apps/{slug}/events/undelivered:
get:
operationId: listUndeliveredEvents
summary: List undelivered events for an app
description: Returns events with status 'retrying' or 'failed' for a specific app. Useful for monitoring delivery health and identifying events that need manual replay.
security:
- ApiKeyAuth: []
parameters:
- name: slug
in: path
required: true
schema:
type: string
- name: since
in: query
schema:
type: string
format: date-time
description: ISO-8601 datetime. Defaults to 24 hours ago.
- name: limit
in: query
schema:
type: integer
default: 100
maximum: 200
responses:
'200':
description: Undelivered event list
content:
application/json:
schema:
type: object
properties:
events:
type: array
items:
$ref: '#/components/schemas/Event'
count:
type: integer
'401':
description: Unauthorized
'429':
description: Rate limit exceeded. Check Retry-After header.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
tags:
- Apps
servers:
- url: https://anyhook.net
description: Management API
- url: https://in.anyhook.net
description: Ingress (webhook receiver)
/api/v1/apps/{slug}/replay-failed:
post:
operationId: replayFailedEvents
summary: Bulk replay failed events
description: 'Re-delivers failed events for an app, oldest first: those created after `since` (default: 24 hours ago), at most `limit` per call. An event replayed once is not selected again, so calling again continues with the rest while `more` is true. Does NOT consume event quota.'
security:
- ApiKeyAuth: []
parameters:
- name: slug
in: path
required: true
schema:
type: string
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
since:
type: string
format: date-time
description: ISO-8601 datetime. Only replay events created after this timestamp.
limit:
type: integer
default: 50
maximum: 100
description: Maximum number of events to replay.
responses:
'200':
description: Bulk replay queued
content:
application/json:
schema:
type: object
properties:
replayed:
type: integer
events:
type: array
items:
type: object
properties:
original_id:
type: string
format: uuid
new_id:
type: string
format: uuid
skipped:
type: array
description: Selected events that were not replayed, and why.
items:
type: object
properties:
original_id:
type: string
format: uuid
reason:
type: string
enum:
- expired
- no_destination
- queue_failed
more:
type: boolean
description: More failed events in the window are waiting past this call's limit.
since:
type: string
format: date-time
description: The start of the window used.
'401':
description: Unauthorized
'404':
description: App not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: Rate limit exceeded. Check Retry-After header.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
tags:
- Apps
servers:
- url: https://anyhook.net
description: Management API
- url: https://in.anyhook.net
description: Ingress (webhook receiver)
/api/v1/apps/{slug}/code:
get:
operationId: getCodeHandler
summary: Read an app's code handler
description: The code that runs on every event this app receives, its secret names, and runs used this month.
security:
- ApiKeyAuth: []
parameters:
- name: slug
in: path
required: true
schema:
type: string
responses:
'200':
description: The handler
content:
application/json:
schema:
type: object
properties:
app:
type: string
plan_allows:
type: boolean
description: 'False on Free: code handlers are on Pro and Scale.'
code:
type:
- string
- 'null'
description: The handler's source; null when the app has none.
secret_names:
type: array
items:
type: string
description: Names only; values never leave the server.
packages:
type: object
additionalProperties:
type: string
description: npm packages the code imports, name → version ("latest" unless pinned), installed when it was saved.
schedule:
type:
- string
- 'null'
description: The cron it also runs on, if any.
receiving:
type: boolean
description: Whether the app's events reach the code (its run destination is present and enabled).
destination:
type: string
enum:
- 'on'
- 'off'
description: 'on: the app''s run destination is there and events run the code. off: it is not, and the code runs only through POST .../code/test.'
disabled:
type: boolean
runs_this_month:
type: integer
runs_per_month:
type:
- integer
- 'null'
description: The plan's monthly run cap; null = unlimited.
'404':
description: App not found
tags:
- Apps
put:
operationId: putCodeHandler
summary: Save code that runs on every event
description: Save an ES module that runs in a sandboxed Node.js on every event this app receives, with AnyHook's retries and replay around it. `export default async function (event, { env, store }) {}`, where event is `{ method, headers, body, raw_body, delivery_id, attempt }` (method is always POST; the query string, path and caller IP are not kept; attempt is 0 on a test run), or a Pipedream Node.js code step (`defineComponent({ run({ steps, $ }) {} })`) with the changes listed at https://anyhook.net/migrate/pipedream. npm packages it imports are installed when it is saved (pin a version as `pkg@1.2.3`); a save that installs new packages can take a few minutes, and a failed install changes nothing (400 with npm's output). Throwing fails the delivery, which is retried on the plan's attempts. Pro and Scale; runs are capped per month with no overage, and retries, test runs, replays and schedule firings each count.
security:
- ApiKeyAuth: []
parameters:
- name: slug
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- code
properties:
code:
type: string
description: The handler's source, at most 64,000 bytes as UTF-8.
secrets:
type: object
additionalProperties:
type:
- string
- 'null'
description: Environment variables for the code (env.NAME, or process.env.NAME in a Pipedream step). Merged into the saved ones; null removes a name. Names are letters, digits and underscores, not starting with a digit; PATH, HOME, NODE_OPTIONS, NODE_PATH, PWD and names starting with ANYHOOK_ belong to the runtime. A save past the limit on the number of secrets or on a value's length answers 400 naming the limit.
schedule:
type:
- string
- 'null'
description: 'Also run on a cron schedule: five fields, UTC unless prefixed CRON_TZ=Area/City. Each firing posts an anyhook.schedule event to the app''s own URL, so it counts as a run and as an event, and it fires only while the code is on. null removes it; omit to keep it. The app''s source must be generic or auto, with no signing secret; otherwise 400.'
enabled:
type: boolean
description: 'Whether events run the code. false saves it switched off (it runs only through POST .../code/test). Omitted: a first save goes live, later saves keep the current state; the dashboard saves new code switched off. While another destination still handles the same events, as in a migration, save with false and turn it on after removing that destination. A switch takes up to a minute to reach every edge location.'
responses:
'200':
description: Saved
content:
application/json:
schema:
type: object
properties:
app:
type: string
plan_allows:
type: boolean
description: 'False on Free: code handlers are on Pro and Scale.'
code:
type:
- string
- 'null'
description: The handler's source; null when the app has none.
secret_names:
type: array
items:
type: string
description: Names only; values never leave the server.
packages:
type: object
additionalProperties:
type: string
description: npm packages the code imports, name → version ("latest" unless pinned), installed when it was saved.
schedule:
type:
- string
- 'null'
description: The cron it also runs on, if any.
receiving:
type: boolean
description: Whether the app's events reach the code (its run destination is present and enabled).
destination:
type: string
enum:
- 'on'
- 'off'
description: 'on: the app''s run destination is there and events run the code. off: it is not, and the code runs only through POST .../code/test.'
disabled:
type: boolean
runs_this_month:
type: integer
runs_per_month:
type:
- integer
- 'null'
description: The plan's monthly run cap; null = unlimited.
'400':
description: Invalid code, secrets or schedule, or npm could not install the packages (npm's output included)
'403':
description: Plan without code handlers, read-only key, or no room for another destination
'503':
description: Installing packages failed on AnyHook's side; nothing was saved. Try again.
tags:
- Apps
delete:
operationId: deleteCodeHandler
summary: Remove an app's code handler
description: Deletes the code and its secrets and removes the app's run destination.
security:
- ApiKeyAuth: []
parameters:
- name: slug
in: path
required: true
schema:
type: string
responses:
'200':
description: Removed
tags:
- Apps
servers:
- url: https://anyhook.net
description: Management API
- url: https://in.anyhook.net
description: Ingress (webhook receiver)
/api/v1/apps/{slug}/code/test:
post:
operationId: testCodeHandler
summary: Run an app's code now
description: Runs the saved handler on a stored event (the latest when event_id is omitted) or on a body you pass, and answers with its logs and return value. Counts as a run. Nothing is delivered; whatever the code itself sends does happen.
security:
- ApiKeyAuth: []
parameters:
- name: slug
in: path
required: true
schema:
type: string
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
event_id:
type: string
format: uuid
body:
description: Run on this body instead of a stored event.
responses:
'200':
description: The run's outcome (ok is false when the handler threw)
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
value:
description: What the handler returned, as JSON.
exports:
description: Values passed to $.export.
exited:
type: string
description: Set when the handler ended early with $.flow.exit.
error:
type: string
logs:
type: string
description: Console output, last 16,000 characters.
ms:
type: integer
event_id:
type:
- string
- 'null'
format: uuid
'403':
description: Read-only key, a plan without code handlers, or a handler AnyHook disabled
'404':
description: No handler, or no event to run on
'429':
description: Monthly runs used up
tags:
- Apps
servers:
- url: https://anyhook.net
description: Management API
- url: https://in.anyhook.net
description: Ingress (webhook receiver)
/api/v1/apps/{slug}/store:
get:
operationId: listCodeStore
summary: Read an app's code store
description: Every live key in the store the app's code reads and writes (store.get/set in a run, or a Pipedream step's data_store prop). At most 1,000 keys, each value at most 64,000 bytes as JSON.
security:
- ApiKeyAuth: []
parameters:
- name: slug
in: path
required: true
schema:
type: string
responses:
'200':
description: The store
content:
application/json:
schema:
type: object
properties:
entries:
type: object
additionalProperties: true
tags:
- Apps
post:
operationId: importCodeStore
summary: Import keys into an app's code store
description: 'Set many keys at once from {"entries": {key: value}}. Existing keys are overwritten, and imported keys have no TTL. Pipedream''s workflow export leaves data stores out, so build the entries yourself.'
security:
- ApiKeyAuth: []
parameters:
- name: slug
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- entries
properties:
entries:
type: object
additionalProperties: true
responses:
'200':
description: Imported
content:
application/json:
schema:
type: object
properties:
imported:
type: integer
'400':
description: A key or value over the limits
tags:
- Apps
delete:
operationId: clearCodeStore
summary: Delete a key, or empty the store
description: With ?key=, removes that key; without, removes every key.
security:
- ApiKeyAuth: []
parameters:
- name: slug
in: path
required: true
schema:
type: string
- name: key
in: query
required: false
schema:
type: string
responses:
'200':
description: Deleted
tags:
- Apps
servers:
- url: https://anyhook.net
description: Management API
- url: https://in.anyhook.net
description: Ingress (webhook receiver)
components:
schemas:
Error:
type: object
properties:
error:
type: string
App:
type: object
description: An app as the API returns it. Destination signing secrets appear only at creation or rotation.
properties:
id:
type: string
name:
type: string
slug:
type: string
source:
type: string
sourceSecret:
type: boolean
description: Whether a sender signing secret is set.
isActive:
type: boolean
inboundUrl:
type: string
inboxAddress:
type: string
destinations:
type: array
items:
type: object
properties:
url:
type: string
enabled:
type: boolean
headers:
type: object
has_signing_secret:
type: boolean
signing_secret_hint:
type: string
event_types:
type: array
items:
type: string
rate_limit:
type: integer
delay_seconds:
type: integer
eventsThisMonth:
type: integer
createdAt:
type: string
format: date-time
previousSlugs:
type: array
items:
type: string
Event:
type: object
description: An event summary, as GET /api/v1/events lists it.
properties:
id:
type: string
appId:
type: string
appName:
type: string
source:
type: string
eventType:
type:
- string
- 'null'
status:
type: string
enum:
- queued
- success
- retrying
- failed
- rejected
- circuit_open
- quota_exceeded
attempt:
type: integer
maxAttempts:
type: integer
isReplay:
type: boolean
replayOf:
type:
- string
- 'null'
outboundUrl:
type:
- string
- 'null'
outboundStatus:
type:
- integer
- 'null'
latencyMs:
type:
- integer
- 'null'
createdAt:
type: string
format: date-time
nextRetryAt:
type:
- string
- 'null'
format: date-time
securitySchemes:
ApiKeyAuth:
type: http
scheme: bearer
bearerFormat: ahk_live_xxx
description: 'API key from Dashboard Settings > API Keys. Format: ahk_live_<32 alphanumeric chars>. Example header: Authorization: Bearer ahk_live_a1b2c3...'
x-refined-from:
- openapi.json
- anyhook-net-openapi.json