readyDocs Open the appOpen the app

Automations

Automations run steps when something happens: a reply, a new contact, a tag, or a call to your inbound webhook. Over the API you can create, change, turn on or off, copy and delete them, add contacts to one, and fire them from another system. Build automations covers the flow canvas, settings, tests, folders, templates and earlier versions; Automation runs and stats covers what they did. Every text an automation sends goes through the same opt-out, quiet hours and balance checks as any other text. Every route here needs the manage_campaigns permission unless it says otherwise. Test keys can read, but any change is refused with 403 test_key_not_allowed.

#The Automation object

List automations returns these. Create and update return the same object without triggers, folder_id, has_canvas and trigger_error.

idinteger
The automation id.
namestring
The automation’s name.
enabledinteger
1 (on) or 0 (off).
trigger_typestring
What starts it, such as inbound_webhook. On an automation with more than one trigger, this is only the first: read triggers.
trigger_configobject
The settings for that trigger.
triggersobject[] | null
When any of several triggers starts it: each one as { trigger_type, trigger_config }. null when it has one trigger.
actionsobject[]
Its steps.
folder_idinteger | null
The folder it is in, or null.
has_canvasboolean
true when it was saved from the flow canvas. Change its steps with PUT /automations/:id/graph.
trigger_errorboolean
true when its Google Sheets trigger is reporting an error. A rate limit doesn’t count.
last_fired_atISO 8601 string | null
When it last fired.
fire_countinteger
How many times it has fired.
created_atISO 8601 string
When it was created.
updated_atISO 8601 string
When it was last changed.

#List automations

Every automation on your account, newest first. Needs the manage_campaigns permission. Returns a list of Automation objects in data.

#Create an automation

Saves a new automation from a trigger and a list of steps. Leave out enabled and it starts on, so it can fire and send right away: send false to save it paused. To build from a flow graph instead, use POST /automations/from-graph, which saves paused unless you ask. Needs the manage_campaigns permission.

Parameters

namestringRequired
Up to 180 characters; a longer name is cut.
trigger_typestringRequired
What starts it, such as inbound_webhook, inbound_keyword, new_contact, contact_tagged or manual_enrollment.
trigger_configobject
The trigger’s settings, as List automations returns them. inbound_intent needs an intent; an inbound_keyword keyword can’t be an opt-out or opt-in word.
actionsobject[]
The steps, in the shape List automations returns, such as { "type": "send_sms", "body": "Hi {{contact.first_name}}" }. For a webhook step, see The Webhook step.
enabledboolean
true, 1 or absent is on; false, 0, "0" or "false" is off. Anything else is refused.
Idempotency-Keystring · header
Send one to retry safely: a repeat with the same key returns the first answer instead of a second automation.
Returns
dataobject
The new Automation object.
empty_mergeobject[] | null
Texts with a merge field that is blank for some of your newest contacts. A warning only: the automation was saved. A contact with a blank there is skipped when it runs.
Errors
HTTPCodeWhen
400NAME_REQUIREDNo name.
400TRIGGER_INVALIDNo trigger_type, one we don’t know, or settings it can’t use.
400TRIGGER_KEYWORD_RESERVEDA keyword is an opt-out or opt-in word.
400STEPS_INVALIDA step isn’t set up correctly. Other step codes, such as WEBHOOK_URL_INVALID or STEP_NOT_SUPPORTED, name the problem; error says what to fix.
400ENABLED_INVALIDenabled isn’t on or off.
500AUTOMATION_CREATE_UNCONFIRMEDWe couldn’t confirm it was saved. List your automations before you create it again.

#Update an automation

Changes only the fields you send. This is also how you turn an automation on or off: send { "enabled": true } or { "enabled": false }. Turning it off stops new runs. A run that is waiting in it is dropped if its wait ends while the automation is off. If has_canvas is true, change its steps with PUT /automations/:id/graph instead, so the canvas and the steps stay the same. Needs the manage_campaigns permission.

