Webhooks
Learn how admins create Ternary webhooks that send budget alerts to an AI agent or workflow tool, and how to edit, disable, rotate secrets for and delete them.
Webhooks let Ternary deliver notifications to other tools, in addition to email and Slack. For example, when a budget alert fires, Ternary sends the alert to each Webhook subscribed to it. This can start a Claude routine, a ChatGPT workspace agent, or a workflow in a tool such as Zapier, Make or Power Automate.
Who can set up and use Webhooks?
| Role | What they can do |
|---|---|
| Admins | Create, test, edit, disable, enable and delete Webhooks in Admin › Integrations › Webhooks |
| Anyone with permission to set up notifications | Select an existing Webhook as a subscriber when they configure budget alerts |
An admin creates a Webhook once. After that, anyone who can set up alert notifications can send alerts to it, alongside email recipients and Slack channels. To attach a webhook to a budget and see example workflows, see Automate budget follow-up with Ternary Webhooks.
Which Webhooks are available?
| Webhook | Sends the alert to | Use it to |
|---|---|---|
| Claude Routine | A Claude routine in claude.ai | Have a Claude agent investigate the alert with Ternary MCP |
| OpenAI Workspace Agent | A workspace agent in ChatGPT | Have a ChatGPT agent investigate the alert with Ternary MCP |
| Custom HTTPS | Any public HTTPS endpoint that accepts a POST request | Start a workflow in Zapier, Make, Power Automate or your own service |
What do you need before you start?
- An admin role in Ternary.
- An endpoint URL from the tool that will receive alerts, and a token for it. A token is required for Claude Routine and OpenAI Workspace Agent Webhooks, and optional for Custom HTTPS. Any token must be at least 16 characters. Step 1 explains where to find them for each kind.
Keep the endpoint URL and token secretAnyone with both can start your workflow. Enter them only in Ternary, and store any copy in your password manager. Some tools show the token only once.
Ternary stores tokens, custom header values and signing secrets encrypted, and never shows them again after you save. The Webhook list and Details show only the first and last three characters of a token.
How is a Webhook configured in Ternary?
Step 1: Get the endpoint URL and token
Create the destination in the receiving tool first, then copy its endpoint URL and token.
Claude Routine
- In claude.ai, go to Code › Routines and open your routine, or select New routine to create one.
- Make sure the routine has the Ternary connector, so it can look up the alert in Ternary.
- Edit the routine, select Add another trigger › API, then select Generate token.
- Copy the fire URL and the token. The token is shown only once. The URL has the form
https://api.anthropic.com/v1/claude_code/routines/trig_…/fire, and Ternary checks it matches that form.
See Automate work with scheduled tasks in Anthropic's documentation for more about routines.
OpenAI Workspace Agent
- In ChatGPT, create the workspace agent and publish it. Ternary can't start an agent that hasn't been published.
- Open the agent's API channel.
- Copy the API URL and the access token. The URL has the form
https://api.chatgpt.com/v1/workspace_agents/agtch_…/trigger.
Custom HTTPS
Create an incoming webhook in your tool and copy its URL. For example:
- Zapier: trigger Webhooks by Zapier › Catch Hook.
- Make: module Webhooks › Custom webhook.
- Power Automate: trigger When an HTTP request is received.
The URL must use https://, must point to a public host, and must not contain credentials such as a user name, password or key. Pass credentials as a bearer token or a header instead. Ternary doesn't send to private or internal addresses.
If your endpoint requires a bearer token, also create or copy one of at least 16 characters.
Step 2: Create the Webhook
- Open Admin in Ternary, select the Integrations tab and scroll to Webhooks. The list shows each webhook's Name, Type and Status.
- Select Create Webhook, then choose the kind: Claude Routine, OpenAI Workspace Agent or Custom HTTPS.
- Complete the form for that kind, as described below. Test Connection and Save become available once the required fields are filled.
To leave without saving, select Back to Webhooks.
Claude Routine
| Field | What to enter |
|---|---|
| Name | A name people will recognise when they choose alert subscribers, such as Cost Investigation Routine. Names must be unique in your tenant. |
| Routine Endpoint | The routine's fire URL from Step 1 |
| API Token | The routine's token from Step 1 |
OpenAI Workspace Agent
| Field | What to enter |
|---|---|
| Name | A recognizable, unique name, such as Cost Investigation Agent |
| API URL | The agent's API URL from Step 1 |
| Access Token | The agent's access token from Step 1 |
Ternary stores only the agent ID from the URL, and shows the full URL again in Details.
Custom HTTPS
| Field | What to enter |
|---|---|
| Name (required) | A recognizable, unique name, such as Jira Automation |
| Endpoint URL (required) | Your tool's Webhook URL from Step 1, with no credentials in it |
| Authentication | Bearer Token (the default) to send Authorization: Bearer <token>, or None |
| Token (required for Bearer Token) | Your bearer token |
| Headers (optional) | Select Add Header to add up to 10 extra headers, each a name and a value. You can't use authorization, content-type, user-agent, or any name starting with webhook-, because Ternary sets these itself. |
Step 3: Test the connection
- Select Test Connection.
- Ternary sends a test message with the headline Ternary webhook test to the endpoint.
- Check the result in the form. Any 2xx response is a success. A Claude routine typically shows Response 200 OK, and an OpenAI Workspace Agent shows Response 202 OK.
If the test fails, the form shows the status code and a reason, such as 401 Unauthorized. Check the authentication details and try again., 404 Request rejected, Host not reachable, Timed out, TLS handshake failed or Endpoint blocked. See Troubleshooting.
- Check the receiving tool. For a Claude routine, a new run appears in claude.ai. If you used the prompt from Automate budget follow-up with Ternary Webhooks, the routine replies Test received.
The test confirms that Ternary can reach your tool and that the token is accepted. It doesn't send a budget alert, and it doesn't change the webhook's status or failure count.
Each test starts a real runFor Claude routines and OpenAI agents, every test starts a run that uses your plan's capacity. Test sparingly.
Step 4: Complete the configuration
- Select Save.
- For a Custom HTTPS Webhook, Ternary now shows a signing secret that starts with
whsec_. Copy it straight away; it's shown only once. Your endpoint can use it to confirm that requests come from Ternary.
The Webhook now appears in the Webhooks list with the status Connected. Anyone with permission to set up notifications can select it under Add Subscribers › Webhooks in the alerts step of a budget.
What does Ternary send?
When a budget alert fires, Ternary sends one HTTPS POST request to each subscribed Webhook. The alert content is the same as the budget alert email, as plain text: the headline, a summary of spend or projected spend against the budget amount for the period, a link to the budget, and a footer.
Claude Routine
POST <Routine Endpoint>
Authorization: Bearer <API Token>
anthropic-version: 2023-06-01
Content-Type: application/json
{"text": "<budget alert text>"}
The routine receives the alert text as its input. A successful request returns 200 OK and starts a new session. See Trigger a routine through the API in Anthropic's documentation.
OpenAI Workspace Agent
POST https://api.chatgpt.com/v1/workspace_agents/<agent ID>/trigger
Authorization: Bearer <Access Token>
OpenAI-Beta: workspace_agent_runs=v1
Idempotency-Key: <delivery ID>
Content-Type: application/json
{"input": "<budget alert text>", "conversation_key": "<budget ID>"}
Because the conversation key is the budget ID, every alert for the same budget continues the same agent conversation.
Custom HTTPS
Ternary sends a JSON envelope with the event id, type (budget-alert), occurredAt, tenantID, workflowID and data (the alert's headline, summary and link). Each request includes content-type: application/json, user-agent: Ternary-Webhooks/1, and the signature headers webhook-id, webhook-timestamp and webhook-signature, followed by your bearer token and custom headers.
For the full field reference and signature verification samples, see Webhooks reference.
Delivery is retried up to three timesTernary makes up to three attempts per alert, 5 seconds and then 10 seconds apart, when the failure might be temporary: a 5xx response, a connection error, or a 429 response. For a 429, Ternary waits for the time in the
Retry-Afterheader, up to 10 minutes.Any other 4xx response is final and isn't retried. A Claude routine that accepts the request but never answers isn't retried either.
Ternary waits up to 5 seconds to connect and 30 seconds in total. Respond with a 2xx quickly, then do the work afterwards.
Every attempt for the same alert carries the same
webhook-id, so a Custom HTTPS endpoint can ignore duplicates. Claude routines have no equivalent, so in rare cases a retry after a 5xx can start a second routine session.
How do admins manage a Webhook?
Each Webhook in Admin › Integrations › Webhooks has an action menu (⋮) at the end of its row, with Details, Edit, Disable or Enable, and Delete. Use Search above the list to find a webhook by name.
A Webhook shows one of three statuses:
| Status | Meaning |
|---|---|
| Connected | Deliveries are succeeding |
| Warning | The last three alerts in a row failed. Details shows the last failure's reason, status code and time. The next successful delivery clears the warning. |
| Disabled | Twenty alerts in a row failed, or an admin disabled the webhook. Ternary skips it until it's enabled again. |
Edit a Webhook
- Go to Admin › Integrations › Webhooks.
- Open the Webhook's action menu (⋮) and select Edit.
- Update the name or endpoint, then select Test Connection. If you changed the endpoint, enter the token again before testing; the form shows Enter the token to test changed settings. A name-only change tests the stored settings.
- Select Save.
Budgets that already subscribe to the Webhook use the updated settings from the next alert onwards.
Disable or enable a Webhook
To pause deliveries without changing any budgets, open the Webhook's action menu and select Disable. The Webhook keeps its budget subscriptions but is skipped when alerts are sent. A disabled Webhook can't be added to more budgets.
To resume deliveries, select Enable. If Ternary disabled the Webhook after repeated failures, fix the cause first.
Rotate the token
Rotate the token if it may have been shared, if someone who had it leaves your team, or as part of your regular key rotation.
- Generate a new token in the receiving tool.
- Claude Routine: edit the routine and select Regenerate next to the API token. The old token stops working immediately.
- OpenAI Workspace Agent: generate a new access token in the agent's API channel.
- Custom HTTPS: create the new token in your tool.
- In Ternary, edit the webhook and paste the new token into API Token, Access Token or Token.
- Select Test Connection, then Save.
Update Ternary as soon as you rotateUntil you save the new token in Ternary, alerts are rejected with a 401. Ternary doesn't retry rejected requests, and after three rejected alerts in a row the Webhook shows Warning.
Rotate the signing secret (Custom HTTPS)
- Edit the Webhook and select Regenerate next to the signing secret, then confirm.
- Copy the new secret. It's shown only once.
- Update the verification key in your endpoint at the same time. Requests signed with the new secret fail verification until you do.
Delete a Webhook
Ternary can't delete a Webhook while any budget subscribes to it; the message says how many budgets use it. Remove the Webhook from those budgets first. To stop deliveries without editing budgets, disable it instead.
- Go to Admin › Integrations › Webhooks.
- Open the Webhook's action menu (⋮) and select Delete.
- In the Delete Webhook dialog, confirm. Deleting can't be undone.
Deleting the Webhook in Ternary doesn't delete the routine, agent or workflow in the receiving tool.
Troubleshooting
| Symptom | Likely cause | What to do |
|---|---|---|
| Test Connection returns 401 | The token is wrong, expired or revoked | Generate a new token and update the Webhook |
| Test Connection returns 404 | The endpoint URL is wrong, or the routine or agent was deleted | Copy the URL again from the receiving tool |
| Test Connection returns 400 for a Claude routine | The routine is paused in claude.ai | Resume the routine in claude.ai |
| Test Connection returns 409 for an OpenAI agent | The agent isn't published, so OpenAI reports it isn't runnable | Publish the agent in ChatGPT |
| Test Connection says Endpoint blocked | The URL points to a private or internal address | Use a public HTTPS endpoint |
| Test Connection says Host not reachable, Timed out or TLS handshake failed | DNS, a response slower than 30 seconds, or a certificate problem at the receiving end | Check the host name, respond faster, or fix the certificate |
| The Claude routine replied Test received | It received the test message | Expected for Test Connection |
| Test succeeds but no budget alert arrives | An alert is sent once per threshold per budget period. A budget that was already past a threshold when the webhook was added won't alert again until a new threshold is crossed or the next period starts. | Add a threshold the budget hasn't crossed yet, or wait for the next period. Check the webhook is selected under Add Subscribers › Webhooks and its status is Connected. |
| A sub-budget alert didn't reach the webhook | Sub-budget (allocation) alerts aren't sent to webhooks | Add the webhook to the parent budget's alerts |
| The webhook isn't listed under Add Subscribers › Webhooks | It's disabled, or it hasn't been created yet | Ask an admin to enable or create it |
| Webhook shows Warning | Three alerts in a row failed | Open Details to see the last failure, then fix the endpoint |
| Webhook shows Disabled | Twenty alerts in a row failed, or an admin disabled it | Fix the cause, then select Enable in the action menu |
| Requests fail with 429 after many alerts | The receiving tool's rate limit was reached. Claude routines accept 30 starts per routine per hour (including Run now) and 100 API starts per account per hour. | Ternary waits and retries automatically. If it keeps happening, spread alerts across more routines or reduce alert rules. |
| Your endpoint rejects the signature | Verification ran on re-serialised JSON, or with an old secret | Verify against the raw request body, with the secret shown at creation or the last Regenerate |
Updated about 2 hours ago
