NAV
curl

Introduction

Welcome to the Structurely API!

These endpoints are used by partners to embed Structurely within your offering.

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. To get an API key please contact us.

Overview

You can configure Live Transfer to enable the AI to automatically bridge the gap between the Conversational AI and Voice. When the AI detects the lead needs to be on a phone call, it will POST a request to the liveTransferUrl. This enables your systems to broker a call between an Agent and the Lead.

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})

Conversations

The Conversation API is a resource, that represents a conversational exchange with Structurely. This resource allows you to interface your CRM directly with Structurely.

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", "liveTransferUrl": "https://your-domain/api/structurely-live-transfer-start/leadId" }, "slots": [{ "name": "email", "value": "jdoe@example.com" }, { "name": "lead_type", "value": "buyer" }, { "name": "lead_type", "value": "seller" }, { "name": "external_lead_id", "value": "63dae72910b57fd51d0d9652"}], "messages": []}'

The above command returns JSON structured like this:

{
    "id": "5c09a4416241ea2c293275b8",
    "settings": {
        "chatbotName": "Aisa",
        "timeZone": "America/Chicago",
        "activateGenerativeAi": true,
        "liveTransferUrl": "https://your-domain/api/structurely-live-transfer-start/leadId"
    },
    "slots": [
        {
            "name": "email",
            "value": "jdoe@example.com"
        },
        {
            "name": "lead_type",
            "value": "buyer"
        },
        {
            "name": "lead_type",
            "value": "seller"
        }
    ],
    "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>

Extra slots for tracking

Set these optional slots to facilitate reporting and querying of conversations using IDs in your own system. Store these optional IDs by sending them as slots with string values. These IDs are persisted internally but not emitted as slots when conversations are retrieved over the API.

Slot Name Purpose
external_account_id Associate this conversation to its account's ID
external_team_id Associate this conversation to its team's ID
external_user_id Associate this conversation to its user's ID
external_lead_id Associate this conversation to its lead's ID

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": {
        "chatbotName": "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_type",
            "value": "buyer"
        },
        {
            "name": "lead_type",
            "value": "seller"
        }
    ],
    "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

Response Body[^]

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": {
        "chatbotName": "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 Description
muted Boolean Once muted, a conversation can still receive messages but will no longer generate replies. It is not possible to unmute a conversation.

Response Body[^]

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 create a message for

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 create a message for

Body Parameters[^]

Parameter Type
_metadata MessageMetaData
text String
received DateTime

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 to use for 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 whether or not this conversation is muted. Once muted, a conversation can still receive messages but will no longer generate replies. It is not possible to unmute a conversation. 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
chatbotName 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, Structurely 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 No false
reDripsEnabled Boolean If set to true, Structurely 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 No false
activateGenerativeAi Boolean If set to true, Structurely will use Generative AI to enhance scripted responses, which results in better conversations and lower carrier filtering. Yes No No false
liveTransferUrl URL Enables Live Transfer, must be a valid URL using https:// Yes No No undefined
liveTransferStatusUpdateUrl URL Sends Live Transfer status reports, must be a valid URL using https:// Yes No No undefined

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]
  1. message and response are mutually exclusive. At least one is required to be present but not both.
  2. context is only required if the response 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
  1. _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 Structurely 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.
email 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 Structurely 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 Structurely is messaging on the behalf of.
office_location String The general location of the realtor office the system is representing.
Slots for Tracking Purposes
external_account_id String Associate this conversation to its account's ID
external_team_id String Associate this conversation to its team's ID
external_user_id String Associate this conversation to its user's ID
external_lead_id String Associate this conversation to its lead's ID
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".

Live Transfer

Live Transfer is in early access beta, there are no restrictions on it's use, but the API may change as we learn how Live Transfer is used by each of our partners.

When Conversations have Live Transfer enabled, the AI is allowed to make live callbacks into a partner's system, when it detects that a Lead needs to be on the phone. This feature is enabled by setting the following fields on ConversationSettings, when creating a conversation.

Live Transfer Control Flow

When a Live Transfer is initiated, the AI will POST a LiveTransferRequest to the configured liveTransferUrl.

// LiveTransferRequest (AI POST to liveTransferUrl)
{
    "conversation_id": "9515a0c8aea973407292bebe",
    "intent_name": "unknown_question",
    "intent_slots": {},
    "all_slots": {
        "context": [
            "expect_listing_appointment"
        ],
        "day_of_week": [
            "Thursday"
        ],
        "name": [
            "John Doe"
        ],
        "email": [
            "john.doe@gmail.com"
        ],
        "phone": [
            "+5555555555"
        ],
        "live_transfer_url": [
            "https://your-internal-domain/{your-lead-id}/live-transfer-start"
        ],
        "live_transfer_status_update_url": [
            "https://your-internal-domain/{your-lead-id}/live-transfer-status"
        ],
    }
}