Parameters

idinteger, pathRequired
The automation id.
More parameters
namestring
A new name.
enabledboolean
On or off. null or "" is off.
trigger_typestring
A new trigger.
trigger_configobject
New trigger settings, checked against trigger_type (the new one if you send it).
actionsobject[]
The whole new list of steps.
folder_idinteger | null
Move it into one of your folders. null or 0 takes it out of its folder.
check_empty_mergeboolean
With enabled: true on an automation that is off: first check its texts for merge fields that are blank for some of your newest contacts. If any are, nothing is saved and you get 200 with success: false and needs_confirmation: "empty_merge_field". Send again with confirm_empty_merge: true to turn it on anyway.
Returns
dataobject
The saved Automation object.
empty_mergeobject[] | null
As on create, when you sent actions; an empty list otherwise.
Errors
HTTPCodeWhen
400NOTHING_TO_SAVEThe body changes nothing.
400NAME_REQUIREDA blank name.
400FOLDER_NOT_FOUNDNo folder with this id on your account.
400ACTIONS_UNREADABLEactions isn’t a list.
400TRIGGER_INVALIDAs on create. So are the step codes.
400ENABLED_INVALIDenabled isn’t on or off.
404AUTOMATION_NOT_FOUNDNo automation with this id on your account.
409AUTOMATION_UNFINISHEDYou turned on a canvas-built automation that isn’t finished: an If / else with an empty path, a step the trigger can’t reach, a keyword trigger with no keyword, or a template placeholder left in a text. Nothing in the request was saved and it stays off.
500AUTOMATION_UPDATE_FAILEDWe couldn’t save. Read it again to see what is saved, then retry.

#Delete an automation

Deletes it for good, with its earlier versions. Runs waiting in it end when their wait does, and a bulk add still in progress stops; nothing more is sent from it. Needs the manage_campaigns permission. Returns { "success": true }.

Parameters

idinteger, pathRequired
The automation id.
Errors
HTTPCodeWhen
404AUTOMATION_NOT_FOUNDNo automation with this id on your account, or it was already deleted.
500AUTOMATION_DELETE_FAILEDWe couldn’t delete it. Read it again before you retry.

#Copy an automation

Makes a copy named "name (copy)", with the same triggers, steps, canvas, folder and settings. The copy is always off. Needs the manage_campaigns permission. Takes an optional Idempotency-Key header, as on create.

Parameters

idinteger, pathRequired
The automation to copy.
Returns
dataobject
The copy, paused (enabled is 0), with its trigger_config and actions, in the same shape as Create an automation returns.
Errors
HTTPCodeWhen
404AUTOMATION_NOT_FOUNDNo automation with this id on your account.
500AUTOMATION_DUPLICATE_FAILEDWe couldn’t copy it. List your automations before you retry.

#Add a contact to an automation

Starts an automation for one contact right now, whatever its trigger. The automation must be on. Each text it sends costs your per-segment rate. Needs the manage_campaigns permission.

Parameters

idinteger, pathRequired
The automation id.
contact_idintegerRequired
The contact to start it for.
Returns
startedboolean
true when it started.
already_runningboolean
true when the contact is already in it. Nothing new started.
rule_idinteger
The automation id.
rule_namestring
The automation’s name.
contact_idinteger
The contact it started for.
Errors
HTTPCodeWhen
400CONTACT_REQUIREDNo contact_id.
402BILLING_PAST_DUEYour last payment failed. Update your card in Billing.
404AUTOMATION_NOT_FOUNDNo automation with this id on your account.
404CONTACT_NOT_FOUNDNo contact with this id on your account.
409AUTOMATION_PAUSEDIt’s off. Turn it on with Update an automation.
409NO_STEPSIt has no steps yet.
409AUTOMATION_ALREADY_ENTEREDThe contact already went through it, and it doesn’t let a contact enter twice.

#Add many contacts to an automation

