Exotel Numbers API

Look up telecom metadata for a phone number via GET /v1/Accounts/{sid}/Numbers/{Number} - operator/circle, number type, and DND status where available for Indian numbers.

OpenAPI Specification

exotel-openapi.yml Raw ↑
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