Appointments API & Webhooks
Update a lead's appointment status from a buyer's CRM or a calendar tool. Endpoints, fields, and error codes for appointment tracking in Lead Distro AI.
Post an appointment status from a CRM
The buyer outcome webhook accepts an appointment status alongside everything else it already handles. The buyer authenticates with their own secret, so they can only touch their own leads.
curl -X POST https://www.leaddistro.ai/api/webhooks/buyer-outcome \
-H "X-Buyer-Secret: BUYER_WEBHOOK_SECRET" \
-H "Content-Type: application/json" \
-d '{
"lead_id": "LEAD_UUID",
"appointment_status": "showed"
}'| Field | Type | Required | Notes |
|---|---|---|---|
| lead_id | string | Yes* | The lead to update. Instead of this you may match on phone or email plus campaign_id. |
| appointment_status | enum | Yes* | One of booked, showed, no_show, canceled. Send this or appointment_qualified. |
| appointment_at | ISO 8601 | No | When the appointment is scheduled. Usually sent with booked. Must include a timezone offset. |
| appointment_qualified | enum | No | One of qualified, unqualified. The review call on an appointment that showed up. Only accepted when the campaign tracks qualification, otherwise the call returns 403. |
Send appointment_at with the booking. Without it you know an appointment exists but not when, which makes time-to-appointment and upcoming-appointment views impossible to build later.
Booking and attendance in one flow
A typical integration sends two calls. The first when the appointment is created, the second when the buyer knows whether it happened.
// 1. When the appointment is booked
{
"lead_id": "LEAD_UUID",
"appointment_status": "booked",
"appointment_at": "2026-09-11T15:00:00-07:00"
}
// 2. After the appointment time passes
{
"lead_id": "LEAD_UUID",
"appointment_status": "showed"
}Sending the same status twice is safe. A repeat of a status the lead already has is recognized and does not bill twice.
Reporting the review
If the buyer pays for appointments that showed up and qualified, a third call reports the review. It is a separate field, not another appointment status, so posting "appointment_status": "qualified" returns 400.
// 3. After someone reviews the appointment
{
"lead_id": "LEAD_UUID",
"appointment_qualified": "qualified"
}The two marks can arrive in either order. If the review lands before the show is reported, nothing bills until the show arrives, and then it bills once. Send unqualified when the review decides the appointment was not worth paying for. If it had already been billed, the charge is reversed.
Call outcomes
If the booking comes out of a phone call rather than a calendar, post it as a call outcome instead. This needs no appointment feature enabled.
curl -X POST https://www.leaddistro.ai/api/v1/lead-update \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"lead_id": "LEAD_UUID",
"call_outcome": "appointment_set"
}'Outcome stages
Both endpoints also accept a stage field carrying a custom outcome stage key, which is how you record an appointment without the billing add-on.
{
"lead_id": "LEAD_UUID",
"stage": "meeting_booked"
}Error codes
| Code | Meaning | Fix |
|---|---|---|
| 400 | The appointment status is not one of the four allowed values. | Send exactly booked, showed, no_show, or canceled, lowercase. |
| 400 | The lead has not been accepted yet. | A buyer can only set an appointment on a lead they accepted. Deliver and accept it first. |
| 401 | The buyer secret is missing or wrong. | Send the buyer's secret in the X-Buyer-Secret header. |
| 403 | Appointment tracking is not enabled for the account. | Contact support to have it turned on. |
| 404 | No matching lead. | Check the lead id, or that the matching phone or email belongs to a lead assigned to this buyer. |
Frequently Asked Questions
How does a buyer's CRM report that an appointment showed up?
https://www.leaddistro.ai/api/webhooks/buyer-outcome with the buyer's secret in the X-Buyer-Secret header and a body containing the lead id and appointment_status. The four accepted values are booked, showed, no_show, and canceled. Add appointment_at with an ISO timestamp when reporting a booking.Where do I find these fields in the app?
Is it safe to send the same appointment status twice?
Why am I getting a 400 saying the lead has not been accepted?
Why am I getting a 403 on the appointment endpoints?
stage value instead to record the same thing through outcome stages.Why am I getting a 403 when I post appointment_qualified?
Why does posting appointment_status of qualified return 400?
appointment_qualified with a value of qualified or unqualified. Keeping them apart is what lets an appointment be Showed and Unqualified at the same time, which is a real and common state.Related Articles
If you have any questions, send us an email at support@leaddistro.ai