How it works
- Trigger — POST a request to
/ai_outbound/requestsidentifying the client bycontact_number(required, optionally withclient_id) and thepurposeof the outreach. - Synchronous intake — Oliver validates the input, resolves the client, and runs suppression checks before responding. A queued request returns
201; a suppressed request returns200with asuppression_reason. - Asynchronous dispatch — Oliver composes an opener and starts the conversation. The request moves through
queued→in_progress. - Outcome — when the conversation resolves, the request reaches a terminal status (
completed,suppressed, orfailed). If you supplied acallback_url, Oliver delivers exactly one outcome webhook — on any of the three terminal statuses, not only when anoutcomeis set. The outcome is also available anytime viaGET /ai_outbound/requests/{id}.
initial_message_script if you send one, otherwise Oliver writes it from the purpose, context and patients.
Rich openers (RCS)
Addcontent to open with a card, carousel, image or reply buttons. It takes the same shape and limits as the messages endpoint. See Writing card text for layouts that work on a phone. Clients whose phone supports RCS see the rich message, with the practice’s name, logo and verified badge. Everyone else gets the plain-text opener as an SMS. Either way, every reply, including a tap on a reply button, goes to Oliver’s AI, which carries on the conversation and books the visit.
A service reminder for two pets, where a tap on Let’s find a time starts booking:

On iPhone. The practice's opt-out line follows the description.
patientstells the AI which pets the outreach is about and what each is due for, so one message covers the household.initial_message_scriptis the plain text: the SMS for phones without RCS, and the bubble ofcontent.type: "text". Leave it out and Oliver writes it, so you can send only reply buttons and let Oliver write the line.opener_channelon the request and the outcome webhook says how the opener arrived:rcsorsms.- The clinic’s opt-out line is added to the plain text and to the card’s description.
media_idis an image you uploaded to Oliver; a hostedmedia_urlworks too. The opener keeps the image it had when Oliver accepted the request, even if you replace the file before the text goes out.
Messages or AI Outbound?
Use Messages for announcements and anything staff should answer. Use AI Outbound when you want the client’s reply to become a booking.
Purposes
Statuses
A request moves through a linear lifecycle:received → queued → in_progress → one of completed, suppressed, failed
When a request is completed, its outcome is one of booked, opted_out, or no_response. A failed request carries undeliverable when the text bounced at the carrier, and a null outcome with an error_message when dispatch never completed. A suppressed request has no outcome — it has a suppression_reason.
Timing
Suppression
Suppression is a normal, auditable outcome — not an error. Oliver will suppress a request when contacting the client would be inappropriate, for example:recent_contact— Oliver already contacted the client (by SMS or AI phone call, from any campaign) within the last 72 hours.active_conversation— there is already an open AI conversation with the client.sms_opted_out— the client has opted out of SMS.voice_not_supported— thevoicechannel is not yet available.
200 with the suppression_reason on the response. Eligibility is also re-checked just before the message is sent, so a request accepted with 201 can still end up suppressed — see the outcome webhook for the full list of reasons.
Idempotency
Setpartner_request_id to a unique value per logical request. Re-submitting the same partner_request_id returns the existing request rather than creating a duplicate, so retries are safe.
Rate limits
Each practice is limited to 120 requests per minute. Exceeding the limit returns429 Too Many Requests.
