Skip to main content
AgentaOS sends a webhook to your server when something happens in your account: a checkout is paid, a subscription renews or changes, a dispute opens, and more. Events lists every event and its payload. Webhooks tell your backend about a payment without polling. Build on them, not on the browser redirect after checkout.
Always verify the signature before you act on a webhook body. Anyone who knows your webhook URL can POST a fake payload to it. Verification is what proves the request actually came from AgentaOS.

Register a webhook URL

1

Open the webhook settings

In app.agentaos.ai, open Settings → Developers → Webhooks.
2

Set your endpoint

Enter the HTTPS URL you want events sent to, for example https://myshop.com/webhooks, and click Save. AgentaOS does not deliver to localhost or a private address: for local development, use a public HTTPS tunnel.
3

Reveal the signing secret

Click Reveal signing secret and copy the whsec_... value.
4

Store it as a secret

Add it to your server’s environment as AGENTAOS_WEBHOOK_SECRET. Never commit it, never log it, never send it to the client.
The signing secret stays the same when you change the URL. If you suspect it has been exposed, click Rotate secret to issue a new one. Rotating invalidates the old secret immediately, so deploy the new value first if you cannot afford failed deliveries.
You can also pass a webhookUrl when you create a checkout or payment link. That payment’s checkout.session.completed then goes to that URL instead of your account’s URL, signed with the same account secret. Every other event goes to the account’s URL.

Verify the signature

Every webhook request carries an X-AgentaOS-Signature header. Verifying it proves two things: the payload came from AgentaOS, and it hasn’t been replayed from an old request.
webhooks.verify() does four things, in order. It parses the t=...,v1=... header, and rejects a timestamp older than 5 minutes or in the future (replay protection). It recomputes the HMAC-SHA256 digest and compares it in constant time. Then it parses and returns a typed WebhookEvent. Any failure throws WebhookVerificationError instead of returning a falsy value, so your code cannot skip the check by accident.

Manual verification (no SDK)

The algorithm is HMAC-SHA256 over {timestamp}.{raw_body}, so any language with an HMAC and a constant-time compare can check it. The samples below apply the SDK’s time rule: they reject a timestamp older than the tolerance, and a timestamp in the future by any amount. Keep your server’s clock synced (NTP), or a clock that runs behind rejects every event.
Use a constant-time comparison (hmac.compare_digest, hmac.Equal, hash_equals, crypto.timingSafeEqual), never == or ===. A naive string comparison leaks timing information an attacker can use to forge a valid signature byte by byte.

Signature format

The timestamp t is part of the signed content, so a captured request cannot be replayed later: verification rejects anything older than 5 minutes by default, or dated in the future.

Delivery and retries

When your endpoint does not answer 2xx in time, AgentaOS tries again, up to 3 attempts in all, and then marks the event failed. You can send a failed event again from Settings → Developers → Webhooks. The exact timeouts, waits and refused addresses are in Delivery and retries.
Return 200 as soon as you have verified the signature and stored the event (a job, a database row). Do the actual work, such as fulfillment emails and external API calls, after you respond. A slow handler is the most common reason a delivery fails and repeats.

Best practices

Don't trust the redirect

The customer can close the browser before the successUrl redirect fires. Treat the webhook, not the redirect, as the proof that a payment happened.

Handle idempotently

Retries mean the same event can arrive more than once. Record a key per event and make your handler safe to run twice. The key for each event type is in Deduplication.

Respond quickly

Verify, queue, return 200. Do the slow work outside the request.

Verify every time

Never branch on event.data before webhooks.verify() (or the manual equivalent) has returned successfully.

Next steps

Event reference

Every event type, its full payload, and a JSON example.

Payment SDK: Webhooks

The webhooks resource in @agentaos/pay, in full.

Checkouts

Set a per-checkout webhookUrl when you create one.

Payouts

What happens to your balance after a payment lands.