Developers
The Partner Booking API lets marketplaces, calendars, and integration platforms read a tenant’s services and availability and create bookings on their behalf. Signed webhooks report booking creation and cancellation events produced by the integration.
Every request must include a Bearer token. Tenants generate and revoke keys in Settings → Integrations in Avena Flow. Each key belongs to one tenant and has specific permissions.
Authorization: Bearer afp_live_8k3...Key format: afp_live_ prefix plus 32 random bytes in URL-safe base64.
/api/v1/public/servicesReturns active, bookable services for the authenticated tenant.
curl https://avenaflow.com/api/v1/public/services \
-H "Authorization: Bearer afp_live_..."Response
/api/v1/public/availabilityReturns open slots over a date range, honoring staff hours, blocks, and configured lead time.
| Param | Type | Notes |
|---|---|---|
| service_id | string | required — UUID returned by /services |
| from | YYYY-MM-DD | optional — defaults to today |
| to | YYYY-MM-DD | optional — defaults to start date + 14 days (max 60) |
| staff_id | string | optional — filter to one staff member |
curl "https://avenaflow.com/api/v1/public/availability?service_id=a7b1&from=2026-06-10&to=2026-06-17" \
-H "Authorization: Bearer afp_live_..."/api/v1/public/bookingsCreates a confirmed appointment in the tenant’s calendar. A contact is created when the email or phone does not match an existing client. Returns 409 if the slot becomes unavailable before confirmation.
Idempotency: send partner_reference_id. Repeating the request with the same value returns the original booking without creating a duplicate.
curl -X POST https://avenaflow.com/api/v1/public/bookings \
+ -H "Authorization: Bearer afp_live_..." \
+ -H "Content-Type: application/json" \
+ -d '{"service_id":"a7b1...","start_time":"2026-06-10T14:00:00Z","customer":{"first_name":"Jane","last_name":"Doe","email":"jane@example.com","phone":"+14015551234"},"partner_reference_id":"partner_res_42"}'Response (201)
/api/v1/public/bookings/{id}Soft-cancels a booking and reopens the slot. A key can only cancel bookings created by the same partner.
curl -X DELETE "https://avenaflow.com/api/v1/public/bookings/ap_9f2?reason=customer_request" \
-H "Authorization: Bearer afp_live_..."Bookings created or cancelled through this API produce signed events for the tenant’s active endpoints. Other change events are not yet part of the public contract.
Implemented events
booking.createdbooking.cancelledRequest headers
POST /your/webhook HTTP/1.1
Content-Type: application/json
X-Avena-Signature: t=1717084800,v1=4f7b2...
X-Avena-Event: booking.cancelled
User-Agent: AvenaFlow-Webhooks/1.0Verify the signature
Concatenate {timestamp}.{raw_body}, create an HMAC-SHA256 with the signing secret, and compare it with v1 in constant time. Reject old timestamps to prevent replay.
import crypto from 'crypto'
function verify(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')))
const ts = Number(parts.t)
const expected = crypto.createHmac('sha256', secret).update(`${ts}.${rawBody}`).digest('hex')
return crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected))
}Retry policy
Delivery is attempted immediately. Failures remain queued for the retry worker; do not depend on an exact retry interval during beta.
/api/v1/public/calendar/{slug}.icsRead-only iCal feed identified by the tenant’s public booking slug. Because the link does not require authentication, share it only when that calendar exposure is appropriate.
All errors return JSON with an error key and, when helpful, message.
| Status | Error | Meaning |
|---|---|---|
| 400 | missing_required_fields | Required body fields are missing |
| 401 | missing_bearer_token | Authorization header is missing |
| 401 | invalid_api_key | Key was not found or is invalid |
| 401 | api_key_revoked | Key was revoked by the tenant |
| 403 | insufficient_scope | Key lacks the required permission |
| 404 | service_not_found | Service does not exist or is inactive |
| 409 | slot_unavailable | Slot became unavailable before confirmation |