Webhook Guide
Subscribe to appointment events and receive JSON payloads in your systems as they happen.
When to Use
- Keep CRMs, marketing platforms, or BI tools in sync without polling.
- Trigger custom automations (e.g., send swag kits when appointments are confirmed).
- Receive notifications for failures in external systems.
Core Concepts
- Location Scoped: Webhooks are created per location, so each header/payload is only sent for events at that location.
- Triggers: Must be a subset of
NEW_APPOINTMENT,APPOINTMENT_CONFIRMED,APPOINTMENT_CANCELLED,APPOINTMENT_RESCHEDULED,APPOINTMENT_REMINDER. - Headers: Optional key/value pairs appended to every delivery (use for auth tokens or tenant IDs).
- Active Flag: Toggle delivery without deleting configuration.
Endpoint Overview
| Endpoint | Purpose |
|---|---|
GET /v3/webhook?locationId=<uuid> | List webhooks for a location. |
POST /v3/webhook?locationId=<uuid> | Create a webhook (url, headers, triggers, active). |
POST /v3/webhook/setWebhooks?locationId=<uuid> | Replace the entire set for a location in one request. |
All routes require company authentication. Requests are validated by the schemas under api/validations/webhook/.
Payload Structure
Deliveries are POST requests with body:
{
"appointment": { ...appointment fields... },
"trigger": "NEW_APPOINTMENT"
}The appointment payload matches the object returned by the controller in processWebhooks. Sensitive internal fields are omitted.
Security Recommendations
- Verify signatures: Store a shared secret in the headers you configure, or include an HMAC signature. The API echoes the headers you define.
- Allowlist source IPs: Restrict your endpoint to OnSched IP ranges if possible.
- Respond quickly: Return a
2xxstatus within a few seconds. Long-running work should happen asynchronously on your side.
Retry Behavior
Webhooks are sent once. If the destination responds with a non-2xx status or times out, an error is logged but the API does not automatically retry. If reliability is critical, relay deliveries through your own queue or monitor logs via observability tooling to reprocess failures.
Troubleshooting
- Not receiving events: Ensure the webhook is
activeand that the location ID matches the appointments being created. - Multiple events per booking: Actions like rescheduling emit both
APPOINTMENT_RESCHEDULEDand a newNEW_APPOINTMENTfor the replacement slot, so handle idempotency by referencingappointment.id. - Headers missing: Remember to send headers as a nested JSON object when creating or setting webhooks. Only string values are supported.
Webhooks keep downstream systems synchronized with zero polling, while the API enforces security and payload consistency.
Updated 4 days ago
