EventsLocationsSpacesSolutionsPricingIntegrationsAPIBlogHelp
EventsLocationsSpacesSolutionsPricingIntegrationsAPIBlogHelp
© 2026 AOA
Getting startedArtistsFor artistsOrganizersVenuesPast eventsCareersPartnersBubble avatarBento pageGitHub
AboutWhat is AOAPrivacySecurityTermsMerchantCookies
Pricing
UAEN
PricingSupport
FOR PEOPLE
People nearbyHow it worksAOA ConnectSuspended coffee
FOR BUSINESS
VenuesOrganizersFor space ownersFor artists and bands
Solutions
Event check-inEvent networkingTelegram botBento pageLoyalty programSuspended coffeeNFC tags for venues
Extend AOA
IntegrationsAPI & SDK
Help centerDocumentationBlogAbout AOAContact

API reference

  • Introduction
  • Authentication
  • Sandbox
  • Rate limits
  • Errors
  • Versioning
  • Events
  • Reservations
  • Checkout

Webhooks

  • Introduction
  • Event types
  • Verifying signatures
  • Make, Zapier, n8n

Webhooks

Introduction

AOA outgoing webhooks: the platform tells your system about payments, refunds and cancelled events. How to register a URL and what it must meet.

A webhook means we send a request to you the moment something happens: a ticket is paid for, money is refunded, an event is cancelled. You don’t have to keep polling us.

Event cancellations matter most

Polling the order status covers the payment, but not what happens later. An event can be cancelled a week after the purchase, and nobody polls the status of a ticket bought long ago. Without a webhook your system simply won’t find out.

How to connect

You need an API key with the webhooks:write scope. Register the URL to send requests to and list the events:

cURL
curl -X POST https://aoa.com.ua/api/v1/webhooks \
  -H "Authorization: Bearer aoa_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/hooks/aoa",
    "events": ["order.paid", "event.cancelled"]
  }'
JSON
{
  "data": {
    "id": "8f3c1a92-…",
    "url": "https://example.com/hooks/aoa",
    "events": ["order.paid", "event.cancelled"],
    "secret": "whsec_9Kq2mR7vXp4nT8wL5yB1zC4d",
    "createdAt": "2026-07-30T12:00:00.000Z"
  }
}

The secret is shown once

The secret field is only returned in the response to creation. After that we store it encrypted and can’t show it again. Save it right away: you use it to verify the signature of every request.

One key can have up to 10 URLs, which is handy when test and production environments listen on different hosts.

URL requirements

  • Only https and port 443 or 8443.
  • The host must be public. Addresses on internal networks (localhost, 10.x, 192.168.x, 169.254.x) are rejected. The check runs both at registration and before every delivery: if the domain later starts resolving to an internal address, we stop sending to it.
  • For local development, use a tunnel such as ngrok or a URL from Make or webhook.site: they are public.

What a delivery looks like

HTTP
POST /hooks/aoa HTTP/1.1
Content-Type: application/json
AOA-Signature: t=1800000000,v1=5f2a…
AOA-Delivery-Id: 3d9f7c21-…
AOA-Event-Type: order.paid

{
  "id": "3d9f7c21-…",
  "type": "order.paid",
  "createdAt": "2026-07-30T12:00:00.000Z",
  "data": {
    "paymentId": "d3f1a2b4-…",
    "eventId": "a1b2c3",
    "status": "SUCCESS",
    "amountMinor": 90000,
    "currency": "UAH",
    "attendeeId": "clx9attendee01"
  }
}
HeaderPurpose
AOA-SignatureThe body signature. Always verify it, see Verifying signatures
AOA-Delivery-IdDelivery identifier. It stays the same on retries, so deduplicate by it
AOA-Event-TypeEvent type. It repeats the type field in the body and is handy for routing

What your handler should do

  • Respond fast. Any 2xx code means “accepted”. We wait up to 10 seconds for a response, so do heavy work after responding, not before.
  • Be ready for retries. The same event can arrive twice: we didn’t get your response in time, even though you processed it. Check against AOA-Delivery-Id.
  • Verify the signature before processing. Your handler URL will become known sooner or later, and the signature is the only thing that tells our request apart from anyone else’s.

What happens if your server is down

We retry the delivery with growing pauses: after a minute, 5 minutes, 30 minutes, 2 hours and 6 hours. That’s about nine hours in total, enough to ride out a night-time deploy or an outage.

If a URL doesn’t respond for a very long time, we switch it off automatically so we don’t keep a queue of dead requests. The same happens at once, with no retries, if the URL starts resolving to an internal network; the reason will show in the lastError field of the last delivery.

You can see the state in GET/api/v1/webhooks, in the disabledAt field. To switch it back on:

cURL
curl -X PATCH https://aoa.com.ua/api/v1/webhooks/{id} \
  -H "Authorization: Bearer aoa_live_…" \
  -H "Content-Type: application/json" \
  -d '{"isActive": true}'

No code

You don’t have to write a handler: AOA webhooks work with Make, Zapier and n8n directly. Ready-made recipes are in Make, Zapier, n8n.

PreviousCheckoutNextEvent types