Introduction
The Merchant Lead Hub Enterprise API is a RESTful API for integrating with the Merchant Lead Hub Enterprise tool.
Authentication
To authorize, use this code:
curl "api_endpoint_here" \
-H "Authorization: Bearer 01234567890abcdef"
Make sure to replace
01234567890abcdefwith your API key.
Merchant Lead Hub Enterprise uses API keys to allow access to the API. You can register a API key in the System web page.
Merchant Lead Hub Enterprise expects the API key to be included in all API requests to the server in a header that looks like the following:
Authorization: Bearer 01234567890abcdef
Leads
Lead Definition
| Attribute | Type | Description |
|---|---|---|
| address1 | string | Physical street address |
| address2 | string | Physical street address line 2 |
| appointment_date | string | Appointment date |
| appointment_time_of_day | string | Appointment time of day in local time |
| call_recording_url | string | URL of call recording |
| caller_notes | string | Notes from the caller |
| city | string | Physical city |
| company_name | string | Name of company |
| contact_name | string | Name of contact |
| created_at | string | When record was created |
| string | ||
| id | uuid | Unique identifier |
| notes | string | Notes from the client or agent |
| phone_number | string | Phone number |
| received_at | string | When lead was received |
| sales_agent.custom_data | string | Sales agent custom data |
| sales_agent.id | uuid | Sales agent ID |
| sales_agent.name | string | Sales agent name |
| sent_agent_email_at | string | When the agent was emailed |
| state | string | Physical state |
| status.id | string | Status ID |
| status.name | string | Human readable status |
| updated_at | string | When record was last updated |
| zip_code | string | Physical zip code |
Get All Leads
curl "https://enterprise.merchantleadhub.com/client/api/leads" \
-H "Authorization: 01234567890abcdef"
The above command returns JSON structured like this:
{
"items": [
{
"id": "01924e84-2be7-7565-8044-f5e5cd76bad6",
"contact_name": "Bill Jones",
"company_name": "Acme Corp",
"address1": "123 Main St.",
"address2": null,
"city": "Sometown",
"state": "CA",
"zip_code": "12345",
"phone_number": "(555) 555-5555",
"email": null,
"appointment_date": "2024-09-23",
"received_at": "2024-09-19T11:29:43.896-04:00",
"caller_notes": "This merchant is interested in interchange optimization",
"notes": null,
"created_at": "2024-09-19T11:29:43.978-04:00",
"updated_at": "2024-10-01T13:56:45.466-04:00",
"call_recording_url": "https://example.com/123456.mp3",
"sent_agent_email_at": null,
"appointment_time_of_day": "15:00:00",
"sales_agent": {
"id": "01924e84-306e-75f2-98d1-d4470fa3446a",
"name": "John Doe",
"custom_data": null
},
"status": {
"id": "active",
"name": "active"
}
}
]
}
This endpoint retrieves all leads sorted by id ascending. This endpoint is paginated. To fetch all records it is necessary to make multiple requests where the query parameter start_after_id is the ID of the last record retrieved on the previous request. This must be done until a response is received where the data array is empty.
HTTP Request
GET https://enterprise.merchantleadhub.com/client/api/leads
Query Parameters
| Parameter | Default | Description |
|---|---|---|
| limit | 10 | Limit the number of leads returned (valid values are integers 1 to 100). |
| start_after_id | None | Only include leads with IDs greater than this. |
Get a Specific Lead
curl "https://enterprise.merchantleadhub.com/client/api/lead/01924e84-2be7-7565-8044-f5e5cd76bad6" \
-H 'Authorization: 01234567890abcdef'
The above command returns JSON structured like this:
{
"id": "01924e84-2be7-7565-8044-f5e5cd76bad6",
"contact_name": "Bill Jones",
"company_name": "Acme Corp",
"address1": "123 Main St.",
"address2": null,
"city": "Sometown",
"state": "CA",
"zip_code": "12345",
"phone_number": "(555) 555-5555",
"email": null,
"appointment_date": "2024-09-23",
"received_at": "2024-09-19T11:29:43.896-04:00",
"caller_notes": "This merchant is interested in interchange optimization",
"notes": null,
"created_at": "2024-09-19T11:29:43.978-04:00",
"updated_at": "2024-10-01T13:56:45.466-04:00",
"call_recording_url": "https://example.com/123456.mp3",
"sent_agent_email_at": null,
"appointment_time_of_day": "15:00:00",
"sales_agent": {
"id": "01924e84-306e-75f2-98d1-d4470fa3446a",
"name": "John Doe",
"custom_data": null
},
"status": {
"id": "active",
"name": "active"
}
}
This endpoint retrieves a specific lead.
HTTP Request
GET https://enterprise.merchantleadhub.com/client/api/sales_agents/{id}
URL Parameters
| Parameter | Description |
|---|---|
| id | The ID of the lead to retrieve |
Update a Specific Lead
curl https://enterprise.merchantleadhub.com/client/api/leads/01924e6b-b2d2-7d3d-9dff-da4588fbb935 \
-H 'Authorization: 01234567890abcdef' \
-H "Content-Type: application/json" \
-X PATCH \
-d "{\"notes\":\"call back tomorrow\"}" \
The above command returns JSON structured like this:
{
"id": "01924e84-2be7-7565-8044-f5e5cd76bad6",
"contact_name": "Bill Jones",
"company_name": "Acme Corp",
"address1": "123 Main St.",
"address2": null,
"city": "Sometown",
"state": "CA",
"zip_code": "12345",
"phone_number": "(555) 555-5555",
"email": null,
"appointment_date": "2024-09-23",
"received_at": "2024-09-19T11:29:43.896-04:00",
"caller_notes": "This merchant is interested in interchange optimization",
"notes": "call back tomorrow",
"created_at": "2024-09-19T11:29:43.978-04:00",
"updated_at": "2024-10-01T13:56:45.466-04:00",
"call_recording_url": "https://example.com/123456.mp3",
"sent_agent_email_at": null,
"appointment_time_of_day": "15:00:00",
"sales_agent": {
"id": "01924e84-306e-75f2-98d1-d4470fa3446a",
"name": "John Doe",
"custom_data": null
},
"status": {
"id": "active",
"name": "active"
}
}
This endpoint updates a lead.
HTTP Request
PATCH https://enterprise.merchantleadhub.com/client/api/sales_agents/{id}
URL Parameters
| Parameter | Description |
|---|---|
| id | The ID of the lead to update |
Allowed Attributes
| Attribute | Type | Description |
|---|---|---|
| notes | string | Notes from the client or agent |
| status_id | string | Status ID (allowed values: active, call_back, closed_yes, not_interested, not_available, bad_record, no_conversation, low_volume, failed_client_qa) |
Sales Agents
Sales Agent Definition
| Attribute | Type | Description |
|---|---|---|
| call_center_instructions | string | Extra instructions for call center |
| created_at | string | When record was created |
| custom_data | string | Custom data such as an internal ID |
| id | uuid | Unique identifier |
| name | string | Name |
| notification_email | string | Email address to send lead notifications to |
| status.id | string | Status ID |
| status.name | string | Human readable status |
| status_inconsistencies | array | Inconsistencies with current status such as active sales agent having no zip codes |
| updated_at | string | When record was last updated |
| zip_codes | array | Zip code strings |
Get All Sales Agents
curl "https://enterprise.merchantleadhub.com/client/api/sales_agents" \
-H "Authorization: 01234567890abcdef"
The above command returns JSON structured like this:
{
"items": [
{
"id": "01924e6b-b2d2-7d3d-9dff-da4588fbb935",
"name": "John Doe",
"notification_email": "johndoe@example.com",
"custom_data": null,
"call_center_instructions": null,
"created_at": "2024-09-18T13:51:48.860-04:00",
"updated_at": "2024-10-02T13:00:07.302-04:00",
"zip_codes": [
"12345"
],
"status": {
"id": "active",
"name": "Active"
},
"status_inconsistencies": []
},
]
}
This endpoint retrieves all sales agents sorted by id ascending. This endpoint is paginated. To fetch all records it is necessary to make multiple requests where the query parameter start_after_id is the ID of the last record retrieved on the previous request. This must be done until a response is received where the data array is empty.
HTTP Request
GET https://enterprise.merchantleadhub.com/client/api/sales_agents
Query Parameters
| Parameter | Default | Description |
|---|---|---|
| limit | 10 | Limit the number of sales agents returned (valid values are integers 1 to 100). |
| start_after_id | None | Only include sales agents with IDs greater than this. |
Get a Specific Sales Agent
curl "https://enterprise.merchantleadhub.com/client/api/sales_agents/01924e6b-b2d2-7d3d-9dff-da4588fbb935" \
-H 'Authorization: 01234567890abcdef'
The above command returns JSON structured like this:
{
"id": "01924e6b-b2d2-7d3d-9dff-da4588fbb935",
"name": "John Doe",
"notification_email": "johndoe@example.com",
"custom_data": null,
"call_center_instructions": null,
"created_at": "2024-09-18T13:51:48.860-04:00",
"updated_at": "2024-10-02T13:00:07.302-04:00",
"zip_codes": [
"12345"
],
"status": {
"id": "active",
"name": "Active"
},
"status_inconsistencies": []
}
This endpoint retrieves a specific sales agent.
HTTP Request
GET https://enterprise.merchantleadhub.com/client/api/sales_agents/{id}
URL Parameters
| Parameter | Description |
|---|---|
| id | The ID of the sales agent to retrieve |
Create a Sales Agent
curl https://enterprise.merchantleadhub.com/client/api/sales_agents \
-H 'Authorization: 01234567890abcdef' \
-H "Content-Type: application/json" \
-X POST \
-d "{\"name\":\"John Doe\",\"zip_codes\":[\"12345\"]}" \
The above command returns JSON structured like this:
{
"id": "01924e6b-b2d2-7d3d-9dff-da4588fbb935",
"name": "John Doe",
"notification_email": "johndoe@example.com",
"custom_data": null,
"call_center_instructions": null,
"created_at": "2024-09-18T13:51:48.860-04:00",
"updated_at": "2024-10-02T13:00:07.302-04:00",
"zip_codes": [
"12345"
],
"status": {
"id": "pending",
"name": "Pending"
},
"status_inconsistencies": []
}
This endpoint creates a sales agent. It will start in the pending state.
HTTP Request
POST https://enterprise.merchantleadhub.com/client/api/sales_agents
Required Attributes
| Attribute | Type | Description |
|---|---|---|
| name | string | Name |
Allowed Attributes
| Attribute | Type | Description |
|---|---|---|
| call_center_instructions | string | Extra instructions for call center |
| custom_data | string | Custom data such as an internal ID |
| notification_email | string | Email address to send lead notifications to |
| zip_codes | array | Zip code strings |
Update a Specific Sales agent
curl https://enterprise.merchantleadhub.com/client/api/sales_agents/01924e6b-b2d2-7d3d-9dff-da4588fbb935 \
-H 'Authorization: 01234567890abcdef' \
-H "Content-Type: application/json" \
-X PATCH \
-d "{\"name\":\"John Doe\",\"zip_codes\":[\"12345\"]}" \
The above command returns JSON structured like this:
{
"id": "01924e6b-b2d2-7d3d-9dff-da4588fbb935",
"name": "John Doe",
"notification_email": "johndoe@example.com",
"custom_data": null,
"call_center_instructions": null,
"created_at": "2024-09-18T13:51:48.860-04:00",
"updated_at": "2024-10-02T13:00:07.302-04:00",
"zip_codes": [
"12345"
],
"status": {
"id": "pending",
"name": "Pending"
},
"status_inconsistencies": []
}
This endpoint updates a sales agent.
HTTP Request
PATCH https://enterprise.merchantleadhub.com/client/api/sales_agents/{id}
URL Parameters
| Parameter | Description |
|---|---|
| id | The ID of the sales agent to update |
Allowed Attributes
| Attribute | Type | Description |
|---|---|---|
| call_center_instructions | string | Extra instructions for call center |
| custom_data | string | Custom data such as an internal ID |
| name | string | Name |
| notification_email | string | Email address to send lead notifications to |
| zip_codes | array | Zip code strings |
Activate a Specific Sales Agent
curl https://enterprise.merchantleadhub.com/client/api/sales_agents/01924e6b-b2d2-7d3d-9dff-da4588fbb935/activate \
-H 'Authorization: 01234567890abcdef' \
-X POST
The above command returns JSON structured like this:
{
"id": "01924e6b-b2d2-7d3d-9dff-da4588fbb935",
"name": "John Doe",
"notification_email": "johndoe@example.com",
"custom_data": null,
"call_center_instructions": null,
"created_at": "2024-09-18T13:51:48.860-04:00",
"updated_at": "2024-10-02T13:00:07.302-04:00",
"zip_codes": [
"12345"
],
"status": {
"id": "active",
"name": "Active"
},
"status_inconsistencies": []
}
This endpoint activates a specific sales agent. The agent must be in the pending state to be activated.
HTTP Request
POST https://enterprise.merchantleadhub.com/client/api/sales_agents/{id}/activate
URL Parameters
| Parameter | Description |
|---|---|
| id | The ID of the user to activate |
Pause a Specific Sales Agent
curl https://enterprise.merchantleadhub.com/client/api/sales_agents/01924e6b-b2d2-7d3d-9dff-da4588fbb935/pause \
-H 'Authorization: 01234567890abcdef' \
-X POST
The above command returns JSON structured like this:
{
"id": "01924e6b-b2d2-7d3d-9dff-da4588fbb935",
"name": "John Doe",
"notification_email": "johndoe@example.com",
"custom_data": null,
"call_center_instructions": null,
"created_at": "2024-09-18T13:51:48.860-04:00",
"updated_at": "2024-10-02T13:00:07.302-04:00",
"zip_codes": [
"12345"
],
"status": {
"id": "paused",
"name": "Paused"
},
"status_inconsistencies": []
}
This endpoint pauses a specific sales agent. The agent must be in the active state to be paused.
HTTP Request
POST https://enterprise.merchantleadhub.com/client/api/sales_agents/{id}/pause
URL Parameters
| Parameter | Description |
|---|---|
| id | The ID of the user to pause |
Unpause a Specific Sales Agent
curl https://enterprise.merchantleadhub.com/client/api/sales_agents/01924e6b-b2d2-7d3d-9dff-da4588fbb935/unpause \
-H 'Authorization: 01234567890abcdef' \
-X POST
The above command returns JSON structured like this:
{
"id": "01924e6b-b2d2-7d3d-9dff-da4588fbb935",
"name": "John Doe",
"notification_email": "johndoe@example.com",
"custom_data": null,
"call_center_instructions": null,
"created_at": "2024-09-18T13:51:48.860-04:00",
"updated_at": "2024-10-02T13:00:07.302-04:00",
"zip_codes": [
"12345"
],
"status": {
"id": "active",
"name": "Active"
},
"status_inconsistencies": []
}
This endpoint unpauses a specific sales agent. The agent must be in the paused state to be unpaused.
HTTP Request
POST https://enterprise.merchantleadhub.com/client/api/sales_agents/{id}/unpause
URL Parameters
| Parameter | Description |
|---|---|
| id | The ID of the user to unpause |
Cancel a Specific Sales Agent
curl https://enterprise.merchantleadhub.com/client/api/sales_agents/01924e6b-b2d2-7d3d-9dff-da4588fbb935/cancel \
-H 'Authorization: 01234567890abcdef' \
-X POST
The above command returns JSON structured like this:
{
"id": "01924e6b-b2d2-7d3d-9dff-da4588fbb935",
"name": "John Doe",
"notification_email": "johndoe@example.com",
"custom_data": null,
"call_center_instructions": null,
"created_at": "2024-09-18T13:51:48.860-04:00",
"updated_at": "2024-10-02T13:00:07.302-04:00",
"zip_codes": [
"12345"
],
"status": {
"id": "canceled",
"name": "Canceled"
},
"status_inconsistencies": []
}
This endpoint cancels a specific sales agent. The agent must be in the active or paused state to be canceled.
HTTP Request
POST https://enterprise.merchantleadhub.com/client/api/sales_agents/{id}/cancel
URL Parameters
| Parameter | Description |
|---|---|
| id | The ID of the user to cancel |
Uncancel a Specific Sales Agent
curl https://enterprise.merchantleadhub.com/client/api/sales_agents/01924e6b-b2d2-7d3d-9dff-da4588fbb935/uncancel \
-H 'Authorization: 01234567890abcdef' \
-X POST
The above command returns JSON structured like this:
{
"id": "01924e6b-b2d2-7d3d-9dff-da4588fbb935",
"name": "John Doe",
"notification_email": "johndoe@example.com",
"custom_data": null,
"call_center_instructions": null,
"created_at": "2024-09-18T13:51:48.860-04:00",
"updated_at": "2024-10-02T13:00:07.302-04:00",
"zip_codes": [
"12345"
],
"status": {
"id": "active",
"name": "Active"
},
"status_inconsistencies": []
}
This endpoint uncancels a specific sales agent. The agent must be in the canceled state to be uncanceled.
HTTP Request
POST https://enterprise.merchantleadhub.com/client/api/sales_agents/{id}/uncancel
URL Parameters
| Parameter | Description |
|---|---|
| id | The ID of the user to uncancel |
Webhooks
Webhooks are a way of being notified when an event occurs. The can be created through from the System web page.
Request Signatures
Webhook requests include a Webhook-Signature header that is the signature of the request. The signature consists of multiple key=value pairs separated by commas. The value of the pair with the key t is the time the request was sent in Unix time. The value of the pair with the key v1 is an HMAC of t and the request body keyed by the webhook HMAC secret.
To validate a signature concatenate t with the request body. Compute an HMAC of this with key HMAC secret and the SHA-256 algorithm. For example this could be done with the following code in Ruby.
require 'openssl' # => true
# webhook_signature is the value of the "Webhook-Signature" header.
webhook_signature = "t=1727812624,v1=f81bf14b6d796c8b9b627f5ba95ba92b9366ff07c285af910558989f998905e9"
# body is complete request body.
body = '{"id":"019249a8-5eef-7c80-904b-ece225dea6e1","type":"lead.passed_internal_qa","data":{"lead":{"id":"019249a8-1632-78d5-8433-f289e033e907","city":"Sometown","email":"test@example.com","notes":null,"state":"IN","status":{"id":"active","name":"active"},"address1":"123 Main St.","address2":null,"zip_code":"12345","received_at":"2024-10-01T14:56:45.488-05:00","sales_agent":{"id":"0192068a-8539-7bcb-b634-0c327eb37643","name":"Abdiel Escalett","custom_data":null},"caller_notes":"Test","company_name":"Acme Corp","contact_name":"John Doe","phone_number":"555-555-5555","appointment_date":"2024-10-02","call_recording_url":"https://example.com/recording.mp3","appointment_time_of_day":{"hour":9,"minute":0,"second":0,"second_of_day":32400}}},"created_at":"2024-10-01 14:57:04 -0500"}'
# hmac_secret is a unique attribute for each webhook.
hmac_secret = "04d09115c90f77f51b797f6e13ae5e40a594d65ba075e1fbb36c37d1886c5571"
# Parse the signature.
sig_parts = webhook_signature.split(",").map { |pair| pair.split("=") }.to_h
# => {"t"=>"1727812624", "v1"=>"f81bf14b6d796c8b9b627f5ba95ba92b9366ff07c285af910558989f998905e9"}
expected_sig = OpenSSL::HMAC.hexdigest("SHA256", hmac_secret, "#{sig_parts["t"]}#{body}")
# => "f81bf14b6d796c8b9b627f5ba95ba92b9366ff07c285af910558989f998905e9"
# Test v1 that matches the expected signature. (Use a constant time comparison in production.)
expected_sig == sig_parts["v1"] #=> true
# Test that the request was sent recently to prevent replay.
Time.at(sig_parts["t"].to_i) #=> 2024-10-01 14:57:04 -0500