Introduction
Welcome to the Structurely Holmes API! You can use our API to view, update, query both leads and agent's accounts. This API is a work in progress and is not in a final state. API endpoints, authentication flows, and availability may be subject to change at any time. If you are intestested in working with us via our API please contact us at info@structurely.com
Authentication
All requests to the API in must include the header X-Api-Authorization with your API key. There will soon be a OAuth2 flow for obtaining bearer tokens to use in the Authorization header. To get an API key please contact us.
Overview
Endpoints
All endpoints are hosted by the domain api.structurely.com
. All requests must use https
. Any request with the protocol http
will be redirected to https
with the status code 301. The path for the api will always start with /v1
. Every resource endpoint will start with https://api.structurely.com/v1
.
Types
Type | Description |
---|---|
ObjectId |
A 24 byte hexadecimal string. See ObjectId. |
Boolean |
A JSON boolean represented by either true or false . |
Integer |
A plain integer. May be restricted by an interval (i.e. Intenger[0,) , Integer[0,10] , Integer(0,100] ). |
Float |
A floating point number. |
String |
A plain string. When used as a url or query parameter, it must be url escaped. |
DateTime |
A date time string that can be parsed into a time zone aware date time object. |
List |
An array of values of either a primitive type or a schema. Usually has a type name defined (i.e. List<Agent> , List<Integer> ) |
Enum |
A single value that can be any primative type. Always has a set of possible values defined (i.e. Enum{'hello', 'world'} , Enum{0, 1, 2} ) |
Agents
The Agent resource represents an account in homechat. An agent has settings and owns leads.
Schemas
Agent
Field | Type | Description | Readable? | Writable? |
---|---|---|---|---|
id | ObjectId |
The ID of the agent this resource represents. | Yes | No |
String |
The email of the agent. This is unique and used for login credentials | Yes | No |
List Agents
curl 'https://api.structurely.com/v1/agents?userId=1025&email=john.richards191919%40example.com' \
-H 'X-Api-Authorization: myapikey'
The above command returns JSON structured like this:
{
"_metadata": {
"collection": "agents",
"limit": 10,
"offset": 0,
"total": 1
},
"agents": [
{
"id": "5b92de82f434f50034330e46",
"email": "john.richards191919@example.com"
}
]
}
This endpoint returns a list of agents sorted and/or filtered by the given parameters. This request requires the user_id parameter which refers to a third party integration user id (e.g. liondesk).
HTTP Request
GET https://api.structurely.com/v1/agents
Query Parameters
Parameter | Type | Description | Required? | Default |
---|---|---|---|---|
userId[1] | String,Integer |
The third party user id | Yes | None |
limit | Integer[1,100] |
The number of results to return | No | 10 |
offset | Integer[0,) |
Indicates the number of results to skip | No | 0 |
sort[2] | String |
A comma separated list of fields to sort by | No | email |
email[3] | String |
A partial or full email to search | No | None |
- This field expects the request to be coming from a system that has already integrated with Homechat. This field is expected to be removed in the near future and is only here to assist in finding an agent in Homechat that has an account in a different system.
- The sort string allows multiple fields with left to right precedence with optional
-
or+
for controlling ascending and descending order - String search fields use a case insensitive partial filter that can match any part of the string
Create Lead
curl 'https://api.structurely.com/v1/agents/5d1faa9de1b5b447404cb545/leads' \
-H 'X-Api-Authorization: myapikey' -H 'Content-Type: application/json' \
-d '{ "name": "John James", "email": "john.james@gmail.com", "phone": "+15551234567", "source": "EasyAgentPro", "type": "Buyer", "conversation": { "initialMessage": "Hello, I am interested in 123 Main St." }, "search": { "addresses": ["123 Main St."] }, "integrations": { "boomtown": { "primaryId": { "name": "contact_id", "value": "1" }, "secondaryIds": [] } }}'
The above command returns JSON structured like this:
{
"id": "5d1fb274e1b5b454fb43b45c",
"name": "John James",
"email": "john.james@gmail.com",
"phone": "+15551234567",
"readiness": "",
"firstContact": 1529970559.365,
"lastContact": 1530572384.613,
"muted": false,
"conversation": {
"collection": "lead.conversation",
"next": "https://api.structurely.com/v1/leads/5d1fb274e1b5b454fb43b45c/conversation",
"total": 108
},
"integrations": {
"boomtown": {
"primaryId": {
"name": "contact_id",
"value": "1"
},
"secondaryIds": []
}
}
}
!!! WIP !!! Full docs and changes to the /leads endpoints will be made in the near future.
This lead endpoint creates a new lead for the agent with the given id. The lead will will be contacted as a lead that filled out a contact form. Hours of operation and other chatbot settings apply to the lead so contact the first message may not be sent immediately or even at all in the appropriate circumstances.
HTTP Request
POST https://api.structurely.com/v1/agents/<id>/leads
URL Parameters
Parameter | Description |
---|---|
id | The ID of the lead to retrieve |
Body Parameters[^]
!!! TODO !!!
Leads
The Lead resource represents a single contact possibly with a conversation in homechat. This conversation includes messages by agents, the lead, and Holmes.
Schemas
Lead
Field | Type | Description | Readable? | Writable? |
---|---|---|---|---|
id | ObjectId |
The ID of the lead this resource represents. | Yes | No |
name | String |
The full name of the lead. | Yes | Yes |
String |
The email of the lead. | Yes | Yes | |
phone | String |
The phone number of the lead in the format +15551234567 . |
Yes | No |
readiness | String |
The readiness of the lead. Can be one of the following values: active , just_looking , researching , or an empty string. |
Yes | No |
firstContact | Float |
The number of seconds after the unix epoch since first contact was made with this lead. | Yes | No |
lastContact | Float |
The number of seconds after the unix epoch since the latest contact was made with this lead. | Yes | No |
muted | Boolean |
Indicates whether Holmes is muted in the conversation or not. | Yes | Yes |
stages | List[String] |
The list of stages this lead is in. Can be any combination of the following values: responded , not_responded , interested , not_interested , needs_follow_up , suggest_fallback . |
Yes | No |
tags | List[String] |
The tags attached to this lead. Can be any string to associate with the lead. | Yes | Yes |
conversation | LeadConversation |
The conversation metadata object for this lead. | Yes | No |
LeadConversation
Field | Type | Description | Readable? | Writable? |
---|---|---|---|---|
collection | String |
Always the value lead.conversation . |
Yes | No |
total | Integer |
The total number of messages sent by the lead, Holmes, and the agent. | Yes | No |
next[1] | String |
The url for the next 100 or fewer messages in the sequence. | Yes | No |
- If this object is not part of a response in a sequence, the next value will be the url for the latest 100 messages for this lead conversation.
LeadMessage
Field | Type | Description | Readable? | Writable? |
---|---|---|---|---|
id | ObjectId |
The ID of the message for this conversation. | Yes | No |
received | Float |
The unix timestamp this message was received/sent. | Yes | No |
text | String |
The text of the message that was sent or received. | Yes | No |
type[1] | String |
The type of the message. It will either be message , response , or agentMessage . |
Yes | No |
- The type
message
is set if the message was sent by the lead. The typeresponse
is set if the message was sent by Holmes. The typeagentMessage
is set if the message was sent by the agent from homechat.
List Leads
curl 'https://api.structurely.com/v1/leads?ownerId=59275069dec26a0d20fcc41e&name=john' \
-H 'X-Api-Authorization: myapikey'
The above command returns JSON structured like this:
{
"_metadata": {
"collection": "leads",
"limit": 10,
"offset": 0,
"total": 3
},
"leads": [
{
"id": "5b317f7f97f5a50048e1a516",
"name": "John Doe",
"email": "jdoe@example.com",
"phone": "+15551234567",
"readiness": "",
"firstContact": 1529970559.365,
"lastContact": 1530572384.613,
"muted": false,
"tags": [],
"conversation": {
"collection": "lead.conversation",
"total": 10,
"next": "https://api.structurely.com/v1/leads/5b317f7f97f5a50048e1a516/conversation"
}
},
{
"id": "5a8b7ce54aecff0034c31776",
"name": "john doe",
"email": "the.real.jdoe@example.com",
"phone": "+15551112222",
"readiness": "active",
"firstContact": 1519090916.902,
"lastContact": 1519090973.948,
"muted": false,
"tags": [],
"conversation": {
"collection": "lead.conversation",
"total": 2,
"next": "https://api.structurely.com/v1/leads/5a8b7ce54aecff0034c31776/conversation"
}
},
{
"id": "5a690b0ef4a8dc00359afb57",
"name": "John Harkin",
"email": "jharkin@example.com",
"phone": "+15557654321",
"readiness": "just_looking",
"firstContact": 1516833549.595,
"lastContact": 1516833576.27,
"muted": true,
"tags": [],
"conversation": {
"collection": "lead.conversation",
"total": 4,
"next": "https://api.structurely.com/v1/leads/5a690b0ef4a8dc00359afb57/conversation"
}
}
]
}
This endpoint returns a list of leads sorted and/or filtered by the given parameters. This request requires the ownerId parameter which refers to an agent id.
HTTP Request
GET https://api.structurely.com/v1/leads
Query Parameters
Parameter | Type | Description | Required? | Default |
---|---|---|---|---|
ownerId | ObjectId |
The id of the agent that owns this lead | Yes | None |
limit | Integer[1,100] |
The number of results to return | No | 10 |
offset | Integer[0,) |
Indicates the number of results to skip | No | 0 |
sort[1] | String |
A comma separated list of fields to sort by | No | -lastContact |
name[2] | String |
A partial or full name to search | No | None |
email[2] | String |
A partial or full email to search | No | None |
phone[2] | String |
A partial or full phone number to search | No | None |
- The sort string allows multiple fields with left to right precedence with optional
-
or+
for controlling ascending and descending order - String search fields use a case insensitive partial filter that can match any part of the string
Create Lead
curl 'https://api.structurely.com/v1/leads' \
-H 'X-Api-Authorization: myapikey' -H 'Content-Type: application/json' \
-d '{ "name": "John James", "email": "john.james@gmail.com", "phone": "+15551234567", "source": "EasyAgentPro", "type": "Buyer", "tags": ["use-case-1"], "conversation": { "initialMessage": "Hello, I am interested in 123 Main St." }, "search": { "addresses": ["123 Main St."] }, "integrations": { "boomtown": { "primaryId": { "name": "contact_id", "value": "1" }, "secondaryIds": [] } }}'
The above command returns JSON structured like this:
{
"id": "5d1fb274e1b5b454fb43b45c",
"name": "John James",
"email": "john.james@gmail.com",
"phone": "+15551234567",
"readiness": "",
"firstContact": 1529970559.365,
"lastContact": 1530572384.613,
"muted": false,
"tags": ["use-case-1"],
"conversation": {
"collection": "lead.conversation",
"next": "https://api.structurely.com/v1/leads/5d1fb274e1b5b454fb43b45c/conversation",
"total": 108
},
"integrations": {
"boomtown": {
"primaryId": {
"name": "contact_id",
"value": "1"
},
"secondaryIds": []
}
}
}
!!! WIP !!! Full docs and changes to the /leads endpoints will be made in the near future.
This lead endpoint creates a new lead for entity that owns the api key with the given id. The lead will will be contacted as a lead that filled out a contact form. Hours of operation and other chatbot settings apply to the lead so contact the first message may not be sent immediately or even at all in the appropriate circumstances.
HTTP Request
POST https://api.structurely.com/v1/leads
Body Parameters[^]
!!! TODO !!!
Get Lead
curl 'https://api.structurely.com/v1/leads/5ab1973c62c5be0034c2102c' \
-H 'X-Api-Authorization: myapikey'
The above command returns JSON structured like this:
{
"id": "5ab1973c62c5be0034c2102c",
"name": "John Doe",
"email": "jdoe@example.com",
"phone": "+15551234567",
"readiness": "researching",
"firstContact": 1529970559.365,
"lastContact": 1530572384.613,
"muted": false,
"tags": ["form-registration"],
"conversation": {
"collection": "lead.conversation",
"next": "https://api.structurely.com/v1/leads/5ab1973c62c5be0034c2102c/conversation",
"total": 108
}
}
This endpoint returns a specific lead.
HTTP Request
GET https://api.structurely.com/v1/leads/<id>
URL Parameters
Parameter | Description |
---|---|
id | The ID of the lead to retrieve |
Get Lead Conversation
curl 'https://api.structurely.com/v1/leads/5ab1973c62c5be0034c2102c/conversation' \
-H 'X-Api-Authorization: myapikey'
The above command returns JSON structured like this:
{
"_metadata": {
"collection": "lead.conversation",
"next": "https://api.structurely.com/v1/leads/5ab1973c62c5be0034c2102c/conversation?before=1540400827.866",
"total": 108
},
"conversation": [
{
"id": "5bd0a6bbbfd5b5002268f971",
"received": 1540400827.866,
"text": "It's always helpful to have financing figured out early in the process!",
"type": "response"
},
{
"id": "5c018167def58d0021d267cd",
"received": 1543602535.414,
"text": "Thank's for all the help. I'm really excited to see this home tomorrow.",
"type": "message"
}
]
}
This endpoint returns a specific lead's conversaton. It will return no more than 100 messages at a time. The _metadata.next
value gives the url that will return the next batch of messages in the sequence. If there are no more messages _metadata.next
will be null
. If the before
parameter is used, the next batch will be before the earliest message and if after
is used, the next batch will be after the latest message. If there is no parameter defined the latest 100 messages are returned and the _metadata.next
url will be for the previous batch with a before parameter. The _metadata.total
value returns the total number of messages in the conversation.
HTTP Request
GET https://api.structurely.com/v1/leads/<id>/conversation
URL Parameters
Parameter | Description |
---|---|
id | The ID of the lead to retrieve the conversation for |
Query Parameters
Parameter | Type | Description | Required? | Default |
---|---|---|---|---|
before[1] | Float |
The unix timestamp all messages must have been received before | No | None |
after[1] | Float |
The unix timestamp all messages must have been received after | No | None |
- The
before
andafter
parameters are mutually exclusive. Neither is required but only one may be present.
Update Lead
curl 'https://api.structurely.com/v1/leads/5ab1973c62c5be0034c2102c' \
-X PATCH \
-H 'X-Api-Authorization: myapikey' \
-H 'Content-Type: application/json' \
-d '{ "muted": true, "tags": ["first-time-home-buyer"] }'
The above command returns JSON structured like this:
{
"id": "5ab1973c62c5be0034c2102c",
"name": "John Doe",
"email": "jdoe@example.com",
"phone": "+15551234567",
"readiness": "just_looking",
"firstContact": 1529970559.365,
"lastContact": 1530572384.613,
"muted": true,
"tags": ["new-lead", "first-time-home-buyer"]
"conversation": {
"collection": "lead.conversation",
"next": "https://api.structurely.com/v1/leads/5ab1973c62c5be0034c2102c/conversation",
"total": 108
}
}
This endpoint updates a specific lead and returns the modified lead object. Tags are added to existing tags.
HTTP Request
PATCH https://api.structurely.com/v1/leads/<id>
URL Parameters
Parameter | Description |
---|---|
id | The ID of the lead to update |
Body Parameters[^]
Parameter | Type |
---|---|
name | String |
String |
|
muted | Boolean |
tags | List[String] |
Conversations
The Conversation resource represents a conversational exchange with Aisa. This is distict from a lead because it interfaces directly with aisa rather than showing up for an agent in homechat.
Schemas
Conversation
Field | Type | Description | Readable? | Writable? | Required? | Default |
---|---|---|---|---|---|---|
id | ObjectId |
The ID of the conversation this resource represents. | Yes | No | No | |
settings | ConversationSettings |
The settings for holmes per this conversation. | Yes | No | Yes | |
slots | List<ConversationSlot> |
A list of extracted or pre-filled values relating to the conversation. | Yes | No | Yes | |
muted | Boolean |
A boolean flag to tell Holmes whether or not this conversation is muted. A muted conversation can still receive messages but will generate no replies. | Yes | Yes | No | false |
stages | List<String> |
A list of stages this conversation is currently in. | Yes | No | No | |
messages | List<ConversationItem> |
A list of lead messages and system responses with the context value with each response. | No | No | Yes |
ConversationSettings
Field | Type | Description | Readable? | Writable? | Required? | Default |
---|---|---|---|---|---|---|
timeZone | String |
The time zone the realtor and/or lead. (See list) | Yes | No | Yes | |
holmesName | String |
The name of conversation AI to use in responses. | Yes | No | No | Aisa |
leadTypes | List<String> |
The lead types that will be supported in this conversation. Possible values are buyer , seller , and renter |
Yes | No | No | ['buyer', 'seller'] |
allowedDomains | List<String> |
The domains that this conversation can use for conversation flows. Possible values are real_estate and mortgage . When a lead sets or changes its lead type, the domain determines what scripts to use. |
Yes | No | No | ['real_estate'] |
dripCampaignEnabled | Boolean |
If set to true, Holmes drip campaigns will be used for an unresponsive lead. Only runs if there is no lead message following a system response in the messages list. | Yes | No | false |
|
reDripsEnabled | Boolean |
If set to true, Holmes will re-engage leads that have responded but are not responding to the current prompt. Will use the current context to determine outbound re-drips even if a custom response is generated by the third party user. | Yes | No | false |
ConversationSlot
Field | Type | Description | Readable? | Writable? | Required? |
---|---|---|---|---|---|
name[a] | String |
The name of the slot. | Yes | No | Yes |
value[a] | Any |
The value of the slot. | Yes | No | Yes |
ConversationItem
Field | Type | Description | Readable? | Writable? | Required? |
---|---|---|---|---|---|
message | Message |
A message the lead sent. | No | Yes | Yes[1] |
respone | Message |
A respone sent by the system. | No | Yes | Yes[1] |
context[b] | String |
The context set by the response in this conversation item. | No | Yes | Yes[2] |
message
andresponse
are mutually exclusive. At least one is required to be present but not both.context
is only required if theresponse
field is used.
Message
Field | Type | Description | Readable? | Writable? | Required? |
---|---|---|---|---|---|
text | String |
The text of the message. | No | Yes | Yes |
received | DateTime |
The time the message was sent or received. | No | Yes | Yes |
_metadata[1] | MessageMetaData |
An optional metadata object to set the outgoing context for a response. | No | Yes | No |
_metadata
is only used when creating a response object.
MessageMetaData
Field | Type | Description | Readable? | Writable? | Required? |
---|---|---|---|---|---|
context | String |
The outgoing context of this response. Used by Holmes to classify messages sent after this response. | No | Yes | No |
Slots, Contexts, and Stages
Slots
Name | Type | Description |
---|---|---|
Lead Contact Information | ||
name | String |
The name of the lead. |
String |
The email of the lead. | |
phone | String |
The phone number of the lead. |
address | String |
The address of the property a buyer lead is interested in. |
selling_address | String |
The address of the property a seller lead is trying to sell. |
lead_type | List<String> |
A list of lead types this lead is considered as. Not limited to but includes any of buyer , buyer_specific , renter , renter_specific , seller , just_looking , pending_sale_interest , investor , rent_to_own , rent_to_own_specific , new_home_loan , new_home_loan_specific , home_refinance or a combination thereof. |
Agent Contact Information | ||
agent_name | String |
The name of the agent Holmes is messaging on the behalf of. |
agent_email | String |
The email of the agent. |
agent_phone | String |
The phone of the agent. |
agency_name | String |
The name of the agency the agent works for or Holmes is messaging on the behalf of. |
office_location | String |
The general location of the realtor office the system is representing. |
General Lead Information | ||
agent_status | Boolean |
True if the lead is already working with an agent. |
alternate_plan | String |
|
appointment | String |
The time the lead is available for an appointment. |
baths | Float |
The specific number bathrooms the lead is looking for. |
baths_min | Float |
The minimum number of bathrooms the lead is looking for. |
baths_max | Float |
The maximum number of bathrooms the lead is looking for. |
beds | Integer |
The specific number of bedrooms the lead is looking for. |
beds_min | Integer |
The minimum number of bedrooms the lead is looking for. |
beds_max | Integer |
The maximum number of bedrooms the lead is looking for. |
benefit | Boolean |
|
business_development | Enum |
Business development. Possible values:{'outbound', 'inbound', 'paid', 'referral', 'networking'} |
call_availability | String |
The time when the lead is available for a call with the agent. |
company_name | String |
|
competitor_status | Boolean |
|
confidence | Enum |
Confidence. Possible values:{'very_confident', 'somewhat_confident', 'not_confident'} |
contact_confirmation | Boolean |
|
contact_time | String |
|
content_offer | Boolean |
|
contingency | Boolean |
True if the lead needs to sell their current home before buying. |
credit | Enum |
Credit rating. Possible values:{'very_poor', 'fair', 'good', 'very_good', 'excellent'} |
credit_score | Integer[300,850] |
|
debt_to_income | Float[0,50] |
|
decision_maker | Boolean |
|
decision_process | String |
|
delivery_followup | Boolean |
|
description | String |
|
down_payment | Float |
|
down_payment_min | Float |
|
down_payment_max | Float |
|
employment_status | Enum |
Employment status. Possible values:{'self_employed', 'employed', 'not_employed'} |
equity_status | Float |
|
equity_status_min | Float |
|
equity_status_max | Float |
|
favorite_city | String |
|
financial_default | Enum |
Financial default. Possible values:{'bankruptcy', 'foreclosure', 'short_sale', 'missed_payments'} |
financing_status | Boolean |
True if the lead is prequalified or paying with cash. |
first_time_buyer | Boolean |
|
fsbo_reason | String |
|
garage_stalls | Integer[0,8] |
Number of garage stalls. |
garage_stalls_min | Integer[0,8] |
Minimum number of garage stalls. |
garage_stalls_max | Integer[0,8] |
Maximum number of garage stalls. |
home_style | Enum |
The home style(s) the lead is interested in. Possible values:{'art_deco', 'barndominium', 'bungalow', 'cape_cod', 'colonial', 'condominium', 'contemporary', 'craftsman', 'creole', 'dutch_colonial', 'farmhouse', 'federal', 'french_provincial', 'georgian', 'gothic_revival', 'greek_revival', 'international', 'italianate', 'log_cabin', 'modern', 'monterey', 'national', 'neoclassical', 'prairie', 'pueblo', 'queen_anne', 'ranch', 'regency', 'saltbox', 'second_empire', 'shed', 'shingle', 'shotgun', 'spanish_eclectic', 'split_level', 'stick', 'tudor', 'victorian', 'other'} |
image | String |
|
income | Float |
|
interest | Enum |
Interest. Possible values:{'interested', 'not_interested', 'somewhat_interested', 'postponed_interested'} |
is_agent | Boolean |
True if the lead is an agent. |
is_investor | Boolean |
True if the lead is an investor buying property. |
is_local | Boolean |
|
language | Enum |
The language detected in this conversation. Current conversation support is for English and Spanish languages only. Possible values:{'spanish', 'mandarin', 'french', 'hindi', 'arabic', 'portuguese', 'bengali', 'russian', 'japanese', 'punjabi', 'english'} |
lead_priority | Enum |
Lead priority. Possible values:{'now', 'soon', 'later', 'distant', 'never'} |
lead_source | String |
The source of the lead. Can be any string. |
lender_status | Boolean |
|
listing_appointment | String |
The time the lead is available for an appointment about their listing. |
listing_url | String |
|
living_space | Integer |
The living space the lead is searching for. |
living_space_min | Integer |
The minimum living space the lead is searching for. |
living_space_max | Integer |
The maximum living space the lead is searching for. |
loan_balance | Integer |
The loan balance. |
loan_balance_min | Integer |
The minimum loan balance. |
loan_balance_max | Integer |
The maximum loan balance. |
loan_type | Enum |
Loan type. Possible values:{'fha', 'conventional', 'va', 'reverse_mortgage', 'jumbo', 'usda'} |
location | String |
The general location the lead is interested in buying. |
lot_size | Integer |
The lot size the lead is searching for. |
lot_size_min | Integer |
The minimum lot size the lead is searching for. |
lot_size_max | Integer |
The maximum lot size the lead is searching for. |
meeting_location | String |
Special values:webcam , zoom , google_hangouts , uberconference , open |
military_active_duty | Boolean |
|
military_branch | Enum |
Possible values:{'army', 'air_force', 'coast_guard', 'marines', 'navy', 'national_guard', 'space_force'} |
military_discharge_type | Enum |
Possible values:{'honorable_discharge', 'general_discharge', 'other_than_honorable_discharge', 'bad_conduct_discharge', 'dishonorable_discharge', 'entry_level_separation', 'medical_separation', 'separation_for_convenience_of_the_government'} |
military_reserves_service | Boolean |
|
military_service_term | Integer |
|
mortgage_escrow | Boolean |
|
mortgage_intent | Enum |
Possible values:{'preapproval', 'rate_quote'} |
motivation | Enum |
Possible values:{'new_job', 'lost_job', 'downsizing', 'upsizing', 'death', 'debt', 'divorce', 'lease_expiry', 'lifestyle', 'investment', 'environmental', 'save_money', 'closer_to_family', 'tired_of_renting', 'new_children', 'retiring', 'space_for_animals', 'neighbor_sold_property', 'sold_property', 'ready_to_move', 'closer_to_school', 'closer_to_friends', 'good_schools', 'vacation_interest', 'homeless', 'privacy', 'weather'} |
motivation_plans | String |
|
outcome | String |
|
ownership | Enum |
Possible values:{'sole_owner', 'co_owner', 'third_party_owner', 'no_ownership'} |
ownership_timeline | String |
Special value: open |
price | Float |
The specific price the lead is looking for. |
price_min | Float |
The minimum price the lead is looking for. |
price_max | Float |
The maximum price the lead is looking for. |
prior_loan_experience | Boolean |
|
problem | String |
|
promotional_offer | Enum |
Interest. Possible values:{'interested', 'not_interested', 'somewhat_interested', 'postponed_interested'} |
property_feature | Enum |
Possible values:{'access_to_water', 'big_yard', 'detached_garage', 'exposed_beams', 'exposed_brick', 'finished_basement', 'handicap_accessible', 'home_office', 'pool', 'space_to_entertain', 'updated_baths', 'updated_kitchen', 'vaulted_ceilings', 'walkable_neighborhood', 'fenced_yard', 'other'} |
property_info_request | Enum |
Possible values:{'baths', 'beds', 'boat_slip', 'community_info', 'covenants', 'days_on_market', 'deed_restrictions', 'disclosures', 'expected_dom', 'floorplan', 'garage_spaces', 'hoa', 'living_space', 'lot_rent', 'lot_size', 'owners', 'pet_friendly', 'price', 'property_location', 'property_type', 'public_remarks', 'rental_history', 'schools', 'senior_community', 'status', 'stories', 'taxes', 'transactions', 'utilities', 'year_built', 'zoning'} |
property_location | String |
|
property_preferences | String |
|
property_records | Enum |
Possible values:{'second_mortgage', 'lien'} |
property_status | Enum |
Possible values:{'active', 'sold', 'pending'} |
property_type | Enum |
Possible values:{'vacant_land', 'handicap_accessible', 'commercial', 'apartment', 'mobile_home', 'acreage', 'ranch', 'vacation_home', 'residential'} |
property_use | Enum |
Property use. Possible values:{'vacation', 'investment', 'primary_residence', 'secondary_residence', 'agriculture'} |
property_value | Float |
|
property_value_min | Float |
|
property_value_max | Float |
|
property_visit | Boolean |
|
question | Enum |
The question that the lead just asked. Possible values:{'pricing', 'integrations', 'how_it_works', 'features', 'setup_time', 'savings', 'repairs', 'results', 'consultation', 'leasing', 'delivery_time', 'competitive_advantage', 'product_requirements', 'specifications', 'incentives', 'warranty', 'return_on_investment', 'discounts', 'assembly_details', 'referrals', 'compliance', 'available_geography', 'upgrade', 'extension', 'company_details', 'sell_power_back', 'inverter_type', 'license_number', 'data_import', 'quote', 'taxes', 'schools', 'other'} |
readiness | Enum |
The readiness of the lead. Possible values:{'active', 'just_looking', 'researching', 'not_interested', ''} |
relocating | Boolean |
|
savings | Float |
|
savings_min | Float |
|
savings_max | Float |
|
selling_property_description | String |
|
showing_appointment | String |
The time the lead is available for a showing appointment. |
tags | String |
General purpose tags for managing and tracking conversations. Will not be asked as a qualifier and is not used to generate responses. |
technology | String |
Special value: open |
tenure | String |
|
time | String |
Special value: open |
timeframe | String |
The general timeframe a lead is looking to move within. |
url | String |
|
veteran | Boolean |
|
veteran_service_disability | Boolean |
|
work_history | String |
Contexts
Name |
---|
general |
expect_address |
expect_agent_status |
expect_alternate_plan |
expect_appointment |
expect_baths |
expect_beds |
expect_business_development |
expect_call_availability |
expect_company_name |
expect_competitor_status |
expect_confidence |
expect_contact_confirmation |
expect_contact_time |
expect_contingency |
expect_credit |
expect_credit_score |
expect_debt_to_income |
expect_decision_maker |
expect_delivery_followup |
expect_description |
expect_down_payment |
expect_email |
expect_employment_status |
expect_equity_status |
expect_financial_default |
expect_financing_status |
expect_first_time_buyer |
expect_fsbo_reason |
expect_garage_stalls |
expect_image |
expect_income |
expect_interest |
expect_is_local |
expect_language |
expect_lead_type |
expect_listing_appointment |
expect_living_space |
expect_loan_balance |
expect_location |
expect_lot_size |
expect_meeting_location |
expect_military_active_duty |
expect_military_branch |
expect_military_discharge_type |
expect_military_reserves_service |
expect_military_service_term |
expect_mortgage_escrow |
expect_mortgage_intent |
expect_motivation |
expect_motivation_plans |
expect_name |
expect_outcome |
expect_ownership |
expect_ownership_timeline |
expect_phone |
expect_preferred_channel |
expect_price |
expect_prior_loan_experience |
expect_problem |
expect_product_interest |
expect_promotional_offer |
expect_property_feature |
expect_property_location |
expect_property_preferences |
expect_property_records |
expect_property_status |
expect_property_type |
expect_property_value |
expect_question |
expect_readiness |
expect_relocating |
expect_savings |
expect_selling_address |
expect_showing_appointment |
expect_time |
expect_timeframe |
expect_url |
expect_veteran |
expect_veteran_service_disability |
Stages
Name | Description |
---|---|
not_responded | The lead has not responded in this conversation. |
responded | The lead has responded in this conversation. |
not_interested | The lead has indicated no interest or opted out of communication in this conversation. |
interested | The lead has responded and has not been classified as not interested. |
needs_follow_up | The lead has reached a conclusion in the conversation that requires further follow-up. |
Domains
To use domains other than the default real_estate domain, the domains have to be enabled in the settings and an appropriate lead type has to be selected in the lead_type slot. An example of using the mortgage scripts for a new home loan buyer would be to set the allowedDomains
settings value to ["real_estate", "mortgage"]
and setting the lead_type slot to the values "buyer"
and "new_home_loan"
.
Create Conversation
curl 'https://api.structurely.com/v1/conversations' \
-X POST \
-H 'X-Api-Authorization: myapikey' \
-H 'Content-Type: application/json' \
-d '{ "settings": { "timeZone": "America/Chicago" }, "slots": [{ "name": "email", "value": "jdoe@example.com" }], "messages": [{ "response": { "text": "Hello, what is your name?", "received": "2018-12-08T15:20:00.000Z" }, "context": "expect_name }, { "message": { "text": "John", "received": "2018-12-08T16:34:00.000Z" } }] }'
The above command returns JSON structured like this:
{
"id": "5c09a4416241ea2c293275b8",
"settings": {
"holmesName": "Aisa",
"timeZone": "America/Chicago"
},
"slots": [
{
"name": "email",
"value": "jdoe@example.com"
}
],
"muted": false
}
This endpoint creates and returns a new conversation object.
HTTP Request
POST https://api.structurely.com/v1/conversations
Body Parameters[^]
Parameter | Type |
---|---|
settings | ConversationSettings |
slots | List<ConversationSlot> |
muted | Boolean |
messages | List<ConversationItem> |
Get Conversation
curl 'https://api.structurely.com/v1/conversations/5c09a4416241ea2c293275b8' \
-H 'X-Api-Authorization: myapikey'
The above command returns JSON structured like this:
{
"id": "5c09a4416241ea2c293275b8",
"settings": {
"holmesName": "Aisa",
"timeZone": "America/Chicago"
},
"slots": [
{
"name": "name",
"value": "John Doe"
},
{
"name": "email",
"value": "jdoe@example.com"
},
{
"name": "phone",
"value": "+15551234567"
},
{
"name": "address",
"value": "123 Main St."
},
{
"name": "agent_name",
"value": "Andi Agent"
},
{
"name": "lead_types",
"value": [
"buyer"
]
}
],
"muted": false
}
This endpoint returns a specific conversation.
HTTP Request
GET https://api.structurely.com/v1/conversations/<id>
URL Parameters
Parameter | Description |
---|---|
id | The ID of the conversation to retrieve |
Update Conversation
curl 'https://api.structurely.com/v1/conversations/5c09a4416241ea2c293275b8' \
-X PATCH \
-H 'X-Api-Authorization: myapikey' \
-H 'Content-Type: application/json' \
-d '{ "muted": true }'
The above command returns JSON structured like this:
{
"id": "5c09a4416241ea2c293275b8",
"settings": {
"holmesName": "Aisa",
"timeZone": "America/Chicago"
},
"slots": [
{
"name": "email",
"value": "jdoe@example.com"
}
],
"muted": true
}
This endpoint updates and returns a specific conversation object.
HTTP Request
PATCH https://api.structurely.com/v1/conversations/<id>
URL Parameters
Parameter | Description |
---|---|
id | The ID of the conversation to update |
Body Parameters[^]
Parameter | Type |
---|---|
muted | Boolean |
Insert Slots
curl 'https://api.structurely.com/v1/conversations/5c09a4416241ea2c293275b8/slots' \
-X POST \
-H 'X-Api-Authorization: myapikey' \
-H 'Content-Type: application/json' \
-d '[{ "name": "agent_name", "value": "Andi Agent" }]'
The above command returns an empty body with a 204 response
This endpoint inserts the given slots to the conversation. Multi-valued slots will append the new values rather than replacing them. Returns a 204 response with an empty body.
HTTP Request
POST https://api.structurely.com/v1/conversations/<id>/slots
URL Parameters
Parameter | Description |
---|---|
id | The ID of the conversation insert slots to |
Body Parameters
The body is a list of objects
Type | Description |
---|---|
List<ConversationSlot> |
The list of conversation slot objects |
Update Slots
curl 'https://api.structurely.com/v1/conversations/5c09a4416241ea2c293275b8/slots' \
-X PATCH \
-H 'X-Api-Authorization: myapikey' \
-H 'Content-Type: application/json' \
-d '[{ "name": "agent_name", "value": "Andi Agent" }]'
The above command returns an empty body with a 204 response
This endpoint updates the given slots to the conversation. Multi-valued slots will be overwritten with the new values replacing the old ones. Returns a 204 response with an empty body.
HTTP Request
PATCH https://api.structurely.com/v1/conversations/<id>/slots
URL Parameters
Parameter | Description |
---|---|
id | The ID of the conversation insert slots to |
Body Parameters
The body is a list of objects
Type | Description |
---|---|
List<ConversationSlot> |
The list of conversation slot objects |
Upsert Slot
curl 'https://api.structurely.com/v1/conversations/5c09a4416241ea2c293275b8/slots/agent_name' \
-X PUT \
-H 'X-Api-Authorization: myapikey' \
-H 'Content-Type: application/json' \
-d '["Andi Agent"]'
The above command returns an empty body with a 204 response
This endpoint updates the exsting slot with that name to the list of values provided. All slots, both multi-valued and single-valued are provided in an array. Make the array a single element array if the slot is single-valued. If the slot does not already exist with that name, it is inserted with all the values provided.
HTTP Request
PUT https://api.structurely.com/v1/conversations/<id>/slots/<name>
URL Parameters
Parameter | Description |
---|---|
id | The ID of the conversation insert slots to |
name | The name of the slot to update or insert |
Body Parameters
The body is a list of values
Type | Description |
---|---|
List<Any> |
The list of slot values |
Create Message
curl 'https://api.structurely.com/v1/conversations/5c09a4416241ea2c293275b8/messages'
-X POST \
-H 'X-Api-Authorization: myapikey' \
-H 'Content-Type: application/json' \
-d '{ "text": "Hello World", "received": "2018-12-09T11:44:00.000Z" }'
The above command returns JSON structured like this:
{
"_metadata": {
"conversation": "5c09a4416241ea2c293275b8",
"messages": 2,
"responses": 1
},
"message": {
"id": "5c09a45e6241ea2c293275bf",
"text": "Hello World",
"received": "2018-12-09T11:44:00.000Z"
}
}
This endpoint creates a new lead message for the conversation for us to extract and classify.
HTTP Request
POST https://api.structurely.com/v1/conversations/<id>/messages
URL Parameters
Parameter | Description |
---|---|
id | The ID of the conversation to retrieve |
Body Parameters[^]
Parameter | Type |
---|---|
text | String |
received | DateTime |
Create Response
curl 'https://api.structurely.com/v1/conversations/5c09a4416241ea2c293275b8/responses'
-X POST \
-H 'X-Api-Authorization: myapikey' \
-H 'Content-Type: application/json' \
-d '{ "_metadata": { "context": "expect_showing_appointment" }, "text": "Hello There", "received": "2018-12-09T11:44:00.000Z" }'
The above command returns JSON structured like this:
{
"_metadata": {
"conversation": "5c09a4416241ea2c293275b8",
"context": "expect_showing_appointment",
"messages": 2,
"responses": 2
},
"response": {
"id": "5c09a4416241ea2c293275b5",
"text": "Hello There",
"received": "2018-12-09T11:44:00.000Z"
}
}
This endpoint creates a new system response for the conversation. This does nothing in our system other than act as a send receipt notifying us that an outbound message was sent on behalf of the system/realtor.
HTTP Request
POST https://api.structurely.com/v1/conversations/<id>/responses
URL Parameters
Parameter | Description |
---|---|
id | The ID of the conversation to retrieve |
Body Parameters[^]
Parameter | Type |
---|---|
_metadata | MessageMetaData |
text | String |
received | DateTime |
Conversation Webhooks
The ConversationWebhook resource represents a url endpoint that will be called for certain actions called triggers. Examples of triggers include conversation updates, response creation, and fallback suggested. Each webhook belongs to an client/API key and all conversations created by that client will be linked to webhooks of the same client.
API Schemas
ConversationWebhook
Field | Type | Description | Readable? | Writable? | Required? | Default |
---|---|---|---|---|---|---|
id | ObjectId |
The ID of the conversation webhook this resource represents. | Yes | No | No | |
name | String |
The user friendly name of the webhook. Has no functional value but useful for describing the webhook's purpose. | Yes | Yes | No | |
target | String |
A valid url that the webhook payload will be sent to. | Yes | Yes | Yes | |
secret | String |
A secret key that will be used as a http header to ensure the sender is our system. | Yes | No | No | |
version | String |
A string indicating the API version. (e.g. 'v1') | Yes | No | No | 'v1' |
triggers | List<String> |
The list of triggers this webhook is subscribed to. | Yes | Yes | Yes | |
createdAt | DateTime |
The datetime string of when this webhook was created. | Yes | No | No | |
updatedAt | DateTime |
The datetime string of when this webhook was last updated. | Yes | No | No |
Webhook Schemas
ConversationSlotUpdate
Field | Type | Description |
---|---|---|
name | String |
The name of the slot being updated. |
action | String |
The action to take on the slot. Either 'set' or 'push' for scalar or list types respectively. |
value[1] | Any [2] |
The new value being set for this slot. Only exists if the action is 'set' . |
values[1] | List<Any> [2] |
The list of values being added to current list of values for this slot. Only exists if the action is 'push' . |
ConversationStageUpdate
Field | Type | Description |
---|---|---|
name | String |
The name of the stage that is being added or removed from the stage list. |
action | String |
The action to take for this stage. Will be either 'add' or 'remove' . |
reasons | List<String> |
A list of reasons why this stage occurred. A list of either intent names or slot comparisons. |
ConversationUpdates
Field | Type | Description |
---|---|---|
slots | List<ConversationSlotUpdate> [^] |
Conversation slot updates. |
stages | List<ConversationStageUpdate> [^] |
Conversation stage updates. |
value
andvalues
are mutually exclusive. Only one will exist at a time and the other will be undefined.- See slots for more info on each slot and it's type.
Conversation Webhook Overview
Webhooks are used to receive updates for conversations available on the API. These updates are used to notify when a conversations state has changed or when an action like sending a response should be taken. To use webhooks, create a webhook with the triggers that you want to listen for and the target set to an endpoint you control in your system.
Response Created
Response Created Example
{
"trigger": "response:created",
"id": "5c09a4416241ea2c293275b8",
"response": {
"text": "Can you tell me more about the location you're interested in?"
}
}
Trigger
response:created
Description
This trigger is called when a new response for a conversation has been created. Responses are generated by Holmes for a message added to the relevant conversation. Use this event to know when and what to respond to a lead with after a lead sends a message.
Payload
Parameter | Type | Description |
---|---|---|
trigger | String |
The trigger that triggered this webhook. |
id | ObjectId |
The id of the conversation. |
response | Message [^] |
A truncated Message object containing only the text field. The text was generated by Holmes to be sent as a response to a message created in this conversation. |
Conversation Updated
Conversation Updated Example
{
"trigger": "conversation:updated",
"id": "5c09a4416241ea2c293275b8",
"updates": {
"slots": [
{
"name": "email",
"action": "set",
"value": "jdoe@example.com"
},
{
"name": "address",
"action": "push",
"values": ["123 Main St.", "456 North Ave."]
}
],
"stages": [
{
"name": "not_responded",
"action": "remove",
"reasons": []
},
{
"name": "responded",
"action": "add",
"reasons": []
},
{
"name": "needs_follow_up",
"action": "add",
"reasons": ["financing_status is false"]
}
]
}
}
Trigger
conversation:updated
Description
This trigger is called when the convsersation object is updated. It will include the updates to the slots and stages. Use this to maintain state between your system and the Structurely API without polling.
Payload
Parameter | Type | Description |
---|---|---|
trigger | String |
The trigger that triggered this webhook. |
id | ObjectId |
The id of the conversation. |
updates | ConversationUpdates [^] |
The updates to the conversation stages and slots. |
List Conversation Webhooks
curl 'https://api.structurely.com/v1/conversationWebhooks?name=My%20&trigger=response:created' \
-H 'X-Api-Authorization: myapikey'
The above command returns JSON structured like this:
{
"_metadata": {
"collection": "conversationWebhooks",
"limit": 10,
"offset": 0,
"total": 2
},
"conversationWebhooks": [
{
"id": "5ceec43ce1b5b412ba9d0e73",
"name": "My Webhook",
"target": "https://www.example.com/webhooks/endpoint",
"secret": "nLjs7uu5AvQfTjqXpXHnSOfj0h8bvc0w0eeZNWgFR1pJo9Gb",
"version": "v1",
"triggers": ["conversation:updated", "response:created"],
"updatedAt": "2019-05-29T12:41:16.000Z",
"createdAt": "2019-05-29T12:41:16.000Z"
},
{
"id": "5ceed39ce1b5b412ba9d0e74",
"name": "My Other Webhook",
"target": "https://hooks.example.com/structurely/response_created",
"secret": "ZQjevvm3JW7Y8drTROfoRokuYR75BPpAq7NDj0MYkQS2pQVa",
"version": "v1",
"triggers": ["response:created"],
"updatedAt": "2019-05-29T13:48:20.000Z",
"createdAt": "2019-05-29T13:48:20.000Z"
}
]
}
This endpoint returns all webhooks that match the provided parameters. The objects returned will match all the provided parameters.
HTTP Request
GET https://api.structurely.com/v1/conversationWebhooks
Query Parameters
Parameter | Type | Description | Required? | Default |
---|---|---|---|---|
limit | Integer[1,100] |
The number of results to return | No | 10 |
offset | Integer[0,) |
Indicates the number of results to skip | No | 0 |
sort[1] | String |
A comma separated list of fields to sort by | No | -createdAt |
name[2] | String |
A partial or full name of a webhook to search | No | None |
target | String |
A exact URL target of a webhook to match | No | None |
trigger | String |
An exact trigger that must be in a matched webhooks triggers list. Matched webhooks must include this trigger exactly. Matched webhooks may include other triggers. | No | None |
- The sort string allows multiple fields with left to right precedence with optional
-
or+
for controlling ascending and descending order - String search fields use a case insensitive partial filter that can match any part of the string unless otherwise noted
Create Conversation Webhook
curl 'https://api.structurely.com/v1/conversationWebhooks' \
-X POST \
-H 'X-Api-Authorization: myapikey' \
-H 'Content-Type: application/json' \
-d '{ "name": "My Webhook", "target": "https://www.example.com/webhooks/endpoint", "triggers": ["conversation:updated", "response:created"] }'
The above command returns JSON structured like this:
{
"id": "5ceec43ce1b5b412ba9d0e73",
"name": "My Webhook",
"target": "https://www.example.com/webhooks/endpoint",
"secret": "nLjs7uu5AvQfTjqXpXHnSOfj0h8bvc0w0eeZNWgFR1pJo9Gb",
"version": "v1",
"triggers": ["conversation:updated", "response:created"],
"updatedAt": "2019-05-29T12:41:16Z",
"createdAt": "2019-05-29T12:41:16Z"
}
This endpoint creates and returns a new conversation webhook.
HTTP Request
POST https://api.structurely.com/v1/conversationWebhooks
Body Parameters[^]
Parameter | Type |
---|---|
name | String |
target | String |
triggers | List<String> |
Get Conversation Webhook
curl 'https://api.structurely.com/v1/conversationWebhooks/5ceec43ce1b5b412ba9d0e73' \
-H 'X-Api-Authorization: myapikey'
The above command returns JSON structured like this:
{
"id": "5ceec43ce1b5b412ba9d0e73",
"name": "My Webhook",
"target": "https://www.example.com/webhooks/endpoint",
"secret": "nLjs7uu5AvQfTjqXpXHnSOfj0h8bvc0w0eeZNWgFR1pJo9Gb",
"version": "v1",
"triggers": ["conversation:updated", "response:created"],
"updatedAt": "2019-05-29T12:41:16Z",
"createdAt": "2019-05-29T12:41:16Z"
}
HTTP Request
GET https://api.structurely.com/v1/conversationWebhooks/<id>
URL Parameters
Parameter | Description |
---|---|
id | The ID of the conversation webhook to retrieve |
Update Conversation Webhook
curl 'https://api.structurely.com/v1/conversationWebhooks/5ceec43ce1b5b412ba9d0e73' \
-X PATCH \
-H 'X-Api-Authorization: myapikey' \
-H 'Content-Type: application/json' \
-d '{ "name": "My Cool Webhook", "target": "https://hooks.example.com/structurely/conversation_updated", "triggers": ["conversation:updated"] }'
The above command returns JSON structured like this:
{
"id": "5ceec43ce1b5b412ba9d0e73",
"name": "My Cool Webhook",
"target": "https://hooks.example.com/structurely/conversation_updated",
"secret": "nLjs7uu5AvQfTjqXpXHnSOfj0h8bvc0w0eeZNWgFR1pJo9Gb",
"version": "v1",
"triggers": ["conversation:updated"],
"updatedAt": "2019-05-29T12:41:16Z",
"createdAt": "2019-05-29T12:41:16Z"
}
HTTP Request
PATCH https://api.structurely.com/v1/conversationWebhooks/<id>
URL Parameters
Parameter | Description |
---|---|
id | The ID of the conversation webhook to update |
Body Parameters[^]
Parameter | Type |
---|---|
name | String |
target | String |
triggers | List<String> |
Delete Conversation Webhook
curl 'https://api.structurely.com/v1/conversationWebhooks/5ceec43ce1b5b412ba9d0e73' \
-X DELETE
-H 'X-Api-Authorization: myapikey'
The above command returns an empty response with the status 204 if successful
HTTP Request
DELETE https://api.structurely.com/v1/conversationWebhooks/<id>
URL Parameters
Parameter | Description |
---|---|
id | The ID of the conversation webhook to delete |
Errors
The Holmes API uses the following error codes:
Error Code | Meaning |
---|---|
400 | Bad Request -- Your request was invalid. |
401 | Unauthorized -- No API key provided. |
403 | Forbidden -- Your API key is invalid. |
404 | Not Found -- The specified resource could not be found. |
405 | Method Not Allowed -- You tried to access an endpoint with an invalid method. |
500 | Internal Server Error -- We had a problem with our server. Try again later. |
502 | Bad Gateway -- Our backend services are unavailable. Please try again later. |
503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later. |
504 | Gateway Timeout -- Our backend services are taking too long to respond. Please try again later. |