Manage webhooks via API
You can manage webhooks programmatically with the same Public API used for envelopes and workspaces: signed POST requests over the Oak tunnel (or via the TypeScript / Python SDK).
Prerequisites
Section titled “Prerequisites”- Team API key in Settings → API Keys with Webhook permissions (e.g. Manage for full CRUD, or granular Create / Read / Update / Delete).
- Plan must include webhooks (same as creating webhooks in the app).
- Use the Encryption Proxy or an SDK so traffic is encrypted end-to-end.
Endpoints
Section titled “Endpoints”All routes are POST (body is JSON). Paths below are what the SDK uses after the base URL / tunnel:
| Action | Path | Permission (typical) |
|---|---|---|
| Create | /public/webhook/create | Create or Manage on Webhook |
| List | /public/webhook/list | Read or Manage on Webhook |
| Update | /public/webhook/update | Update or Manage on Webhook |
| Delete | /public/webhook/delete | Delete or Manage on Webhook |
Request and response shapes match the session webhook API; see the OpenAPI specification for full schemas.
Limits
Section titled “Limits”Each team can have at most 20 webhooks. If you call create when the team already has 20, the API returns WEBHOOK_LIMIT_REACHED (HTTP 400).
TypeScript (SDK)
Section titled “TypeScript (SDK)”import { SubnotoClient } from "@subnoto/api-client";
const client = new SubnotoClient({ accessKey: process.env.API_ACCESS_KEY!, secretKey: process.env.API_SECRET_KEY!});
const { data: created } = await client.POST("/public/webhook/create", { body: { url: "https://api.example.com/subnoto-webhook", contentType: "application/json", sslVerify: true, active: true, events: ["ENVELOPE_COMPLETED"], title: "Production hook" }});
const { data: listed } = await client.POST("/public/webhook/list", { body: { page: 1, limit: 50 }});
await client.POST("/public/webhook/update", { body: { uuid: created!.webhook.uuid, active: false, title: "Paused hook" }});
await client.POST("/public/webhook/delete", { body: { uuid: created!.webhook.uuid }});Python (SDK)
Section titled “Python (SDK)”from subnoto_api_client import SubnotoSyncClient, SubnotoConfig
with SubnotoSyncClient(SubnotoConfig()) as client: r = client.post( "/public/webhook/create", json={ "url": "https://api.example.com/subnoto-webhook", "contentType": "application/json", "sslVerify": True, "active": True, "events": ["ENVELOPE_COMPLETED"], "title": "Production hook", }, ) uuid = r.json()["webhook"]["uuid"]
client.post("/public/webhook/list", json={"page": 1, "limit": 50})
client.post( "/public/webhook/update", json={"uuid": uuid, "active": False, "title": "Paused hook"}, )
client.post("/public/webhook/delete", json={"uuid": uuid})