The recieving system must respond in a timely manner. At a high level this controller's responsibility is to detect if a call is possible, initiate that call, and then respond to the AI. Future work will enable a partner to POST a transcription and recording at call completion, enabling the AI to set slots and intents, thus closing the circle between the Voice Call and the Conversational AI.

The response to this API request must be a HTTP 200 with a JSON body that conforms to the LiveTransferResponse schema, this response's slot settings indicate to the AI that a call was started (or not).

There are a wide set of states that a call could end up in, the response schema allows the endpoint to respond appropriately. Live Transfer requests generally end up in three buckets:

  1. Attempt to start call was successful.
  2. Attempt to start call was not successful, future (modeled but not active) retry the live transfer after a specified delay.
  3. Some pre-condition was not met, send a response to the lead.
// LiveTransferResponse (partner response to AI)
{
    "slots": {
        "live_transfer_call_id": "7915a28266d24462457cd8d6",
        "live_transfer_started": "2023-09-28T15:57:55.535370Z",
        "live_transfer_agent_name": "Jane Seller",
    }
}

Success paths set live_transfer_call_id, failure paths set live_transfer_disposition. Experimental It is also possible to populate a list of responses that will be recorded on the conversation and sent via webhook back into your system.

Finally if a liveTransferStatusUpdateUrl was configured, the AI will respond with status updates using the LiveTransferStatus payload.

// LiveTransferStatus (AI POST to liveTransferStatusUpdateUrl)
{
    "conversation_id": "9515a0c8aea973407292bebe",
    "event": "live-transfer:started",
    "payload": {
        "intent_name": "unknown_question",
        "intent_slots": {},
        "all_slots": {
            "context": [
                "expect_listing_appointment"
            ],
            "day_of_week": [
                "Thursday"
            ],
            "name": [
                "John Doe"
            ],
            "email": [
                "john.doe@gmail.com"
            ],
            "phone": [
                "+5555555555"
            ],
            "live_transfer_url": [
                "https://your-internal-domain/{your-lead-id}/live-transfer-start"
            ],
            "live_transfer_status_update_url": [
                "https://your-internal-domain/{your-lead-id}/live-transfer-status"
            ],
            "live_transfer_started": [
                "2023-09-28T15:57:55.535370Z"
            ],
            "live_transfer_agent_name": [
                "Jane Seller"
            ],
            "live_transfer_call_id": [
                "7915a28266d24462457cd8d6"
            ]
        }
    }
}

Schema

LiveTransferRequest

This payload will be sent to the liveTransferUrl as a POST JSON body.

Field Type Description Required
conversation_id ObjectId The unique ID for this conversation Yes
intent_name String The name of the intent that triggered the transfer (only populated when triggered by an intent) No
intent_slots Map[String, Array[String]] A map of slots tied to the intent, (only populated when triggered by an intent) No
all_slots Map[String, Array[String]] A map of all slots in this conversation Yes

LiveTransferResponse

This payload will be sent as the response body (JSON encoded) for the LiveTransferRequest.

Field Type Description Required
slots LiveTransferResponseSlots Slots configuring how brain should respond to the live transfer Yes
responses Array[Message] Experimental Optional list of responses to send No

LiveTransferResponseSlots

Field Type Description Required
live_transfer_call_id String Used to indicate success, the unique ID of the created call. Will be used by CallAI Future to correlate call analysis with Live Transfer. No
live_transfer_started DateTime ISO 8601 Timezone aware datetime string for the start time for this call, will be defaulted to system time if not set No
live_transfer_agent_name String Track a slot for who the lead was connected to, can be used in future responses from the AI No
live_transfer_disposition String Used to indicate a failure mode, do not set this on success No
live_transfer_retry_delay Number Experimental Used during a failure mode, trigger the AI to retry this live transfer after a configureable time period (seconds) No

LiveTransferStatus

Field Type Description Required
conversation_id ObjectId The unique ID for this conversation Yes
event String The type of event update Yes
payload LiveTransferRequest The current state of the live transfer request Yes

Conversation Webhooks

The Conversation Webhook is resource, that 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.
  1. value and values are mutually exclusive. Only one will exist at a time and the other will be undefined.
  2. 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 Structurely 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 Structurely 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
  1. The sort string allows multiple fields with left to right precedence with optional - or + for controlling ascending and descending order
  2. 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 Structurely 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.