Skip to main content
The AI Outbound API lets a partner ask Oliver to reach out to a specific client on the practice’s behalf. Oliver’s AI handles the conversation — today over SMS — for a given purpose such as booking an appointment or a prescription refill follow-up.

How it works

  1. Trigger — POST a request to /ai_outbound/requests identifying the client by contact_number (required, optionally with client_id) and the purpose of the outreach.
  2. Synchronous intake — Oliver validates the input, resolves the client, and runs suppression checks before responding. A queued request returns 201; a suppressed request returns 200 with a suppression_reason.
  3. Asynchronous dispatch — Oliver composes an opener and starts the conversation. The request moves through queuedin_progress.
  4. Outcome — when the conversation resolves, the request reaches a terminal status (completed, suppressed, or failed). If you supplied a callback_url, Oliver delivers exactly one outcome webhook — on any of the three terminal statuses, not only when an outcome is set. The outcome is also available anytime via GET /ai_outbound/requests/{id}.
Outreach is a single AI-composed opener followed by a reply-driven conversation — Oliver sends no automated follow-up texts.

Purposes

Statuses

A request moves through a linear lifecycle: receivedqueuedin_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 — the voice channel is not yet available.
Suppression detected at intake returns 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

Set partner_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 returns 429 Too Many Requests.