---
title: "Subscribe a target URL to a trigger event (REST Hook)"
method: POST
path: "/api/v1/hooks"
tags: ["Webhooks"]
---

# Subscribe a target URL to a trigger event (REST Hook)

`POST /api/v1/hooks`

## Request

- Base URL: `https://api.agendaforge.app`
- URL: `https://api.agendaforge.app/api/v1/hooks`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-API-Key`

Re-subscribing the same URL and event is a no-op that returns the existing subscription id. Each delivery POSTs an envelope of the form { event, timestamp, payload }, where payload is the resource object; map payload.* rather than the top level. Deliveries are retried up to 3 times and carry an X-Webhook-Signature header (HMAC-SHA256 of the raw request body, keyed with the endpoint signing secret). This endpoint does not return that secret, so a subscription made here cannot be verified; use a long, unguessable target URL over HTTPS. Webhooks added in the AgendaForge app show their secret once, at creation.

## Query parameters

- `source` 'zapier' | 'make' | 'n8n'

## Request body

- object
  - `event` 'contact.added' | 'contact.added_to_event' | 'contact.updated' | 'contact.removed' | 'sponsor.added' | 'sponsor.updated' | 'sponsor.removed' | 'session.added' | 'session.updated' | 'session.removed' | 'speaker.confirmed' | 'speaker.declined' | 'submission.created' | 'submission.status_changed' | 'review.completed' | 'event.published', required: Trigger event names accepted by POST /api/v1/hooks and GET /api/v1/triggers/{event}/sample.
  - `targetUrl` string, uri, required: The http(s) URL deliveries are POSTed to.

## Response `200`

The subscription id (existing id when re-subscribing).

- object
  - `id` string, required: Webhook subscription id.

## Other responses

- `400`: A required field is missing or invalid, an unknown event was supplied, or a referenced record is not owned by the key's organization.
- `401`: The API key is missing, malformed, invalid, expired, or revoked.
- `403`: The API key is valid but does not include the public_api scope. Create a key with the public_api scope in Settings > API Tokens.
- `404`: No such endpoint under /api/v1. The message lists the valid endpoints.
- `429`: The fixed window for this API key (120 requests per minute) or IP (30 per minute, unauthenticated) is exhausted. Wait Retry-After seconds and retry.
- `500`: An unexpected server failure. The body still follows the JSON error contract; retry with exponential backoff.
- `default`: Any other failure, including 404 NOT_FOUND for an unknown path and transient 5xx errors. Always the same JSON error contract.

---

[API](https://skmtc.dev/agendaforge/apis/agendaforge-public-rest-api.md) · [All operations](https://skmtc.dev/agendaforge/apis/agendaforge-public-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/agendaforge/apis/agendaforge-public-rest-api/revisions/b8956ce1e5f3?raw)
