Leads API Reference
Fetch leads and query histories for contacts matching Hermon data records.
Rate Limiting: Requests are limited per organization (300 per minute, shared by all of its API keys). If exceeded, a 429 Too Many Requests error is returned with a Retry-After header giving the seconds to wait.
List Leads
Retrieve a paginated list of leads. Results can be filtered by source, status role, and assigned setter, closer, or triager, or searched by email or phone number.
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 |
| search | string | Optional | Find a lead by email (case-insensitive substring) or phone number (notation-insensitive). See Search. |
| source | string | Optional | Filter by lead source. See Lead Source Values. |
| status_role | string | Optional | Comma-separated list of status roles. See Status Role Values. |
| 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 to filter by. |
| 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_from. Accepts YYYY-MM-DD or ISO 8601. |
| updated_at | string | Optional | Upper bound for updated_at. Accepts YYYY-MM-DD or ISO 8601. |
Search
Use searchto locate a specific lead by email or phone number — useful for resolving a lead's id before calling the detail, custom field, or status-update endpoints. It combines with the date-range filters and pagination, and a value that matches nothing returns an empty list.
Phone — a value made up only of digits, +, spaces, dashes, and parentheses is matched against the phone number. Leading zeros are ignored and local and international notations are treated as equivalent. For a lead stored as +31612345678, all of 0612345678, +31612345678, and 0031612345678 match. Name and custom-field matching are not supported.
Code Examples
curl -X GET "https://api.hermon.io/api/external/leads?page=1&limit=10&search=john.doe@example.com&source=LANDING_PAGE&status_role=NEW_LEAD&setter=sales-setter@mailinator.com&closer=hermon@mailinator.com&triager=triager@mailinator.com" \
-H "Content-Type: application/json" \
-H "x-api-key: sk_live_your_key_here"Response Example
{
"success": true,
"message": "Leads fetched successfully",
"data": [
{
"id": "e799c30f-9da7-4fd7-9552-83b96a9bfac2",
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com",
"phone_e164": "+14155551234",
"phone_country": "US",
"source": "LANDING_PAGE",
"sales_status": {
"id": "status_xyz123",
"name": "New Lead",
"role": "NEW_LEAD",
"description": "Newly imported lead",
"text_color": "#2563EB",
"bg_color": "#DBEAFE"
},
"setter": null,
"triager": null,
"closer": null,
"notes": [],
"counts": {
"notes": 0,
"appointments": 1,
"contracts": 0,
"payments": 0,
"opt_ins": 1,
"deliveries": 0
},
"custom_fields": [
{
"id": "field_age",
"name": "Age",
"value": 30
}
],
"first_source": {
"id": "src_fb",
"name": "Facebook Ads"
},
"last_source": {
"id": "src_fb",
"name": "Facebook Ads"
},
"touch_points": [
{
"id": "6f1c2b9e-3d4a-4f8b-9c2e-1a7d5e3b8c40",
"owner": {
"id": "user_2abcSetter",
"first_name": "Jane",
"last_name": "Smith",
"profile_image_url": null,
"role": "org:sales_setter"
},
"owner_id": "user_2abcSetter",
"type": "PHONE_CALL",
"due_at": "2026-02-10T15:00:00.000Z",
"has_time": true,
"note": "Call back after budget approval",
"created_at": "2026-02-08T10:30:00.000Z"
}
],
"created_at": "2026-02-08T10:00:00.000Z",
"updated_at": "2026-02-08T10:30:00.000Z"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 1,
"totalPages": 1,
"hasNext": false,
"hasPrev": false
}
}Get Lead Details
Fetch detailed information for a single lead by its unique UUID.
Path Parameters
Lead Object Fields
| Field | Type | Description |
|---|---|---|
| id | string (UUID) | Unique identifier for the lead. |
| first_name | string | Lead's first name. |
| last_name | string | Lead's last name. |
| string | Lead's email address. | |
| phone_e164 | string | null | Phone number in E.164 format. |
| phone_country | string | null | ISO 3166-1 alpha-2 country code derived from phone. |
| source | string (enum) | Lead source (e.g. CALENDLY, TYPEFORM, WEB_FORM). See Lead Source Values. |
| sales_status | object | Current status details. See Lead Status Object. |
| setter | object | null | Assigned setter. See Lead User Object. |
| triager | object | null | Assigned triager. See Lead User Object. |
| closer | object | null | Assigned closer. See Lead User Object. |
| notes | array | Latest note(s) on the lead. See Lead Note Object. |
| counts | object | Total count of related resources. See Lead Counts Object. |
| custom_fields | array | Assigned custom field values. See Lead Custom Field Object. |
| first_source | object | null | First marketing attribution source. See Lead Source Object. |
| last_source | object | null | Last marketing attribution source. See Lead Source Object. |
| touch_points | array | Open next touchpoints on the lead, earliest due first. Each team member (setter, triager, closer, …) owns at most one. Empty when none are scheduled. See Lead Touch Point Object. |
| billing_details | object | null | Billing information. See Lead Billing Details Object [Details API Only]. |
| created_at | string (ISO 8601) | UTC timestamp of creation. |
| updated_at | string (ISO 8601) | UTC timestamp of last update. |
Code Examples
curl -X GET "https://api.hermon.io/api/external/leads/e799c30f-9da7-4fd7-9552-83b96a9bfac2" \
-H "Content-Type: application/json" \
-H "x-api-key: sk_live_your_key_here"Response Example
{
"success": true,
"message": "Lead fetched successfully",
"data": {
"id": "e799c30f-9da7-4fd7-9552-83b96a9bfac2",
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com",
"phone_e164": "+14155551234",
"phone_country": "US",
"source": "LANDING_PAGE",
"sales_status": {
"id": "status_xyz123",
"name": "New Lead",
"role": "NEW_LEAD",
"description": "Newly imported lead",
"text_color": "#2563EB",
"bg_color": "#DBEAFE"
},
"setter": null,
"triager": null,
"closer": null,
"notes": [],
"counts": {
"notes": 0,
"appointments": 1,
"contracts": 0,
"payments": 0,
"opt_ins": 1,
"deliveries": 0
},
"custom_fields": [],
"first_source": {
"id": "src_fb",
"name": "Facebook Ads"
},
"last_source": {
"id": "src_fb",
"name": "Facebook Ads"
},
"touch_points": [
{
"id": "6f1c2b9e-3d4a-4f8b-9c2e-1a7d5e3b8c40",
"owner": {
"id": "user_2abcSetter",
"first_name": "Jane",
"last_name": "Smith",
"profile_image_url": null,
"role": "org:sales_setter"
},
"owner_id": "user_2abcSetter",
"type": "PHONE_CALL",
"due_at": "2026-02-10T15:00:00.000Z",
"has_time": true,
"note": "Call back after budget approval",
"created_at": "2026-02-08T10:30:00.000Z"
}
],
"billing_details": {
"id": "bill_xyz123",
"business_name": "Doe Coaching LLC",
"address": "123 Main St",
"city": "San Francisco",
"zipcode": "94105",
"province": "CA",
"country": "US",
"vat_number": null,
"vat_exempt": false,
"created_at": "2026-02-08T10:00:00.000Z",
"updated_at": "2026-02-08T10:00:00.000Z"
},
"created_at": "2026-02-08T10:00:00.000Z",
"updated_at": "2026-02-08T10:30:00.000Z"
}
}Update Lead Status
Update the status of a specific lead by providing a valid status UUID.
Path Parameters
Headers
Request Body Fields
| Field | Type | Required | Description |
|---|---|---|---|
| status_id | string (UUID) | Required | The unique UUID of the status to assign to the lead. |
| reason_id | string (UUID) | Optional | Reason to record for this change, by id. Only applies to statuses with role LOST or UNQUALIFIED. Must be an active reason configured on that status. Takes precedence when both reason_id and reason_name are sent. |
| reason_name | string | Optional | Reason to record for this change, matched case-insensitively against the status’s active reasons. Alternative to reason_id. Returns a validation error when no active reason with that name exists on the status. |
Code Examples
curl -X PATCH "https://api.hermon.io/api/external/leads/24567881-3574-4aa9-82b2-d7837efa10e5/status"
-H "Content-Type: application/json"
-H "x-api-key: sk_live_your_key_here"
-d '{
"status_id": "4bb2ae65-8ab1-4695-b896-190711a07cd0"
}'Response Example
{
"success": true,
"message": "Lead status updated successfully",
"data": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": {
"id": "status_xyz789",
"name": "Follow-up Required",
"role": "FOLLOW_UP"
}
}
}Update Lead Assignments
Update a lead's ownership — its setter, closer, and/or triager — by passing any combination of the three roles. Only fields present in the request body are changed; omitted fields are left untouched, and passing nullclears (unassigns) that role. Each provided user is validated to be an active member of the same workspace. The change is attributed on the lead's activity timeline as an External update, and the same assignment notifications fire as from the dashboard.
Path Parameters
Headers
Request Body Fields
At least one of setter_id, closer_id, or triager_id must be present.
| Field | Type | Required | Description |
|---|---|---|---|
| setter_id | string (Clerk user ID) | null | Optional | The user to assign as setter. Pass a Clerk user ID (e.g. "user_2abc...") to assign, or null to unassign. Omit the field to leave the current setter unchanged. |
| closer_id | string (Clerk user ID) | null | Optional | The user to assign as closer. Pass a Clerk user ID to assign, or null to unassign. Omit the field to leave the current closer unchanged. |
| triager_id | string (Clerk user ID) | null | Optional | The user to assign as triager. Pass a Clerk user ID to assign, or null to unassign. Omit the field to leave the current triager unchanged. |
Code Examples
curl -X PATCH "https://api.hermon.io/api/external/leads/24567881-3574-4aa9-82b2-d7837efa10e5/assignments" \
-H "Content-Type: application/json" \
-H "x-api-key: sk_live_your_key_here" \
-d '{
"setter_id": "user_2abc123def456",
"closer_id": "user_2ghi789jkl012",
"triager_id": null
}'Response Example
{
"status": "success",
"message": "Lead assignments updated successfully",
"data": {
"id": "24567881-3574-4aa9-82b2-d7837efa10e5"
}
}Add Lead Note
Attach a plain-text note to a specific lead. The note is stored on the lead's activity timeline with its source recorded as External (no individual user is attributed as the author).
Path Parameters
Headers
Request Body Fields
| Field | Type | Required | Description |
|---|---|---|---|
| note | string | Required | The note content to attach to the lead. Must be non-empty and at most 10,000 characters. |
Code Examples
curl -X POST "https://api.hermon.io/api/external/leads/24567881-3574-4aa9-82b2-d7837efa10e5/notes"
-H "Content-Type: application/json"
-H "x-api-key: sk_live_your_key_here"
-d '{
"note": "Followed up by phone — lead requested a call back next week."
}'Response Example
{
"status": "success",
"message": "Note added successfully",
"data": {
"id": "f7c1a2b3-4d5e-6789-abcd-ef0123456789"
}
}Values Reference
Lead Source Values
| Value | Description |
|---|---|
| CALENDLY | Calendly integration |
| ICLOSED | iClosed integration |
| GOHIGHLEVEL | GoHighLevel integration |
| MANUAL | Manually created |
| TYPEFORM | Typeform integration |
| WEBINAR | Webinar signup |
| NEWSLETTER | Newsletter subscription |
| LANDING_PAGE | Landing page submission |
| OTHER | Other source |
Status Role Values
| Value | Description |
|---|---|
| NEW_LEAD | New/unqualified lead |
| APPOINTMENT_BOOKED | Appointment scheduled |
| NO_SHOW | Lead did not attend appointment |
| 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 |
Touch Point Type Values
| Value | Description |
|---|---|
| PHONE_CALL | Phone call |
| WhatsApp message | |
| FOLLOW_UP_CALL | Follow-up phone call |
| PROPOSAL_REVIEW | Proposal review meeting |
| OTHER | Other touchpoint type |
Nested Objects Reference
User Object Fields
| 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 |
Source Object Fields
| Field | Type | Description |
|---|---|---|
| id | string | Marketing source ID |
| name | string | Marketing source name |
Status Object Fields
| Field | Type | Description |
|---|---|---|
| id | string | Status ID |
| name | string | Status display name |
| role | string | Status role (enum value) |
| description | string | Status description |
| text_color | string | Hex color code for text |
| bg_color | string | Hex color code for background |
Touch Point Object Fields
| Field | Type | Description |
|---|---|---|
| id | string (UUID) | Touchpoint ID |
| owner | object | null | Team member who owns the touchpoint. See User Object. Null if the user can no longer be resolved. |
| owner_id | string | Clerk user ID of the owner |
| type | string (enum) | Touchpoint type. See Touch Point Type Values. |
| due_at | string (ISO 8601) | UTC timestamp the touchpoint is due. |
| has_time | boolean | Whether an explicit time was chosen. When false, only the date of due_at is meaningful. |
| note | string | null | Short touchpoint note |
| created_at | string (ISO 8601) | UTC timestamp of creation. |
Billing Details Object Fields
| Field | Type | Description |
|---|---|---|
| id | string | Billing details ID |
| business_name | string | Company/business name |
| address | string | Street address |
| city | string | City |
| zipcode | string | Postal/ZIP code |
| province | string | State/province |
| country | string | ISO 3166-1 alpha-2 country code |
| vat_number | string | VAT/tax ID number |
| vat_exempt | boolean | Whether the lead is marked VAT-exempt |
| created_at | string (ISO 8601) | When billing details were added |
| updated_at | string (ISO 8601) | When billing details were last updated |
Note Object Fields
| Field | Type | Description |
|---|---|---|
| note | string | Note content |
| mention_users | array | Users @mentioned in the note (always empty on list) |
Counts Object Fields
| Field | Type | Description |
|---|---|---|
| notes | integer | Number of notes |
| appointments | integer | Number of appointments |
| contracts | integer | Number of contracts |
| payments | integer | Number of payments |
| opt_ins | integer | Number of opt-in submissions |
| deliveries | integer | Number of delivery engagements |
Custom Field Object Fields
| Field | Type | Description |
|---|---|---|
| id | string | Custom field definition ID |
| name | string | Custom field name |
| value | any | Field value (type depends on field definition) |
Error Responses
{
"status": "error",
"message": "note is required"
}{
"status": "error",
"message": "Invalid or revoked API key"
}{
"status": "error",
"message": "Resource not found"
}{
"status": "error",
"message": "Rate limit exceeded for this organization. Retry after the number of seconds in the Retry-After header."
}