Send events to a URL, a Slack channel or a GitHub repository (repository_dispatch) as they happen (paid plans).

POSThttps://api.appgoat.ai/v1/webhooks
FreeoperationId createWebhook

kind:

  • webhook (default): POST of the event JSON, signed with appgoat-signature: t=<unix>,v1=<hex HMAC-SHA256(secret, "<t>.<raw body>")>. The secret is returned once, here (rotate with PATCH rotate_secret). Answer 2xx within 10 s.
  • slack: url is a Slack incoming webhook (https://hooks.slack.com/services/…).
  • github: url is owner/repo, github_token a fine-grained token with Contents: read and write on it. Sends { event_type: "appgoat.<type>", client_payload: <event> } to start a workflow on: repository_dispatch. Failed deliveries are retried after 1 min, 5 min, 30 min, 2 h, 6 h, 12 h and 24 h; an endpoint failing 50 times in a row is disabled (PATCH active=true re-enables it). Free plan: 402 plan_limit (use GET /v1/events).

Request

curl -X POST "https://api.appgoat.ai/v1/webhooks" \
  -H "x-api-key: $APPGOAT_API_KEY" \
  -H "content-type: application/json" \
  -d '{"url":"string","kind":"webhook","event_types":["new_version"],"description":"string","github_token":"string"}'

Request body

JSON, required.

urlstring
https URL (webhook), Slack incoming webhook URL (slack) or owner/repo (github).
kind"webhook" | "slack" | "github"
event_typesEventType[] | null
null = every type.
descriptionstring | null
github_tokenstring
kind github only; never returned.

Response

201 with data: WebhookEndpoint. See the envelope for meta.

idinteger
kind"webhook" | "slack" | "github"
urlstring
github: owner/repo; slack: shortened (the URL is a credential).
descriptionstring | null
event_typesEventType[] | null
activeboolean
disabled_reasonstring | null
failure_countinteger
Consecutive failed attempts.
last_success_atstring | null
last_failure_atstring | null
secretstring
kind webhook: the signing secret, only in the create / rotate response.
secret_hintstring
created_atstring
updated_atstring
Example
{
  "data": {
    "id": 1,
    "kind": "webhook",
    "url": "string",
    "description": "string",
    "event_types": [
      "new_version"
    ],
    "active": false,
    "disabled_reason": "string",
    "failure_count": 1,
    "last_success_at": "2026-10-22T10:00:00Z",
    "last_failure_at": "2026-10-22T10:00:00Z",
    "secret": "string",
    "secret_hint": "string",
    "created_at": "2026-10-22T10:00:00Z",
    "updated_at": "2026-10-22T10:00:00Z"
  },
  "meta": {
    "credits_used": 0,
    "credits_remaining": 9981,
    "request_id": "req_123"
  }
}

Status codes

201
The endpoint, with its signing secret (only now).
A parameter is missing or invalid (error.param names it).
Missing or invalid API key.
insufficient_credits (the call costs more than you have left; nothing was done) or plan_limit (a feature of a higher plan).
Too many requests per second for your plan.