> ## Documentation Index
> Fetch the complete documentation index at: https://docs.helloannie.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Start outbound SMS conversation

> Initiate an outbound SMS conversation from an Annie phone number to a destination number. Production SMS requires the sending organization's business verification and A2P 10DLC campaign to be approved. The sender phone number must also be attached to the approved Messaging Service. SMS is subject to legal hours (9 AM–8 PM org timezone) and per-number rate limits. Rate limits per destination number: max 6 SMS per rolling 30 days, min 24 hours between attempts, 30-day cooldown after 3 consecutive failed attempts, and max 3 attempts per rolling 7 days. Returns 409 Conflict if a send to the same number is already in progress. Returns a conversation ID for tracking the SMS conversation.



## OpenAPI

````yaml /openapi/openapi.yaml post /sms
openapi: 3.0.3
info:
  title: Annie API
  description: >
    ### Overview


    The Annie API is a (mostly) RESTful API. Typically, both POST bodies and
    responses are JSON-encoded.


    Note: The documenation is Work In Progress and is subject to change.


    ### Base URL


    The base URL for the Annie API is https://api.helloannie.com/.


    Examples in this document may abbreviate this to `/`.


    ### Versioning


    Routes are prefixed with a version number i.e. `v1`. The version will change
    when there is a non-backwards compatible or other significant change to the
    api.


    ### Authentication


    The Annie API supports two authentication methods API Keys and OAuth Access
    Tokens:


    #### API Keys


    API Keys are long-lived tokens that can be generated from the Developer
    Portal on your organization page. API keys are prefixed with `annie-sk-v2-`
    and can be used directly in the `Authorization` header.


    ```

    curl -H "Authorization: Bearer annie-sk-xxxxx"
    https://api.helloannie.com/...

    ```


    #### OAuth Tokens


    OAuth tokens are short-lived access tokens generated using the OAuth 2.0
    Client Credentials flow (Machine-to-Machine). OAuth clients provide scoped
    permissions and are ideal for server-to-server integrations.


    **Creating an OAuth Client**


    OAuth clients can be created in the Developer Portal on your organization
    page. When creating a client, you'll receive:


    - `client_id`: Your OAuth client identifier

    - `client_secret`: Your OAuth client secret (store this securely)


    **Generating an OAuth Token**


    To generate an OAuth access token, make a POST request to the Annie OAuth
    token endpoint:


    **Endpoint:** `https://annie-external-api.us.auth0.com/oauth/token`


    **Example Request:**


    ```bash

    curl -X POST https://annie-external-api.us.auth0.com/oauth/token \
      -H "Content-Type: application/json" \
      -d '{
        "grant_type": "client_credentials",
        "client_id": "your-client-id",
        "client_secret": "your-client-secret",
        "audience": "https://api.helloannie.com"
      }'
    ```


    The `access_token` from the response should be used in the `Authorization`
    header when making requests to the Annie API:


    ```

    curl -H "Authorization: Bearer eyJhbGciOiJSUzI..."
    https://api.helloannie.com/v1/...

    ```


    ### API Response Structure


    The Annie API returns status codes consistent with standard HTTP
    conventions. Success and Error responses follow the below structure:


    ```

    {
      "success": boolean
      "data": {}
      "message": string // optional
    }

    ```


    ### Rate Limiting


    The Annie API enforces rate limits to ensure stability and fair usage. The
    default rate limit is **60 requests per minute** per organization. This
    limit is applied per endpoint pattern (e.g. `GET /v1/bots/:id`).


    When the rate limit is exceeded, the API responds with HTTP `429 Too Many
    Requests`.


    Response headers include:


    - `X-RateLimit-Limit`: The maximum number of requests allowed in the current
    window.

    - `X-RateLimit-Remaining`: The number of requests remaining in the current
    window.

    - `X-RateLimit-Reset`: The time at which the current rate limit window
    resets (in UTC epoch seconds).


    If you exceed the limit, the response will contain a `Retry-After` header
    indicating how many seconds to wait before retrying.


    ### Pagination


    The Annie API does not currently support pagination. All results are
    returned at once.
  version: v1
servers:
  - url: https://api.helloannie.com/v1