Queues up to 50,000 contacts into an automation. Returns 202 and works through them in the background. Each text it sends costs your per-segment rate. Needs the manage_campaigns and edit_contacts permissions.

Parameters

idinteger, pathRequired
The automation id.
contact_idsinteger[]Required
Up to 50,000.
request_idstringRequired
Your id for this request, 16 to 100 letters, digits, _ or -. Sending it again returns the same job with replayed: true, so a retry never adds anyone twice.
Returns
data.job_idinteger
The background job.
data.totalinteger
Contacts queued.
data.rule_namestring
The automation’s name.
data.replayedboolean
true when this request_id was sent before and you got the same job back.
Errors
HTTPCodeWhen
400BAD_SELECTIONNo contacts, or more than 50,000.
400BAD_REQUEST_IDA bad request_id.
400NO_CONSENTNo consent_attested: true. error_code is attestation_required, as on campaigns.
402BILLING_PAST_DUEThe account is past due.
404RULE_MISSINGNo automation with this id on your account. error_code is AUTOMATION_NOT_FOUND, as on a single enroll.
409RULE_PAUSEDThe automation is off. error_code is AUTOMATION_PAUSED, as on a single enroll.
409RULE_EMPTYThe automation has no steps. error_code is NO_STEPS, as on a single enroll.
409IN_FLIGHTThis request_id is still being started. Retry the same request_id in a few seconds. If you got 503 ENROLL_QUEUE_FAILED for it before, it will never start: see that row.
409OTHER_SELECTIONThis request_id was used for other contacts. Use a new request_id.
409CONTACTS_GONESome contacts were deleted.
429rate_limitedToo many requests. Wait and retry.
503ENROLL_QUEUE_FAILEDThe enrollment could not be started safely, and no contacts were added. Retry once with the same request_id. If that answers 409 IN_FLIGHT, the first try stopped after its job was made and that request_id can’t be used again: send the same contacts with a new request_id.

#Get your inbound webhook

Your account’s inbound webhook address. Any automation with the Inbound webhook trigger runs when something posts to it. Needs the manage_campaigns permission.

Returns
urlstring
Post to this. Keep it secret: anyone with it can fire your automations.
tokenstring
The last part of url.

#Fire your inbound webhook

Runs your Inbound webhook automations. Point a form, CRM or Zapier here. No API key: the token in the address is the key. Each text it sends costs your per-segment rate.

Parameters

tokenstring, pathRequired
From GET /automations/inbound-webhook.
More parameters
phonestring
The person this is about. We find the contact by number, or create one.
first_namestring
Used when we create the contact. firstName works too.
last_namestring
Used when we create the contact. lastName works too.
emailstring
Used when we create the contact.
contact_idinteger
Or an existing contact’s id.
any other fieldany
Passed to the automation, so its steps and conditions can use it.
Returns
firedboolean
true when the event was handed to your Inbound webhook automations. It does not mean one ran.
contact_idinteger | null
The contact it ran for.
duplicateboolean
The same body posted twice within 60 seconds runs once; the second answers duplicate: true.
Errors
HTTPCodeWhen
404WEBHOOK_UNKNOWNUnknown token. It may have been changed.
429no codeMore than 60 calls in a minute to this address.

#Change your inbound webhook

Replaces the address, for example after it leaked. The old one stops working right away, so update every system that uses it. Needs the manage_campaigns permission.

Returns
urlstring
The new address.
tokenstring
The last part of the new url.
Errors
HTTPCodeWhen
409INBOUND_WEBHOOK_CLOSE_CONNECTEDClose is connected to this address. Disconnect Close first.

#Check for a Webhook step

Whether any automation that is on has a Webhook step, so Send a lead to your webhook has somewhere to post. Needs the manage_campaigns permission.

Returns
availableboolean
true when at least one turned-on automation has a Webhook step.

#Send a lead to your webhook

