Create a webhook
const url = 'https://api.hyperresearch.ai/v1/webhooks';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"url":"https://example.com/hooks/hyperresearch","events":["run.clarifying"]}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.hyperresearch.ai/v1/webhooks \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "url": "https://example.com/hooks/hyperresearch", "events": [ "run.clarifying" ] }'The signing secret is returned once. The URL is checked against the SSRF guard at registration and again at delivery.
Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”object
Example
https://example.com/hooks/hyperresearchResponses
Section titled “ Responses ”Created
object
The wire values this endpoint is subscribed to. * means every event.
The same subscription with a human name for each event (“Run finished”, “A source needs your decision”), so a picker never has to show run.done (E2E5-08). Same order as events; an event this build does not recognise keeps its raw value as its label. The full catalogue, with descriptions, is GET /v1/webhooks/events.
object
How many deliveries to this endpoint gave up after exhausting their retries (1 m, 5 m, 30 m, 2 h, 12 h). These are gone: nothing re-sends them. GET /v1/webhooks/{id}/deliveries lists them with the status each attempt got back.
Example
{ "id": "wh_01J9ZQ7V6H0000000000000000", "dead_deliveries": 0, "secret": "whsec_…"}Headers
Section titled “Headers”Example
"reads";q=60;w=60The quota policy this request was counted against (draft-ietf-httpapi-ratelimit-headers): "<bucket>";q=<requests>;w=<window seconds>, e.g. "reads";q=60;w=60. Buckets: reads 60/min, status 600/min, creates 10/min, writes 20/min per credential; public 300/min per network on keyless routes.
Example
"reads";r=57;t=41Remaining quota in the current window: "<bucket>";r=<remaining>;t=<seconds until reset>, e.g. "reads";r=57;t=41.
Requests allowed per window in this bucket (legacy form of RateLimit-Policy).
Requests left in this window (legacy form of RateLimit).
Unix time (seconds) when the window resets.
Which bucket counted the request: reads, status, creates, writes or public.
Invalid request
object
object
Example
{ "error": { "type": "invalid_request", "code": "missing_api_key", "request_id": "req_01J9ZQ7V6H0000000000000000" }}Authentication failed
object
object
Example
{ "error": { "type": "invalid_request", "code": "missing_api_key", "request_id": "req_01J9ZQ7V6H0000000000000000" }}Insufficient scope or plan
object
object
Example
{ "error": { "type": "invalid_request", "code": "missing_api_key", "request_id": "req_01J9ZQ7V6H0000000000000000" }}Not found
object
object
Example
{ "error": { "type": "invalid_request", "code": "missing_api_key", "request_id": "req_01J9ZQ7V6H0000000000000000" }}Rate limited or over quota
object
object
Example
{ "error": { "type": "invalid_request", "code": "missing_api_key", "request_id": "req_01J9ZQ7V6H0000000000000000" }}Headers
Section titled “Headers”Seconds to wait before retrying. Always present on a 429.
Example
"reads";q=60;w=60The quota policy this request was counted against (draft-ietf-httpapi-ratelimit-headers): "<bucket>";q=<requests>;w=<window seconds>, e.g. "reads";q=60;w=60. Buckets: reads 60/min, status 600/min, creates 10/min, writes 20/min per credential; public 300/min per network on keyless routes.
Example
"reads";r=57;t=41Remaining quota in the current window: "<bucket>";r=<remaining>;t=<seconds until reset>, e.g. "reads";r=57;t=41.
Requests allowed per window in this bucket (legacy form of RateLimit-Policy).
Requests left in this window (legacy form of RateLimit).
Unix time (seconds) when the window resets.
Which bucket counted the request: reads, status, creates, writes or public.
Internal error
object
object
Example
{ "error": { "type": "invalid_request", "code": "missing_api_key", "request_id": "req_01J9ZQ7V6H0000000000000000" }}