Exotel Campaigns API
Create, list, get, update (pause/resume), and delete bulk outbound call campaigns under the v2 API (POST/GET/PUT/DELETE /v2/accounts/{sid}/campaigns), and pull per-call records via campaigns/{id}/call-details.
Create, list, get, update (pause/resume), and delete bulk outbound call campaigns under the v2 API (POST/GET/PUT/DELETE /v2/accounts/{sid}/campaigns), and pull per-call records via campaigns/{id}/call-details.
openapi: 3.0.3
info:
title: Exotel API
description: >-
Exotel is an Indian cloud telephony and customer-engagement (CPaaS)
platform. This OpenAPI describes a representative, grounded subset of
Exotel's documented public REST API: placing outbound voice calls
(connect two numbers, or connect a number to a call flow / applet),
sending SMS, retrieving call details, looking up phone-number metadata,
and managing call campaigns.
Base URL is region-specific and Twilio-style:
`https://<subdomain>/v1/Accounts/<account_sid>/...` for the v1 telephony
APIs and `https://<subdomain>/v2/accounts/<account_sid>/...` for the v2
Campaigns API. All requests use HTTP Basic authentication with your API
Key as the username and API Token as the password (credentials may also
be embedded in the URL as `https://<key>:<token>@<subdomain>/...`).
GROUNDING NOTE: Endpoint paths and HTTP methods for Calls/connect,
Calls/{CallSid}, Numbers/{Number}, Sms/send, and the v2 Campaigns
resource are confirmed from Exotel's developer docs. Request/response
SCHEMAS below are MODELED from the documented parameter lists and
Exotel's Twilio-style conventions - Exotel does not publish a machine
OpenAPI, so field-level schemas should be verified against the live docs
before production use. Exotel APIs return XML by default; append `.json`
to a resource path to receive JSON (shown here as the JSON variants).
version: '1.0'
contact:
name: Exotel Developer Support
url: https://developer.exotel.com
x-grounding:
confirmedEndpoints:
- POST /v1/Accounts/{sid}/Calls/connect
- GET /v1/Accounts/{sid}/Calls/{CallSid}
- GET /v1/Accounts/{sid}/Numbers/{Number}
- POST /v1/Accounts/{sid}/Sms/send
- POST /v2/accounts/{sid}/campaigns
- GET /v2/accounts/{sid}/campaigns/{campaign_id}
- GET /v2/accounts/{sid}/campaigns/{campaign_id}/call-details
modeledEndpoints:
- GET /v1/Accounts/{sid}/Calls (bulk list; documented as existing, path follows Exotel convention)
- GET /v1/Accounts/{sid}/Sms/Messages/{SmsSid} (SMS details; documented as existing, path follows Exotel convention)
schemaStatus: >-
All request/response body and form-field schemas are modeled from
documented parameter lists, not from a vendor-published OpenAPI.
servers:
- url: https://api.exotel.com
description: Singapore cluster (default)
- url: https://api.in.exotel.com
description: Mumbai / India cluster
security:
- basicAuth: []
tags:
- name: Voice
description: Place and control outbound voice calls.
- name: Call Details
description: Retrieve details of past and in-progress calls.
- name: SMS
description: Send SMS and retrieve message details.
- name: Numbers
description: Look up telecom metadata for phone numbers.
- name: Campaigns
description: Create and manage bulk outbound call campaigns (v2).
paths:
/v1/Accounts/{sid}/Calls/connect.json:
parameters:
- $ref: '#/components/parameters/AccountSid'
post:
operationId: connectCall
tags:
- Voice
summary: Connect two numbers or connect a number to a call flow
description: >-
Places an outbound call. In the "connect two numbers" mode, Exotel
first calls `From`, and when answered connects to `To`. In the
"connect to a flow" mode, provide `Url` pointing to an Exotel call
flow (App/applet, e.g.
`http://my.exotel.com/{sid}/exoml/start_voice/{flow_id}`) instead of
`To`. Confirmed endpoint; body schema modeled from documented
form parameters.
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/ConnectCallRequest'
responses:
'200':
description: Call queued/initiated.
content:
application/json:
schema:
$ref: '#/components/schemas/CallResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/Accounts/{sid}/Calls/{CallSid}.json:
parameters:
- $ref: '#/components/parameters/AccountSid'
- name: CallSid
in: path
required: true
description: The unique Sid of the call to retrieve.
schema:
type: string
get:
operationId: getCallDetails
tags:
- Call Details
summary: Get details of a single call
description: >-
Retrieves details (status, direction, duration, price, recording
URL) for a call by its Sid. Confirmed endpoint; response schema
modeled.
responses:
'200':
description: Call details.
content:
application/json:
schema:
$ref: '#/components/schemas/CallResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/v1/Accounts/{sid}/Calls.json:
parameters:
- $ref: '#/components/parameters/AccountSid'
get:
operationId: listCalls
tags:
- Call Details
summary: List / bulk-query calls
description: >-
Lists calls for the account, filterable by date and status. MODELED
path - Exotel documents bulk call queries, and this path follows
Exotel's Twilio-style convention; verify against live docs.
parameters:
- name: DateCreated
in: query
required: false
description: Filter by creation date (YYYY-MM-DD).
schema:
type: string
- name: Status
in: query
required: false
schema:
type: string
enum: [queued, in-progress, completed, failed, busy, no-answer]
responses:
'200':
description: A page of call records.
content:
application/json:
schema:
type: object
properties:
Calls:
type: array
items:
$ref: '#/components/schemas/CallResponse'
'401':
$ref: '#/components/responses/Unauthorized'
/v1/Accounts/{sid}/Sms/send.json:
parameters:
- $ref: '#/components/parameters/AccountSid'
post:
operationId: sendSms
tags:
- SMS
summary: Send an SMS
description: >-
Sends a single SMS from an ExoPhone or approved Sender ID. India
traffic requires DLT registration IDs. Confirmed endpoint; body
schema modeled from documented parameters.
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/SendSmsRequest'
responses:
'200':
description: SMS accepted.
content:
application/json:
schema:
$ref: '#/components/schemas/SmsResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'429':
$ref: '#/components/responses/TooManyRequests'
/v1/Accounts/{sid}/Sms/Messages/{SmsSid}.json:
parameters:
- $ref: '#/components/parameters/AccountSid'
- name: SmsSid
in: path
required: true
description: The unique Sid of the SMS message.
schema:
type: string
get:
operationId: getSmsDetails
tags:
- SMS
summary: Get SMS details
description: >-
Retrieves the delivery status and metadata of a sent SMS. MODELED
path following Exotel's Twilio-style convention; verify against live
docs.
responses:
'200':
description: SMS details.
content:
application/json:
schema:
$ref: '#/components/schemas/SmsResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/v1/Accounts/{sid}/Numbers/{Number}.json:
parameters:
- $ref: '#/components/parameters/AccountSid'
- name: Number
in: path
required: true
description: The phone number (E.164) to look up.
schema:
type: string
get:
operationId: getNumberMetadata
tags:
- Numbers
summary: Get phone-number metadata
description: >-
Returns telecom metadata (operator/circle, number type, DND status
where available) for an Indian phone number. Confirmed endpoint;
response schema modeled.
responses:
'200':
description: Number metadata.
content:
application/json:
schema:
$ref: '#/components/schemas/NumberMetadata'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/v2/accounts/{sid}/campaigns:
parameters:
- $ref: '#/components/parameters/AccountSid'
get:
operationId: listCampaigns
tags:
- Campaigns
summary: List campaigns
description: Lists call campaigns for the account. Confirmed v2 resource; schema modeled.
responses:
'200':
description: A list of campaigns.
content:
application/json:
schema:
type: object
properties:
response:
type: array
items:
$ref: '#/components/schemas/Campaign'
'401':
$ref: '#/components/responses/Unauthorized'
post:
operationId: createCampaign
tags:
- Campaigns
summary: Create a campaign
description: >-
Creates a new outbound call campaign against a list of numbers and a
call flow / caller ID. Confirmed endpoint; body schema modeled.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CampaignInput'
responses:
'200':
description: Campaign created.
content:
application/json:
schema:
$ref: '#/components/schemas/Campaign'
'401':
$ref: '#/components/responses/Unauthorized'
/v2/accounts/{sid}/campaigns/{campaign_id}:
parameters:
- $ref: '#/components/parameters/AccountSid'
- name: campaign_id
in: path
required: true
schema:
type: string
get:
operationId: getCampaign
tags:
- Campaigns
summary: Get a campaign
description: Retrieves a single campaign's configuration and status. Confirmed endpoint; schema modeled.
responses:
'200':
description: Campaign details.
content:
application/json:
schema:
$ref: '#/components/schemas/Campaign'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
put:
operationId: updateCampaign
tags:
- Campaigns
summary: Update / pause / resume a campaign
description: Updates campaign configuration or state (e.g. pause, resume). Confirmed endpoint; schema modeled.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CampaignInput'
responses:
'200':
description: Campaign updated.
content:
application/json:
schema:
$ref: '#/components/schemas/Campaign'
'401':
$ref: '#/components/responses/Unauthorized'
delete:
operationId: deleteCampaign
tags:
- Campaigns
summary: Delete a campaign
description: Deletes a campaign. Confirmed endpoint.
responses:
'200':
description: Campaign deleted.
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/v2/accounts/{sid}/campaigns/{campaign_id}/call-details:
parameters:
- $ref: '#/components/parameters/AccountSid'
- name: campaign_id
in: path
required: true
schema:
type: string
get:
operationId: getCampaignCallDetails
tags:
- Campaigns
summary: Get campaign call details
description: Retrieves per-call records for a campaign. Confirmed endpoint; schema modeled.
responses:
'200':
description: Campaign call records.
content:
application/json:
schema:
type: object
properties:
response:
type: array
items:
$ref: '#/components/schemas/CallResponse'
'401':
$ref: '#/components/responses/Unauthorized'
components:
securitySchemes:
basicAuth:
type: http
scheme: basic
description: >-
HTTP Basic authentication. Username = API Key, Password = API Token
(both from Exotel Dashboard -> Settings -> API Settings). May also be
embedded in the URL as https://<key>:<token>@<subdomain>/...
parameters:
AccountSid:
name: sid
in: path
required: true
description: Your Exotel account Sid (Account SID).
schema:
type: string
responses:
Unauthorized:
description: Missing or invalid API Key/Token.
NotFound:
description: Resource not found.
TooManyRequests:
description: Rate limit exceeded (Voice APIs are limited to ~200 calls/minute).
schemas:
ConnectCallRequest:
type: object
required:
- From
- CallerId
properties:
From:
type: string
description: The number Exotel calls first (E.164 preferred).
To:
type: string
description: The number to connect to. Use this OR Url.
Url:
type: string
description: >-
An Exotel call-flow URL to connect the call to instead of a
second number, e.g. http://my.exotel.com/{sid}/exoml/start_voice/{flow_id}.
CallerId:
type: string
description: Your ExoPhone / virtual number shown as caller ID.
CallType:
type: string
enum: [trans, promo]
description: Call type classification.
TimeLimit:
type: integer
description: Max call duration in seconds (up to 14400).
TimeOut:
type: integer
description: Ring timeout in seconds.
WaitUrl:
type: string
description: Audio URL to play while the callee is being connected.
Record:
type: boolean
description: Whether to record the call.
StatusCallback:
type: string
description: Webhook URL called on call state changes.
StatusCallbackEvents:
type: array
items:
type: string
enum: [terminal, answered]
CustomField:
type: string
CallResponse:
type: object
properties:
Sid:
type: string
AccountSid:
type: string
Status:
type: string
enum: [queued, in-progress, completed, failed, busy, no-answer]
From:
type: string
To:
type: string
PhoneNumberSid:
type: string
description: The ExoPhone / virtual number used.
Direction:
type: string
Duration:
type: integer
Price:
type: string
RecordingUrl:
type: string
DateCreated:
type: string
SendSmsRequest:
type: object
required:
- From
- To
- Body
properties:
From:
type: string
description: ExoPhone or approved Sender ID.
To:
type: string
description: Recipient mobile number (E.164 preferred).
Body:
type: string
description: Message content (up to 2000 characters).
EncodingType:
type: string
enum: [plain, unicode]
SmsType:
type: string
enum: [transactional, transactional_opt_in, promotional]
Priority:
type: string
enum: [normal, high]
DltEntityId:
type: string
description: DLT entity/registration ID (mandatory for India).
DltTemplateId:
type: string
description: DLT-approved template ID.
StatusCallback:
type: string
CustomField:
type: string
SmsResponse:
type: object
properties:
Sid:
type: string
AccountSid:
type: string
Status:
type: string
From:
type: string
To:
type: string
Body:
type: string
DateCreated:
type: string
DetailedStatus:
type: string
NumberMetadata:
type: object
description: Modeled from documented number-lookup fields.
properties:
PhoneNumber:
type: string
Circle:
type: string
description: Telecom circle (region).
CircleName:
type: string
Type:
type: string
description: Number type (e.g. mobile, landline).
Operator:
type: string
OperatorName:
type: string
DND:
type: string
description: Do-Not-Disturb registration status where available.
Campaign:
type: object
properties:
id:
type: string
name:
type: string
status:
type: string
caller_id:
type: string
type:
type: string
created_at:
type: string
CampaignInput:
type: object
properties:
name:
type: string
caller_id:
type: string
lists:
type: array
items:
type: string
description: List IDs of contacts to dial.
campaign_type:
type: string
url:
type: string
description: Call-flow URL to run for each connected call.
schedule:
type: object
additionalProperties: true