Hands a conversation to your CRM by hand. We pick the turned-on automation with a Webhook step that best fits this contact (its phone line and tag filters; one that requires a tag wins over a catch-all) and run only its Webhook steps, with the contact’s latest text as the event. No other step runs and no text is sent. Every call posts again, so call it once per lead. Needs the manage_campaigns permission.

Parameters

conversation_idinteger
The conversation. Send this or contact_id.
contact_idinteger
Or the contact.
Returns
rule_namestring
The automation whose Webhook steps ran.
captured_lead_idstring | null
The lead id a Shape CRM post answered with, when we stored it. null for any other webhook.
Errors
HTTPCodeWhen
400INVALID_IDNeither id, or one that isn’t a whole number.
400NO_MATCHING_WEBHOOKNo turned-on automation with a Webhook step fits this contact.
402BILLING_PAST_DUEThe account is past due.
404NO_INBOUND_MESSAGEThe contact hasn’t texted you yet, so there is no lead to send.
429rate_limitedToo many requests. Wait and retry.
502WEBHOOK_REJECTEDYour webhook answered with an error. rule_name says which automation.
502WEBHOOK_URL_INVALIDThe Webhook step’s address isn’t valid.
502WEBHOOK_NOT_SENTThe Webhook step isn’t fully set up, so nothing was posted.
502WEBHOOK_OUTCOME_UNKNOWNYour webhook didn’t answer. The lead may have arrived: check your CRM before you send it again.
503WEBHOOK_CONTACT_UNREADABLEWe couldn’t read the contact, so nothing was posted. Retry in a minute.
500SEND_TO_WEBHOOK_FAILEDNothing was sent. Retry in a minute.

#The Webhook step

The Webhook step calls any web API from an automation. Method picks GET, POST, PUT, PATCH or DELETE (GET and DELETE send no data). Headers adds your own, such as Authorization with Bearer your_token; the names Host, Content-Length, Connection, Transfer-Encoding and Cookie are not allowed. Send only these fields sends just the fields you list, with none of Ready’s contact details around them. Without it, the post carries the event, its data, the contact (name, email, phone, address, tags, score, status), the assigned team member’s name and email, and notes: the last 50 texts with this contact, both directions, in full. For example, to add a message in GoHighLevel, POST to https://services.leadconnectorhq.com/conversations/messages/inbound with the headers Authorization: Bearer your_token and Version: 2021-04-15, tick Send only these fields, and add type = SMS, contactId and message = {{last_reply}}.

Without Send only these fields, the JSON body has these fields. Any extra field you add to the step is set last, so it replaces a field of the same name.

eventstring
The event that started the run.
dataobject
The event’s data, such as the fields posted to your inbound webhook. Keys that start with __ are left out.
contactobject | null
The contact: contact_first_name, contact_last_name, contact_full_name, contact_email, contact_phone, contact_company, the address fields (contact_address1, contact_address2, contact_city, contact_state, contact_postal_code, contact_country), contact_score, contact_pipeline_stage, contact_status, contact_source, contact_tags (a list) and contact_tags_csv, plus these extra keys, named the way one CRM (Shape) expects its fields: firstname, lastname, leadfullname, phone, email, refconcompanyname, address2, city, state, zip, leadfulladdress and leadtags. Most repeat a contact_* value, but address2 carries the street line (contact_address1), not contact_address2. null when the run has no contact.
assigneeobject | null
The team member the contact is assigned to: assigned_to_id, assigned_to_email, assigned_to_first_name, assigned_to_last_name and assigned_to_name, with the email and name repeated as assignee_email, assignee_name, agent_email and agent_name, plus assignedUserId, shapeUserId and depursAE, which are null unless your CRM routes leads by rep. null when nobody is assigned.
notesstring | null
The last 50 texts with the contact, oldest first, one per line, like [2026-10-15 18:22] IN : Yes please. The times are UTC, not the account’s time zone. null when there are none.
rule_idinteger
The automation id.
fired_atISO 8601 string
When the step posted.