Hooks

Set the app's setup and teardown hooks

Operation ID: putHooks

PUT
/hooks

Replaces the app's hooks. The first save makes the signing secret and returns it; later saves keep it. Both URLs are checked: https, a public host, standard port (400 invalid_request otherwise).

Needs an API key with the manage scope.

Authorization

apiKey
headerAuthorizationBearer <oq_ followed by 43 letters and digits>

An Outqube API key, made in the app's settings. It belongs to one app and has the scope read, trigger or manage; a higher scope includes the lower ones. A revoked or expired key is a 401.

Request Body

application/json
  1. body

Replaces the app's hooks. Anything left out gets its default.

setup_url?|

Called before a run's first test: an https:// URL, or null for none.

Defaultnull
teardown_url?|

Called after a run's last test: an https:// URL, or null for none.

Defaultnull
timeout_seconds?integer

Seconds to wait for an answer, 1 to 120; default 30.

Range1 <= value <= 120
Default30
enabled?boolean

Whether Outqube calls the hooks; default true.

Defaulttrue

Response Body

OK

application/json
  1. response

The hooks as saved; the signing secret comes with the app's first save only.

app_id*string

The app the hooks belong to.

Match^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
Formatuuid
setup_url*|

Called before a run's first test; null for none.

teardown_url*|

Called after a run's last test; null for none.

timeout_seconds*integer

Seconds to wait for an answer: 1 to 120.

Range-9007199254740991 <= value <= 9007199254740991
enabled*boolean

Whether Outqube calls the hooks.

secret_hint*string

The last 4 characters of the signing secret.

previous_secret_expires_at*|

After a rotation, when the previous secret stops signing; else null.

created_at*string

When the hooks were first saved.

Match^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
Formatdate-time
updated_at*string

When the hooks last changed.

Match^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z))$
Formatdate-time
secret*|

The signing secret, only on the save that made it (the app's first); else null.

Example Request
curl -X PUT 'https://app.outqube.com/api/v1/hooks' \  -H 'Content-Type: application/json' \  -d '{  "setup_url": "https://staging.acme.test/outqube/setup",  "teardown_url": "https://staging.acme.test/outqube/teardown",  "timeout_seconds": 30,  "enabled": true}'
Example Response
{  "app_id": "9b1d2f4e-7a3c-4c58-9e0b-6f3a1d2c4b5a",  "setup_url": "https://staging.acme.test/outqube/setup",  "teardown_url": "https://staging.acme.test/outqube/teardown",  "timeout_seconds": 30,  "enabled": true,  "secret_hint": "q7Wd",  "previous_secret_expires_at": null,  "created_at": "2026-10-25T10:05:00.000Z",  "updated_at": "2026-10-25T10:05:00.000Z",  "secret": "whsec_c2FtcGxlLWhvb2tzLWtleS1ub3QtYS1zZWNyZXQhISE="}