Appointments API Reference
Create and cancel appointments from external calendar tools, and query calendar syncs, booked appointments, hosts, setters, meeting URLs, and outcome log states.
Create Appointment
Add an appointment to Hermon from an external calendar tool (for example, Cal.ai via Make.com). The lead is resolved by email (created if new), the event type is resolved by name (created as a SALES_CALL if new), and all standard booking side effects run — default statuses, the Call Booked notification, and outbound webhooks — exactly as an in-app booking.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| external_reference | string | Required | Unique ID of the booking from your source system (e.g. the Cal.ai booking ID). Used to prevent duplicates: sending the same value again returns the existing appointment instead of creating a new one. |
| schedule_time | string (ISO 8601) | Required | Appointment start time in UTC, e.g. 2026-08-20T15:00:00Z. |
| lead_email | string | Required | Attendee email. Finds an existing lead in your org by email, or creates a new lead if none matches. Required unless lead_id is provided. |
| event_type_name | string | Required | Name of the call/event type (e.g. "Sales Call"). Matched case-insensitively; if it does not exist yet, a new event type is created with call category SALES_CALL. Required unless event_type_id is provided. |
| lead_id | string (UUID) | Optional | Target an existing lead directly by UUID. Use instead of lead_email. |
| event_type_id | string (UUID) | Optional | Target an existing event type directly by UUID. Use instead of event_type_name. |
| lead_first_name | string | Optional | First name used when a new lead is created. Falls back to the email prefix if omitted. |
| lead_last_name | string | Optional | Last name used when a new lead is created. |
| lead_phone | string | Optional | Attendee phone number. E.164 format preferred (e.g. +14155551234); numbers that cannot be parsed are ignored. |
| host_email | string | Optional | Email of the host (closer) for the call. Must be an active member of your organization. |
| setter_email | string | Optional | Email of the setter. Must be an active member of your organization. |
| triager_email | string | Optional | Email of the triager. Must be an active member of your organization. |
| meeting_url | string | Optional | URL of the video/meeting room for the appointment. |
| notes | string | Optional | Free-text note attached to the appointment. |
Code Examples
curl -X POST "https://api.hermon.io/api/external/appointments" \
-H "Content-Type: application/json" \
-H "x-api-key: sk_live_your_key_here" \
-d '{
"external_reference": "cal-ai-booking-123",
"schedule_time": "2026-08-20T15:00:00Z",
"lead_email": "jane@example.com",
"event_type_name": "Sales Call",
"lead_first_name": "Jane",
"lead_phone": "+14155551234",
"host_email": "closer@yourorg.com",
"meeting_url": "https://cal.ai/j/abc",
"notes": "Booked via Cal.ai"
}'Response Example
A new booking returns 201 Created.
{
"status": "success",
"message": "Appointment created successfully",
"data": {
"id": "c76340d1-72a8-403e-b920-d6a2b526926c",
"is_duplicate": false
}
}A repeated external_reference returns 200 OK with the existing appointment.
{
"status": "success",
"message": "Appointment already exists for this reference",
"data": {
"id": "c76340d1-72a8-403e-b920-d6a2b526926c",
"is_duplicate": true
}
}Cancel Appointment
Cancel an appointment that was added through this API. Send the same external_reference used when it was created; Hermon marks the appointment Canceled — updating the lead status, clearing the meeting URL, and firing the cancellation notification and outbound webhook, exactly like canceling in the app.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| external_reference | string | Required | The booking ID you sent when the appointment was created. Identifies which appointment to cancel. |
| notes | string | Optional | Free-text note explaining the cancellation (e.g. "Canceled by attendee"). |
Code Examples
curl -X POST "https://api.hermon.io/api/external/appointments/cancel" \
-H "Content-Type: application/json" \
-H "x-api-key: sk_live_your_key_here" \
-d '{
"external_reference": "cal-ai-booking-123",
"notes": "Canceled by attendee"
}'Response Example
{
"status": "success",
"message": "Appointment cancelled successfully",
"data": {
"id": "c76340d1-72a8-403e-b920-d6a2b526926c"
}
}List Appointments
Retrieve a paginated list of appointments. Results can be filtered by call category, outcome status role, lead, assigned setter, triager, or closer (host).
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| page | integer | Optional | Page number for pagination. Default: 1 |
| limit | integer | Optional | Number of items per page. Default: 10, Max: 100 |
| lead_id | string (UUID) | Optional | UUID of the lead to filter appointments by. Must be a valid UUID that exists in your org. |
| call_category | string | Optional | Comma-separated list of call categories (e.g. SALES_CALL, COACHING_CALL, TRIAGE_CALL). |
| outcome_role | string | Optional | Comma-separated list of outcome status roles (e.g. NEW_LEAD, APPOINTMENT_BOOKED, NO_SHOW, RESCHEDULED, CANCELED, PARTIAL_PAYMENT, WON, UNQUALIFIED, FOLLOW_UP, LOST). |
| setter | string | Optional | Email address of the setter to filter by. |
| triager | string | Optional | Email address of the triager to filter by. |
| closer | string | Optional | Email address of the closer (host) to filter by. |
| scheduled_from | string | Optional | Lower bound for schedule_time. Accepts YYYY-MM-DD or ISO 8601. |
| scheduled_to | string | Optional | Upper bound for schedule_time. Accepts YYYY-MM-DD or ISO 8601. |
| created_from | string | Optional | Lower bound for created_at. Accepts YYYY-MM-DD or ISO 8601. |
| created_to | string | Optional | Upper bound for created_at. Accepts YYYY-MM-DD or ISO 8601. |
| updated_from | string | Optional | Lower bound for updated_at. Accepts YYYY-MM-DD or ISO 8601. |
| updated_to | string | Optional | Upper bound for updated_at. Accepts YYYY-MM-DD or ISO 8601. |
Code Examples
curl -X GET "https://api.hermon.io/api/external/appointments?page=1&limit=10&call_category=COACHING_CALL&outcome_role=APPOINTMENT_BOOKED&setter=sales-setter@mailinator.com&closer=hermon@mailinator.com&triager=triager@mailinator.com&lead_id=e799c30f-9da7-4fd7-9552-83b96a9bfac2" \
-H "Content-Type: application/json" \
-H "x-api-key: sk_live_your_key_here"Response Example
{
"success": true,
"message": "Appointments fetched successfully",
"data": [
{
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"lead": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com",
"phone_e164": "+14155551234",
"phone_country": "US",
"next_touch_point_at": "2026-06-15T14:00:00.000Z",
"next_touch_point_type": "PHONE_CALL"
},
"schedule_time": "2026-02-10T15:00:00.000Z",
"host": {
"first_name": "Jane",
"last_name": "Smith",
"email": "jane@example.com",
"profile_image_url": "https://img.clerk.com/eyJ0eXBlIjoicHJveHkiLCJzcmMiOiJodHRwczovL2ltYWdlcy5jbGVyay5kZXYvb2F1dGhfZ29vZ2xlL2ltZ18zOWJ3NkxJaTFFSTdlM3Z4RHFhTFViUTZVeFMifQ",
"id": "user_456def",
"role": "org:admin"
},
"setter": {
"first_name": "Alice",
"last_name": "Jones",
"email": "alice@example.com",
"profile_image_url": null,
"id": "user_123abc",
"role": "org:member"
},
"triager": null,
"meeting_url": "https://calendly.com/jane-smith/discovery",
"appointment_type": "Discovery Call",
"call_category": "SALES_CALL",
"appointment_event_type": {
"id": "evt_abc123",
"provider": "CALENDLY",
"owner_name": "Jane Smith"
},
"outcome": {
"id": "status_won123",
"name": "Closed Won",
"role": "WON",
"description": "Deal successfully closed",
"text_color": "#14532D",
"bg_color": "#DCFCE7",
"created_at": "2025-12-01T09:00:00.000Z"
},
"notes": {
"note": "Strong buying intent, ready to start immediately",
"mention_users": []
},
"recording_url": "https://example.com/recordings/call-abc123",
"no_show": false,
"source": "CALENDLY",
"external_reference": "CALY-abc123",
"utm_source": "facebook",
"utm_medium": "paid_social",
"utm_campaign": "q1-2026-coaching",
"utm_content": "video-ad-v2",
"utm_term": null,
"fathom": {
"id": "fathom_xyz789",
"fathom_call_id": "fathom-call-abc123",
"ai_generated_title": "Discovery Call — Strong Interest in Premium Package",
"ai_rationale": "Lead showed high engagement and asked specific questions about onboarding",
"ai_suggested_outcome": "WON",
"ai_confidence_score": 0.87,
"appointment_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"created_at": "2026-02-10T16:30:00.000Z"
},
"created_at": "2026-02-08T10:00:00.000Z",
"updated_at": "2026-02-10T16:35:00.000Z",
"custom_fields": []
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 1,
"totalPages": 1,
"hasNext": false,
"hasPrev": false
}
}Get Appointment Details
Fetch detailed information for a single appointment by its unique UUID.
Path Parameters
Appointment Object Fields
| Field | Type | Description |
|---|---|---|
| id | string (UUID) | Unique identifier for the appointment. |
| lead | object | Basic lead info (id, first_name, last_name, email, phone_e164, phone_country, next_touch_point_at, next_touch_point_type). |
| schedule_time | string (ISO 8601) | UTC timestamp of the scheduled appointment. |
| host | object | null | The closer/host conducting the call (first_name, last_name, email, profile_image_url, id, role). |
| setter | object | null | Setter who booked the appointment (first_name, last_name, email, profile_image_url, id, role). |
| triager | object | null | Triager assigned to the appointment (first_name, last_name, email, profile_image_url, id, role). |
| meeting_url | string | null | Video/phone meeting URL. |
| appointment_type | string | null | Name of the event type (e.g. "Discovery Call"). |
| call_category | string (enum) | Category of the call (SALES_CALL, COACHING_CALL, TRIAGE_CALL). |
| appointment_event_type | object | Event type metadata (id, provider, owner_name). |
| outcome | object | null | Outcome status (id, name, role, description, text_color, bg_color, created_at). |
| notes | object | null | Latest note on the appointment (note, mention_users) [List API Only]. |
| recording_url | string | null | Call recording URL. |
| no_show | boolean | Whether the lead was a no-show. |
| source | string (enum) | Booking source (CALENDLY, ICLOSED, GOHIGHLEVEL, MANUAL). |
| external_reference | string | null | Reference ID from the booking provider. |
| utm_source | string | null | UTM source parameter [List API Only]. |
| utm_medium | string | null | UTM medium parameter [List API Only]. |
| utm_campaign | string | null | UTM campaign parameter [List API Only]. |
| utm_content | string | null | UTM content parameter [List API Only]. |
| utm_term | string | null | UTM term parameter [List API Only]. |
| fathom | object | null | Fathom AI call analysis (id, fathom_call_id, ai_generated_title, ai_rationale, ai_suggested_outcome, ai_confidence_score, appointment_id, created_at). |
| created_at | string (ISO 8601) | UTC timestamp when created. |
| updated_at | string (ISO 8601) | UTC timestamp when last updated. |
| custom_fields | array | Custom field values. |
| first_source | object | Lead's first attribution source [Details API Only]. |
| last_source | object | Lead's last attribution source [Details API Only]. |
| opt_ins | array | Up to 3 most recent opt-in submissions from the lead [Details API Only]. |
Code Examples
curl -X GET "https://api.hermon.io/api/external/appointments/c76340d1-72a8-403e-b920-d6a2b526926c" \
-H "Content-Type: application/json" \
-H "x-api-key: sk_live_your_key_here"Response Example
{
"success": true,
"message": "Appointment fetched successfully",
"data": {
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"lead": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com",
"phone_e164": "+14155551234",
"phone_country": "US",
"next_touch_point_at": "2026-06-15T14:00:00.000Z",
"next_touch_point_type": "PHONE_CALL"
},
"schedule_time": "2026-02-10T15:00:00.000Z",
"host": {
"first_name": "Jane",
"last_name": "Smith",
"email": "jane@example.com",
"profile_image_url": "https://img.clerk.com/eyJ0eXBlIjoicHJveHkiLCJzcmMiOiJodHRwczovL2ltYWdlcy5jbGVyay5kZXYvb2F1dGhfZ29vZ2xlL2ltZ18zOWJ3NkxJaTFFSTdlM3Z4RHFhTFViUTZVeFMifQ",
"id": "user_456def",
"role": "org:admin"
},
"setter": null,
"triager": null,
"meeting_url": "https://calendly.com/jane-smith/discovery",
"appointment_type": "Discovery Call",
"call_category": "SALES_CALL",
"appointment_event_type": {
"id": "evt_abc123",
"provider": "CALENDLY",
"owner_name": "Jane Smith"
},
"outcome": {
"id": "status_won123",
"name": "Closed Won",
"role": "WON",
"description": "Deal successfully closed",
"text_color": "#14532D",
"bg_color": "#DCFCE7",
"created_at": "2025-12-01T09:00:00.000Z"
},
"recording_url": "https://example.com/recordings/call-abc123",
"no_show": false,
"source": "CALENDLY",
"external_reference": "CALY-abc123",
"fathom": null,
"first_source": {
"id": "src_abc123",
"name": "Facebook Ad Campaign"
},
"last_source": {
"id": "src_def456",
"name": "Referral"
},
"custom_fields": [],
"opt_ins": [
{
"id": "optin_xyz789",
"lead_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"source": "TYPEFORM",
"provider_form_id": "form_abc123",
"provider_form_name": "Coaching Application",
"external_reference": "TYPEFORM-abc123",
"created_at": "2026-01-15T09:00:00.000Z"
}
],
"created_at": "2026-02-08T10:00:00.000Z",
"updated_at": "2026-02-10T16:35:00.000Z"
}
}Values Reference
Call Category Values
| Value | Description |
|---|---|
| SALES_CALL | Sales discovery or closing call |
| COACHING_CALL | Coaching session |
| TRIAGE_CALL | Initial qualification/triage call |
Status Role Values
| Value | Description |
|---|---|
| NEW_LEAD | New/unqualified lead |
| APPOINTMENT_BOOKED | Appointment scheduled |
| NO_SHOW | Lead did not attend |
| RESCHEDULED | Appointment rescheduled |
| CANCELED | Appointment canceled |
| PARTIAL_PAYMENT | Partial payment received |
| WON | Deal won/closed |
| UNQUALIFIED | Lead disqualified |
| FOLLOW_UP | Requires follow-up |
| LOST | Deal lost |
Appointment Source Values
| Value | Description |
|---|---|
| CALENDLY | Booked via Calendly |
| ICLOSED | Booked via iClosed |
| GOHIGHLEVEL | Booked via GoHighLevel |
| MANUAL | Manually created |
Nested Objects Reference
Appointment Lead Object
| Field | Type | Description |
|---|---|---|
| id | string (UUID) | Lead ID |
| first_name | string | First name |
| last_name | string | Last name |
| string | Email address | |
| phone_e164 | string | Phone in E.164 format |
| phone_country | string | ISO 3166-1 alpha-2 country code |
| next_touch_point_at | string (ISO 8601) | Next touchpoint timestamp |
| next_touch_point_type | string (enum) | Type of next touchpoint |
User Object
| Field | Type | Description |
|---|---|---|
| first_name | string | First name |
| last_name | string | Last name |
| string | Email address | |
| profile_image_url | string | Profile image URL (null if none) |
| id | string | Clerk user ID |
| role | string | Organization role |
Event Type Object
| Field | Type | Description |
|---|---|---|
| id | string | Event type ID (null when no event type is set) |
| provider | string | Booking provider (e.g. CALENDLY, ICLOSED, GOHIGHLEVEL) |
| owner_name | string | Owner name in the booking provider |
Outcome Object
| Field | Type | Description |
|---|---|---|
| id | string | Status ID |
| name | string | Status display name |
| role | string (enum) | Status role |
| description | string | Status description |
| text_color | string | Hex color code for text |
| bg_color | string | Hex color code for background |
| created_at | string (ISO 8601) | When this status was created |
Note Object
| Field | Type | Description |
|---|---|---|
| note | string | Note text |
| mention_users | array | Users @mentioned in the note (Clerk user objects) |
Fathom Object
| Field | Type | Description |
|---|---|---|
| id | string | Record ID |
| fathom_call_id | string | Fathom platform call ID |
| ai_generated_title | string | AI-generated call title |
| ai_rationale | string | AI reasoning for the suggested outcome |
| ai_suggested_outcome | string | Suggested outcome status name |
| ai_confidence_score | number | Confidence score (0–1) |
| appointment_id | string | Parent appointment ID |
| created_at | string (ISO 8601) | When the record was created |
Error Responses
{
"status": "error",
"message": "external_reference is required"
}{
"status": "error",
"message": "Invalid or revoked API key"
}{
"status": "error",
"message": "Resource not found"
}{
"status": "error",
"message": "No appointment found for external_reference \"cal-ai-booking-123\""
}{
"status": "error",
"message": "external_reference \"cal-ai-booking-123\" already maps to an appointment at a different time. Send a new external_reference for a new booking."
}{
"status": "error",
"message": "Too many requests"
}