Place an outbound bot call
PLACES A REAL PHONE CALL. Dials `phoneNumber` with the bot `botId` NOW — there is no scheduling, no retry ladder and no confirmation step; the partner owns the timing. Calls are only placed between 08:00 and 20:00 in the tenant’s timezone (`OUTSIDE_CALL_WINDOW` otherwise, window echoed in `details`); nothing is queued. `idempotencyKey` is REQUIRED and is what makes a retry safe: the same key never dials twice — a replay returns the existing session with **200** instead of **201**, and the same key with a different bot or number is refused with `IDEMPOTENCY_KEY_REUSED`. The key is consumed the moment the dispatcher accepts the request — even if the call then fails before anyone picks up (`FAILED` when the call never connects, `no_answer`, `voicemail`): a replay returns that session and never re-dials, so calling the same person again needs a NEW key. Every dispatcher-side error carries `details.dispatchId`. Use your own message or notification id. Requires the opt-in scope `bot-calls.write` (no wildcard grants it). The bot needs an outbound phone number (`BOT_NO_OUTBOUND_NUMBER`) and a published configuration (`BOT_NOT_PUBLISHED`); check `GET /bots/{botId}/readiness` → `readyForOutbound`. `context` is rendered into the bot’s prompt, greeting and workflow as `{{reason}}`, `{{message}}`, `{{appointment_date}}`, `{{appointment_time}}`, `{{appointment_doctor_name}}` (from `appointment.staffName`, or its medical alias `doctorName`), `{{appointment_service_name}}`, `{{appointment_location_name}}`, `{{appointment_address}}`, `{{appointment_external_id}}` plus `variables` verbatim; reserved names are refused as a `422 VALIDATION_ERROR` on `context.variables.<name>`. The bot must be switched on (`BOT_INACTIVE` otherwise). The response is the session as accepted by the dispatcher, still `IN_PROGRESS`: the outcome arrives on the `bot_call.completed` webhook (status completed / no_answer / voicemail / failed / stuck, `durationSec`, `outcome`, `links`) and on `GET /bot-sessions/{dispatchId}`. Mid-call actions (reschedule, cancel) are the bot’s own tools, configured on the bot. Sessions placed this way carry `attemptId` `ext-<dispatchId>`. Required scope: `bot-calls.write`.
/bot-sessionsAuthorization
ApiKeyAuth An external API key, sent as Authorization: Bearer mflo_…. Scopes are checked per route; see each operation’s description.
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/bot-sessions" \ -H "Content-Type: application/json" \ -d '{ "botId": "58ed41f0-04bf-402f-9853-7143ef7dd5ce", "phoneNumber": "string", "idempotencyKey": "string", "context": { "reason": "string" } }'{ "data": { "dispatchId": "a1a7028f-f483-4bbb-b8e5-fe878bddb1ae", "botId": "58ed41f0-04bf-402f-9853-7143ef7dd5ce", "botName": "string", "status": "IN_PROGRESS", "endReason": "string", "startedAt": "2019-08-24T14:15:22Z", "endedAt": "2019-08-24T14:15:22Z", "durationSec": 0, "phoneNumber": "string", "attemptId": "string", "hasTranscript": true, "hasRecording": true, "hasTelemetry": true, "outcome": { "property1": null, "property2": null }, "links": { "telemetry": "string", "transcript": "string", "recording": "string" } }}List bot sessions GET
A bot session is one dispatch of one bot to one number — NOT a telephony call record. `status` filters on the same derived status the response reports. Required scope: `bot-calls.read`.
Check whether a bot can take calls GET
A checklist assembled from the publish and dispatch preconditions, for the bot’s channels. Three verdicts: `ready` (can serve at all; a chat-only bot also needs its widget), `readyForOutbound` (serves VOICE_OUTBOUND and the phone chain is dispatchable — a chat-only bot is legitimately false; do not bind a number) and `readyForWebChat` (serves WEB_CHAT and the chat widget is bound). `chat_widget_bound` is fixed in the Portal (Settings → Chat widget). When website chat has booking on, `web_chat_booking_widget` and `web_chat_booking_sms` report WEB_CHAT_BOOKING_WIDGET_MISSING and WEB_CHAT_BOOKING_SMS_MISSING; they are informational. `phone_number_attached` verifies the WHOLE outbound chain and is flagged `requiredFor: outbound` only when the bot places calls. `operating_hours_configured`, `workflow_active` and `location_set` are informational. `ai_disclosure` is an informational ADVISORY: it sweeps the prompt, greeting and active workflow for wording that tells the person they are talking to an AI (EU AI Act Article 50). It is a Polish/English keyword heuristic, so `ok: false` means "we could not find one, please confirm" — not a compliance finding. The obligation and the wording belong to the operator; Mediflo neither enforces nor verifies them, and this check never affects any verdict. Required scope: `bots.read`.