security: []
paths:
  /sms:
    post:
      tags:
        - SMS
      summary: Start outbound SMS conversation
      description: >-
        Initiate an outbound SMS conversation from an Annie phone number to a
        destination number. Production SMS requires the sending organization's
        business verification and A2P 10DLC campaign to be approved. The sender
        phone number must also be attached to the approved Messaging Service.
        SMS is subject to legal hours (9 AM–8 PM org timezone) and per-number
        rate limits. Rate limits per destination number: max 6 SMS per rolling
        30 days, min 24 hours between attempts, 30-day cooldown after 3
        consecutive failed attempts, and max 3 attempts per rolling 7 days.
        Returns 409 Conflict if a send to the same number is already in
        progress. Returns a conversation ID for tracking the SMS conversation.
      operationId: postV1Sms
      requestBody:
        description: Request body for starting an outbound SMS conversation
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StartSmsRequest'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/StartSmsRequest'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/StartSmsRequest'
      responses:
        '200':
          description: >-
            Response returned when an outbound SMS conversation is successfully
            initiated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StartSmsResponse'
        '400':
          description: The request was invalid or malformed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequestResponse'
        '403':
          description: You do not have permission to perform this action
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenResponse'
        '404':
          description: The requested resource was not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotFoundResponse'
        '409':
          description: The request conflicts with another in-progress operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConflictResponse'
        '500':
          description: An internal server error occurred
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServerErrorResponse'
components:
  schemas:
    StartSmsRequest:
      additionalProperties: false
      example:
        fromNumber: '+15551234567'
        toNumber: '+15559876543'
        message: >-
          Hi Sarah, this is Annie from Bright Smiles Dental. We wanted to reach
          out about scheduling your next cleaning appointment.
        patientInfo:
          firstName: Sarah
          lastName: Johnson
          dateOfBirth: '1988-03-22T00:00:00.000Z'
          patientId: PAT-10432
        appointmentInfo:
          startTime: '2025-03-10T15:00:00-06:00'
          endTime: '2025-03-10T15:30:00-06:00'
          appointmentTypeId: apt-type-cleaning
          appointmentDescription: 6-month routine cleaning and exam
          appointmentId: '81260683'
        context: >-
          Confirming upcoming cleaning appointment scheduled for March 10th at
          3:00 PM
      type: object
      required:
        - fromNumber
        - toNumber
        - message
      properties:
        fromNumber:
          description: >-
            The Annie phone number to send SMS from (must be configured in the
            system)
          example: '+15551234567'
          type: string
        toNumber:
          description: The phone number to send SMS to
          example: '+15559876543'
          type: string
        message:
          description: The initial SMS message to send to the patient
          minLength: 1
          maxLength: 500
          example: >-
            Hi Sarah, this is Annie from Bright Smiles Dental. We wanted to
            reach out about scheduling your next cleaning appointment. Would you
            like to set something up?
          type: string
        patientInfo:
          additionalProperties: false
          description: Patient information for the call
          example:
            firstName: Sarah
            lastName: Johnson
            dateOfBirth: '1988-03-22T00:00:00.000Z'
            patientId: PAT-10432
          type: object
          properties:
            firstName:
              description: Patient's first name
              maxLength: 100
              example: Sarah
              type: string
            lastName:
              description: Patient's last name
              maxLength: 100
              example: Johnson
              type: string
            dateOfBirth:
              description: Patient's date of birth (YYYY-MM-DD format)
              pattern: ^\d{4}-\d{2}-\d{2}$
              maxLength: 10
              example: '1988-03-22T00:00:00.000Z'
              type: string
            patientId:
              description: Patient's external ID from the practice management system
              maxLength: 255
              example: PAT-10432
              type: string
        appointmentInfo:
          additionalProperties: false
          description: Appointment information for context during the call
          example:
            startTime: '2025-03-10T15:00:00-06:00'
            endTime: '2025-03-10T15:30:00-06:00'
            appointmentTypeId: apt-type-cleaning
            appointmentDescription: 6-month routine cleaning and exam
            appointmentId: '81260683'
          type: object
          properties:
            startTime:
              description: >-
                Appointment start time in ISO 8601 format with timezone offset
                (e.g., 2025-03-10T15:00:00-06:00)
              pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,3})?[+-]\d{2}:\d{2}$
              example: '2025-03-10T15:00:00-06:00'
              type: string
            endTime:
              description: >-
                Appointment end time in ISO 8601 format with timezone offset
                (e.g., 2025-03-10T15:30:00-06:00)
              pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,3})?[+-]\d{2}:\d{2}$
              example: '2025-03-10T15:30:00-06:00'
              type: string
            appointmentTypeId:
              description: ID of the appointment type
              maxLength: 255
              example: apt-type-cleaning
              type: string
            appointmentDescription:
              description: Description of the appointment
              maxLength: 255
              example: 6-month routine cleaning and exam
              type: string
            appointmentId:
              description: >-
                Appointment ID from the practice management system (numeric IDs
                recommended for appointment confirmation support)
              maxLength: 255
              example: '81260683'
              type: string
        context:
          description: Context about the SMS conversation being initiated
          maxLength: 500
          example: >-
            Confirming upcoming cleaning appointment scheduled for March 10th at
            3:00 PM
          type: string
    StartSmsResponse:
      additionalProperties: false
      type: object
      required:
        - success
        - data
      properties:
        success:
          enum:
            - true
          type: boolean
        data:
          additionalProperties: false
          description: >-
            Data returned when an outbound SMS conversation is successfully
            initiated
          type: object
          required:
            - conversationId
          properties:
            conversationId:
              format: uuid
              description: The conversation ID for this SMS conversation
              type: string
    BadRequestResponse:
      additionalProperties: false
      type: object
      required:
        - success
        - data
        - message
      properties:
        success:
          enum:
            - false
          type: boolean
        data:
          additionalProperties: false
          type: object
          properties: {}
        message:
          type: string
    ForbiddenResponse:
      additionalProperties: false
      type: object
      required:
        - success
        - data
        - message
      properties:
        success:
          enum:
            - false
          type: boolean
        data:
          additionalProperties: false
          type: object
          properties: {}
        message:
          type: string
    NotFoundResponse:
      additionalProperties: false
      type: object
      required:
        - success
        - data
        - message
      properties:
        success:
          enum:
            - false
          type: boolean
        data:
          additionalProperties: false
          type: object
          properties: {}
        message:
          type: string
    ConflictResponse:
      additionalProperties: false
      type: object
      required:
        - success
        - data
        - message
      properties:
        success:
          enum:
            - false
          type: boolean
        data:
          additionalProperties: false
          type: object
          properties: {}
        message:
          type: string
    ServerErrorResponse:
      additionalProperties: false
      type: object
      required:
        - success
        - data
        - message
      properties:
        success:
          enum:
            - false
          type: boolean
        data:
          additionalProperties: false
          type: object
          properties: {}
        message:
          type: string

````