openapi: 3.1.0
# Added by API Auto Mocking Plugin
servers:
  - description: Sakari Production
    url: https://api.sakari.io
info:
  description: |
    # Introduction

    Welcome to the documentation for the Sakari Messaging REST API. 

    Sakari provides an advanced platform to drive large scale customized SMS communication

    REST is a web-service protocol that lends itself to rapid development by using everyday HTTP and JSON technology.

    To find out more about our product offering, please visit [https://sakari.io](https://sakari.io).

    # Quickstart

    For your convenience we have created a quickstart guide to get you up and running in 5 minutes. 

    [https://sakari.io/blog/text-messaging-sms-api-quickstart/](https://sakari.io/blog/text-messaging-sms-api-quickstart/)

    # PostMan Collection

    We've created a simple set of examples using [PostMan](https://www.getpostman.com/) Simply click below to import these. You will need to setup three environment variables in PostMan - AccountId, ClientId and ClientSecret. Check out our PostMan blog post for more information

    [![Run in Postman](https://run.pstmn.io/button.svg)](https://app.getpostman.com/run-collection/d616e273edc916a7a6eb)

    # Finding your client id, client secret and account id

    To authenticate against the API's you will need three key pieces of data
     - client id
     - client secret
     - account id

    To retrieve these, simply login into [https://hub.sakari.io](https://hub.sakari.io) and click on the "cog" in the top right corner. In the popup dialog at the bottom you should see your API credentials and account id. If these are not visible you will need to click on "Request Credentials"

    # Versioning

    With any breaking changes we will introduce a new version of the API. The latest version is v1.

    The API uses an open schema model, which means server may add extra properties to responses. Likewise, the server will ignore any extra query parameters and request body properties. When you write clients, you need to ignore additional properties in responses to ensure they do not break.

    # Testing

    There are numerous tools available for testing the API's. We will include examples using curl and the client SDKs that we have created. If you would like to see an SDK in a language not currently available, please let us know.

    # Throttling / Limits

    Our API's have been specifically designed to support bulk messaging in a single API call. We therefore impose limits on the frequency of calling the APIs to prevent abuse or runaway processes. If you feel you need a higher limit, please contact us. If you hit the limit you will get a 429 error code returned from our servers

    # Errors

    The API uses standard HTTP status codes to indicate the success or failure of the API call. The body of the response will be JSON in the following format:

    ```
    {
      "success": false,
      "error": {
        "code": "CONT-001",
        "message": "Invalid mobile number"
      }
    }
    ```

    # Pagination

    For performance, most GET calls return a subset of data. This data is paginated for easy access. Most APIs which return collections of data will return a pagination object as such:

    ```
    {
      "pagination": {
        "offset": 0,
        "limit": 10
      }  
    }
    ```

    When making calls to the API, you can adjust the slice of data returned using query parameters such as:

    `` https://api.sakari.io/v1/accounts/123/contacts?offset=20&limit=25 ``

    This will return 25 contacts with an offset of 20.

  version: "1.0.2"
  title: Sakari
  termsOfService: "https://sakari.io/terms-service.html"
  contact:
    email: help@sakari.io
  # x-logo:
  # url: 'https://sakari.io/assets/images/sakari_logo.svg'
tags:
  - name: authentication
    description: |
      Sakari uses OAuth2 for authentication. After you have created an account at [https://hub.sakari.io](https://hub.sakari.io), you can retrieve your client id and secret from the 'Account Details' screen (click on the 'cog' icon in the top right corner and scroll down to API Credentials)

      Using your client id and secret, you can exchange these for a JWT ([JSON Web Token](https://en.wikipedia.org/wiki/JSON_Web_Token))

      The JWT should then be used when accessing any of the core API's. It should be passed in the `Authorization` header.

      For example:

      ``Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImt....``

    # externalDocs:
    # description: Find out more
    # url: 'https://sakari.io'
  - name: accounts
    description: Create, modify or delete accounts
  - name: contacts
    description: Create, modify or delete contacts
  - name: integrations
    description: View existing integrations in your Sakari account
  - name: autoresponders
    description: Create, modify, or delete autoresponders
  - name: availablephonenumbers
    description: Check for available phone numbers
  - name: bulk
    description: Bulk actions for contacts and users
  - name: messages
    description: Send or track messages to one contact, a group of contacts or your entire address book
  - name: templates
    description: Define reusable message or web templates
  - name: campaigns
    description: Define reusable message campaigns with a predefined contact list/filter, template and schedule
  - name: conversations
    description: Conversations group your message history with each contact into one thread
  - name: tools
    description: Tools to assist with sending and receiving messages, such as file sharing, translation, etc.
  - name: webhooks
    description: Webhooks allow your own system to be automatically notified upon certin events, such as a new message received from one of your contacts or a status change notification for your messages
  - name: workflows
    description: Create, modify, and delete workflows
  - name: workflowtemplates
    description: Existing workflow templates that can be used
  - name: meetingevents
    description: Configure meeting events for your leads to book time with you
  - name: meetings
    description: Meetings with your contacts

paths:
  /oauth2/token:
    post:
      tags:
        - authentication
      summary: Get token for accessing APIs
      operationId: auth.token
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TokenRequest"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TokenResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      x-code-samples:
        - lang: CURL
          source: |
            curl -X POST \
              https://api.sakari.io/oauth2/token \
              -H 'Content-Type: application/json' \
              -d '{
              "grant_type": "client_credentials",
              "client_id": "12345678-1234-1234-1234-123456789012",
              "client_secret": "87654321-4321-4321-4321-098765432121"
            }'
        - lang: JavaScript
          source: |
            var settings = {
              "async": true,
              "crossDomain": true,
              "url": "https://api.sakari.io/oauth2/token",
              "method": "POST",
              "headers": {
                "Content-Type": "application/json"
              },
              "processData": false,
              "data": "{\n\t\"grant_type\": \"client_credentials\",\n\t\"client_id\": \"12345678-1234-1234-1234-123456789012\",\n\t\"client_secret\": \"87654321-4321-4321-4321-098765432121\"\n}"
            }

            $.ajax(settings).done(function (response) {
              console.log(response);
            });
        - lang: PHP
          source: |
            <?php

              $request = new HttpRequest();
              $request->setUrl('https://api.sakari.io/oauth2/token');
              $request->setMethod(HTTP_METH_POST);
              
              $request->setHeaders(array(
                'Content-Type' => 'application/json'
              ));
              
              $request->setBody('{
                "grant_type": "client_credentials",
                "client_id": "12345678-1234-1234-123456789012",
                "client_secret": "87654321-4321-4321-898765432121"
              }');
              
              try {
                $response = $request->send();
              
                echo $response->getBody();
              } catch (HttpException $ex) {
                echo $ex;
              }

  /v1/accounts:
    $ref: "./accounts.yaml#/methods"

  /v1/accounts/{accountId}:
    get:
      tags:
        - accounts
      summary: Fetch account
      operationId: accounts.fetch
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AccountResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

    # put:
    #   tags:
    #   - accounts
    #   summary: Update account
    #   operationId: accounts.update
    #   parameters:
    #   - $ref: '#/components/parameters/accountId'
    #   responses:
    #     200:
    #       description: successful operation
    #       content:
    #         application/json:
    #           schema:
    #             $ref: '#/components/responses/AccountResponse'
    #     4XX:
    #       description: invalid request
    #       content:
    #         application/json:
    #           schema:
    #             $ref: '#/schemas/ErrorResponse'
    #     5XX:
    #       description: invalid request
    #       content:
    #         application/json:
    #           schema:
    #             $ref: '#/schemas/ErrorResponse'
    #   security:
    #   - sakari_auth: []

  /v1/accounts/{accountId}/attributes:
    get:
      tags:
        - accounts
      summary: Fetch account attributes
      operationId: account.attributes.fetch
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AccountAttributesResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/attributes/{attributeType}:
    get:
      tags:
        - accounts
      summary: Fetch account attributes by type
      operationId: account.attributes.fetchByType
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/attributeTypePath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AccountAttributesResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []
    post:
      tags:
        - accounts
      summary: Setup autotopup for your account
      operationId: account.attributes.create
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/attributeTypePath"
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Contact"
          text/csv:
            #description: Bulk upload using CSV file
            schema:
              type: string
              example: >
                country,firstName,lastName,email,mobile,jobTitle,Address,City,State,ZipCode
                US,Joe,Bloggs,joebloggs@sakari.co,123-456-7890,mover,123 Text Street,San Francisco,CA,12345
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AutoTopupResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/attributes/{attributeType}/{attributeId}:
    get:
      tags:
        - accounts
      summary: Fetch account attributes
      operationId: account.attributes.fetchById
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/attributeTypePath"
        - $ref: "#/components/parameters/attributeIdPath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AccountAttributesResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []
    put:
      tags:
        - accounts
      summary: Setup autotopup for your account
      operationId: account.attributes.update
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/attributeTypePath"
        - $ref: "#/components/parameters/attributeIdPath"
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Contact"
          text/csv:
            #description: Bulk upload using CSV file
            schema:
              type: string
              example: >
                country,firstName,lastName,email,mobile,jobTitle,Address,City,State,ZipCode
                US,Joe,Bloggs,joebloggs@sakari.co,123-456-7890,mover,123 Text Street,San Francisco,CA,12345
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AutoTopupResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []
    delete:
      tags:
        - accounts
      summary: Disable autotopup for your account
      operationId: account.attributes.delete
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/attributeTypePath"
        - $ref: "#/components/parameters/attributeIdPath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "./common.yaml#/schemas/BasicResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/balance:
    get:
      tags:
        - accounts
      summary: Fetch account balance
      operationId: balance.fetch
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BalanceResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  # /v1/accounts/{accountId}/invoices:
  #   get:
  #     tags:
  #     - accounts
  #     summary: Fetch account invoices
  #     operationId: invoices.fetch
  #     parameters:
  #     - $ref: '#/components/parameters/accountIdPath'
  #     responses:
  #       200:
  #         description: successful operation
  #         content:
  #           application/json:
  #             schema:
  #               $ref: '#/components/schemas/InvoicesResponse'
  #     security:
  #     - sakari_auth: []

  /v1/accounts/{accountId}/checkout:
    post:
      tags:
        - accounts
      summary: create a checkout session to upgrade from trial to paid plan
      operationId: account.checkout.create
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/checkoutSuccessUrl"
        - $ref: "#/components/parameters/checkoutCancelUrl"
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CheckoutRequest"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CheckoutResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/plan:
    get:
      tags:
        - accounts
      summary: Fetch account plan
      operationId: plans.fetch
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "./pricing.yaml#/responses/PlanResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

    put:
      tags:
        - accounts
      summary: Change account plan
      operationId: account.plans.update
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdatePlanRequest"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "./pricing.yaml#/responses/PlanResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/plan/enterprise:
    post:
      tags:
        - accounts
      summary: make a request to increase plan commitment beyond max
      operationId: account.plans.enterpriseInquiry.create
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EnterpriseInquiryRequest"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EnterpriseInquiryResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/plans:
    get:
      tags:
        - accounts
      summary: Fetch eligible subscription
      operationId: account.plans.fetchAll
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "./pricing.yaml#/responses/PlansResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/topup:
    put:
      tags:
        - accounts
      summary: Topup your account
      operationId: topups.update
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "./common.yaml#/schemas/BasicResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/autotopup:
    put:
      tags:
        - accounts
      summary: Setup autotopup for your account
      operationId: autotopups.update
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AutoTopupResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

    delete:
      tags:
        - accounts
      summary: Disable autotopup for your account
      operationId: autotopups.delete
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "./common.yaml#/schemas/BasicResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/autoresponders:
    get:
      tags:
        - autoresponders
      summary: Fetch All Account Autoresponders
      operationId: accounts.autoresponders.fetchAll
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AutorespondersResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

    post:
      tags:
        - autoresponders
      summary: Create an Autoresponder
      operationId: accounts.autoresponders.create
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AutoresponderResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/autoresponders/{autoresponderId}:
    get:
      tags:
        - autoresponders
      summary: Fetch All Account Autoresponders
      operationId: accounts.autoresponders.fetch
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/autoresponderIdPath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AutoresponderResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

    put:
      tags:
        - autoresponders
      summary: Update An Autoresponder
      operationId: accounts.autoresponders.update
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/autoresponderIdPath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AutoresponderResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

    delete:
      tags:
        - autoresponders
      summary: Remove an autoresponder
      operationId: accounts.autoresponders.remove
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/autoresponderIdPath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "./common.yaml#/schemas/BasicResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/availablephonenumbers:
    get:
      tags:
        - availablephonenumbers
      summary: Check all available phone numbers
      operationId: accounts.availablephonenumbers
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/country"
        - $ref: "#/components/parameters/type"
        - $ref: "#/components/parameters/postalCode"
        - $ref: "#/components/parameters/features"
        - $ref: "#/components/parameters/contains"
        - $ref: "#/components/parameters/areaCode"

      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AvailablePhoneNumbersResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"

      security:
        - sakari_auth: []

  # /v1/accounts/{accountId}/availablephonenumbers/metadata:
  #   get:
  #     tags:
  #     - availablephonenumbers
  #     summary: Check all available types of phone numbers for every region
  #     operationId: accounts.availablephonenumbers.metadata
  #     parameters:
  #     - $ref: '#/components/parameters/accountIdPath'
  #     responses:
  #       200:
  #         description: successful operation
  #         content:
  #           application/json:
  #             schema:
  #               type: object
  #               properties:
  #                 success:
  #                   type: boolean
  #                   default: true
  #                 data:
  #                   type: object

  #     security:
  #     - sakari_auth: []

  # /v1/accounts/{accountId}/availablephonenumbers/metadata/{countryParam}:
  #   get:
  #     tags:
  #     - availablephonenumbers
  #     summary: Check all available types of phone numbers in a country
  #     operationId: accounts.availablephonenumbers.metadata.country
  #     parameters:
  #     - $ref: '#/components/parameters/accountIdPath'
  #     - $ref: '#/components/parameters/country'
  #     responses:
  #       200:
  #         description: successful operation
  #         content:
  #           application/json:
  #             schema:
  #               type: object
  #               properties:
  #                 success:
  #                   type: boolean
  #                   default: true
  #                 data:
  #                   type: array
  #                   items:
  #                     $ref: '#/components/schemas/LineTypeMetaData'

  #     security:
  #     - sakari_auth: []

  # /v1/accounts/{accountId}/bulk/contacts/count:
  #   post:
  #     tags:
  #     - bulk
  #     summary: Fetch number of contacts in account
  #     operationId: accounts.contacts.count
  #     parameters:
  #     - $ref: '#/components/parameters/accountIdPath'
  #     responses:
  #       200:
  #         description: successful operation
  #         content:
  #           application/json:
  #             schema:
  #               type: object
  #               properties:
  #                 success:
  #                   type: boolean
  #                   default: true
  #                 data:
  #                   type: number

  # /v1/accounts/{accountId}/bulk/contacts/download:
  #   post:
  #     tags:
  #     - bulk
  #     summary: Get all contacts in CSV format
  #     operationId: accounts.contacts.bulk.download
  #     parameters:
  #     - $ref: '#/components/parameters/accountIdPath'
  #     responses:
  #       200:
  #         description: successful operation
  #         content:
  #           text/csv:
  #             schema:
  #               type: string

  # /v1/accounts/{accountId}/bulk/contacts/block:
  #   post:
  #     tags:
  #     - bulk
  #     summary: Bulk block contacts in account
  #     operationId: accounts.bulk.contacts.block
  #     parameters:
  #     - $ref: '#/components/parameters/accountIdPath'
  #     responses:
  #       200:
  #         description: successful operation
  #         content:
  #           application/json:
  #             schema:
  #               type: object
  #               properties:
  #                 success:
  #                   type: boolean
  #                 count:
  #                   type: number

  # /v1/accounts/{accountId}/bulk/contacts/delete:
  #   post:
  #     tags:
  #     - bulk
  #     summary: Bulk block contacts in account
  #     operationId: accounts.bulk.contacts.delete
  #     parameters:
  #     - $ref: '#/components/parameters/accountIdPath'
  #     responses:
  #       200:
  #         description: successful operation
  #         content:
  #           application/json:
  #             schema:
  #               type: object
  #               properties:
  #                 success:
  #                   type: boolean
  #                 count:
  #                   type: number

  /v1/accounts/{accountId}/calls:
    get:
      tags:
        - calls
      summary: Fetch call history
      operationId: callhistory.fetchAll
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/conversationId"
        - $ref: "#/components/parameters/phonenumberId"
        - $ref: "#/components/parameters/contactId"
        - $ref: "#/components/parameters/userId"
        - $ref: "#/components/parameters/groupId"
        - $ref: "#/components/parameters/callDirection"
        - $ref: "#/components/parameters/callStatus"
        - $ref: "#/components/parameters/from"
        - $ref: "#/components/parameters/to"
        - $ref: "#/components/parameters/offset"
        - $ref: "#/components/parameters/limit"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CallHistoriesResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []
      x-code-samples:
        - lang: CURL
          source: |
            curl -X GET \
              https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}/calls \
              -H 'Authorization: Bearer {{TOKEN}}'
        - lang: JavaScript
          source: |
            var request = require("request");
            var options = { method: 'GET',
              url: 'https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}/calls',
              headers: 
               { Authorization: 'Bearer {{TOKEN}}' } };

            request(options, function (error, response, body) {
              if (error) throw new Error(error);

              console.log(body);
            });

        - lang: PHP
          source: |
            <?php
              $request = new HttpRequest();
              $request->setUrl('https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/calls');
              $request->setMethod(HTTP_METH_GET);
              
              $request->setHeaders(array(
                'Authorization' => 'Bearer {{TOKEN}}'
              ));
              
              try {
                $response = $request->send();
              
                echo $response->getBody();
              } catch (HttpException $ex) {
                echo $ex;
              }

  /v1/accounts/{accountId}/calls/{callId}:
    get:
      tags:
        - calls
      summary: Fetch details of call history by call ID
      operationId: call.fetch
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/callId"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CallHistoryResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []
      x-code-samples:
        - lang: CURL
          source: |
            curl -X GET \
              https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/calls/{{CALL_ID}} \
              -H 'Authorization: Bearer {{TOKEN}}'
        - lang: JavaScript
          source: |
            var request = require("request");
            var options = { method: 'GET',
              url: 'https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/calls/{{CALL_ID}}',
              headers: 
               { Authorization: 'Bearer {{TOKEN}}' } };

            request(options, function (error, response, body) {
              if (error) throw new Error(error);

              console.log(body);
            });

        - lang: PHP
          source: |
            <?php
              $request = new HttpRequest();
              $request->setUrl('https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/calls/{{CALL_ID}}');
              $request->setMethod(HTTP_METH_GET);
              
              $request->setHeaders(array(
                'Authorization' => 'Bearer {{TOKEN}}'
              ));
              
              try {
                $response = $request->send();
              
                echo $response->getBody();
              } catch (HttpException $ex) {
                echo $ex;
              }

  /v1/accounts/{accountId}/calls/recording/{recordingId}:
    get:
      tags:
        - calls
      summary: Streams a recording
      operationId: call.streamRecording
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/recordingId"
      responses:
        200:
          description: successful operation
          content:
            audio/wav:
              schema:
                type: string
                format: binary
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/contacts:
    get:
      tags:
        - contacts
      summary: Fetch contacts
      operationId: contacts.fetchAll
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/offset"
        - $ref: "#/components/parameters/limit"
        - $ref: "#/components/parameters/firstName"
        - $ref: "#/components/parameters/lastName"
        - $ref: "#/components/parameters/mobile"
        - $ref: "#/components/parameters/email"
        - $ref: "#/components/parameters/tags"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ContactsResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []
      x-code-samples:
        - lang: CURL
          source: |
            curl -X GET \
              https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/contacts \
              -H 'Authorization: Bearer {{TOKEN}}'
        - lang: JavaScript
          source: |
            var request = require("request");
            var options = { method: 'GET',
              url: 'https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/contacts',
              headers: 
               { Authorization: 'Bearer {{TOKEN}}' } };

            request(options, function (error, response, body) {
              if (error) throw new Error(error);

              console.log(body);
            });

        - lang: PHP
          source: |
            <?php
              $request = new HttpRequest();
              $request->setUrl('https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/contacts');
              $request->setMethod(HTTP_METH_GET);
              
              $request->setHeaders(array(
                'Authorization' => 'Bearer {{TOKEN}}'
              ));
              
              try {
                $response = $request->send();
              
                echo $response->getBody();
              } catch (HttpException $ex) {
                echo $ex;
              }

    post:
      tags:
        - contacts
      summary: Create contact
      operationId: contacts.create
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - name: mergeStrategy
          in: query
          description: Determines how existing contacts with matching mobile numbers are treated
          required: false
          schema:
            type: string
            # TODO add enum descriptions
            enum:
              - append
              - core
              - remove
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Contact"
          text/csv:
            #description: Bulk upload using CSV file
            schema:
              type: string
              example: >
                country,firstName,lastName,email,mobile,jobTitle,Address,City,State,ZipCode
                US,Joe,Bloggs,joebloggs@sakari.co,123-456-7890,mover,123 Text Street,San Francisco,CA,12345
      responses:
        201:
          description: successful operation
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/ContactsResponse"
                  - $ref: "#/components/schemas/ContactUploadResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []
      x-code-samples:
        - lang: CURL
          source: |
            curl -X POST \
              https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/contacts \
              -H 'Content-Type: application/json' \
              -d '{
              "firstName": "Chris",
              "lastName": "Thomson",
              "mobile": {
                "number": "+1234567890",
                "country": "US"
              }
            }'
        - lang: JavaScript
          source: |
            var request = require("request");
            var options = { method: 'POST',
              url: 'https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/contacts',
              headers: {
                 Authorization: 'Bearer {{TOKEN}}',
                 'Content-Type': 'application/json' },
              body: 
               { firstName: 'Chris',
                 lastName: 'Thomson',
                 mobile: { number: '+1234567890', country: 'US' } },
              json: true };

            request(options, function (error, response, body) {
              if (error) throw new Error(error);

              console.log(body);
            });

        - lang: PHP
          source: |
            <?php
              $request = new HttpRequest();
              $request->setUrl('https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/contacts');
              $request->setMethod(HTTP_METH_POST);
              
              $request->setHeaders(array(
                'Content-Type' => 'application/json'
              ));
              
              $request->setBody('{
                "firstName": "Chris",
                "lastName": "Thomson",
                "mobile": {
                  "number": "+1234567890",
                  "country": "US"
                }
              }');
              
              try {
                $response = $request->send();
              
                echo $response->getBody();
              } catch (HttpException $ex) {
                echo $ex;
              }

  /v1/accounts/{accountId}/contacts/{contactId}:
    get:
      tags:
        - contacts
      summary: Fetch contact by ID
      operationId: contacts.fetch
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/contactId"
        - name: contactId
          in: path
          description: ID of contact to return
          required: true
          schema:
            type: string
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ContactResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []
      x-code-samples:
        - lang: CURL
          source: |
            curl -X GET \
              https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/contacts/{{CONTACT_ID}} \
              -H 'Authorization: Bearer {{TOKEN}}'
        - lang: JavaScript
          source: |
            var request = require("request");
            var options = { method: 'GET',
              url: 'https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/contacts/{{CONTACT_ID}}',
              headers: 
               { Authorization: 'Bearer {{TOKEN}}' } };

            request(options, function (error, response, body) {
              if (error) throw new Error(error);

              console.log(body);
            });

        - lang: PHP
          source: |
            <?php
              $request = new HttpRequest();
              $request->setUrl('https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/contacts/{{CONTACT_ID}}');
              $request->setMethod(HTTP_METH_GET);
              
              $request->setHeaders(array(
                'Authorization' => 'Bearer {{TOKEN}}'
              ));
              
              try {
                $response = $request->send();
              
                echo $response->getBody();
              } catch (HttpException $ex) {
                echo $ex;
              }
    put:
      tags:
        - contacts
      summary: Updates a contact
      operationId: contacts.update
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - name: contactId
          in: path
          description: ID of contact
          required: true
          schema:
            type: string
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ContactResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []
      x-code-samples:
        - lang: CURL
          source: |
            curl -X PUT \
              https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/contacts/{{CONTACT_ID}} \
              -H 'Authorization: Bearer {{TOKEN}}'' \
              -H 'Content-Type: application/json' \
              -d '{
              "firstName": "Bob",
              "lastName": "Thomson",
              "mobile": {
                "number": "+1234567890",
                "country": "US"
              }
            }'
        - lang: JavaScript
          source: |
            var request = require("request");
            var options = { method: 'PUT',
              url: 'https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/contacts/{{CONTACT_ID}}',
              headers: 
               { 'Authorization': 'Bearer {{TOKEN}}',
                 'Content-Type': 'application/json' },
              body: 
               { firstName: 'Bob',
                 lastName: 'Thomson',
                 mobile: { number: '+1234567890', country: 'US' } },
              json: true };

            request(options, function (error, response, body) {
              if (error) throw new Error(error);

              console.log(body);
            });

        - lang: PHP
          source: |
            <?php
              $request = new HttpRequest();
              $request->setUrl('https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/contacts/{{CONTACT_ID}}');
              $request->setMethod(HTTP_METH_PUT);
              
              $request->setHeaders(array(
                'Authorization' => 'Bearer {{TOKEN}}',
                'Content-Type' => 'application/json'
              ));
              
              $request->setBody('{
                "firstName": "Bob",
                "lastName": "Thomson",
                "mobile": {
                  "number": "+1234567890",
                  "country": "US"
                }
              }');
              
              try {
                $response = $request->send();
              
                echo $response->getBody();
              } catch (HttpException $ex) {
                echo $ex;
              }
    delete:
      tags:
        - contacts
      summary: Deletes a contact
      operationId: contacts.remove
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - name: contactId
          in: path
          description: Contact id to delete
          required: true
          schema:
            type: string
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []
      x-code-samples:
        - lang: CURL
          source: |
            curl -X DELETE \
              https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/contacts/{{CONTACT_ID}} \
              -H 'Authorization: Bearer {{TOKEN}}' \
              -H 'Content-Type: application/json' \
            }'
        - lang: JavaScript
          source: |
            var request = require("request");
            var options = { method: 'DELETE',
              url: 'https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/contacts/{{CONTACT_ID}}',
              headers: 
               { 'Authorization': 'Bearer {{TOKEN}}',
                 'Content-Type': 'application/json' } };

            request(options, function (error, response, body) {
              if (error) throw new Error(error);

              console.log(body);
            });

        - lang: PHP
          source: |
            <?php
              $request = new HttpRequest();
              $request->setUrl('https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/contacts/{{CONTACT_ID}}');
              $request->setMethod(HTTP_METH_DELETE);
              
              $request->setHeaders(array(
                'Authorization' => 'Bearer {{TOKEN}}',
                'Content-Type' => 'application/json'
              ));
              
              $request->setBody('{
                "firstName": "Chris",
                "lastName": "Thomson",
                "mobile": {
                  "number": "+1234567890",
                  "country": "US"
                }
              }');
              
              try {
                $response = $request->send();
              
                echo $response->getBody();
              } catch (HttpException $ex) {
                echo $ex;
              }

  /v1/accounts/{accountId}/messages:
    get:
      tags:
        - messages
      summary: Fetch messages
      operationId: messages.fetchAll
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/offset"
        - $ref: "#/components/parameters/limit"
        - $ref: "#/components/parameters/contactId"
        - $ref: "#/components/parameters/conversationId"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MessagesResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []
      x-code-samples:
        - lang: CURL
          source: |
            curl -X GET \
              https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/messages \
              -H 'Authorization: Bearer {{TOKEN}}'
        - lang: JavaScript
          source: |
            var settings = {
              "async": true,
              "crossDomain": true,
              "url": "https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/messages",
              "method": "GET",
              "headers": {
                "Authorization": "Bearer {{TOKEN}}"
              }
            }

            $.ajax(settings).done(function (response) {
              console.log(response);
            });
        - lang: PHP
          source: |
            <?php
              $request = new HttpRequest();
              $request->setUrl('https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/messages');
              $request->setMethod(HTTP_METH_GET);
              
              $request->setHeaders(array(
                'Authorization' => 'Bearer {{TOKEN}}'
              ));
              
              try {
                $response = $request->send();
              
                echo $response->getBody();
              } catch (HttpException $ex) {
                echo $ex;
              }
    post:
      tags:
        - messages
      summary: Send Messages
      operationId: messages.send
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SendMessagesRequest"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SendMessagesResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []
      x-code-samples:
        - lang: CURL
          source: |
            curl -X POST \
              https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/messages \
              -H 'Accept: application/json' \
              -H 'Authorization: Bearer {{TOKEN}}' \
              -H 'Content-Type: application/json' \
              -d '{
              "contacts": [{
                "mobile": {
                  "number": "+1234567890",
                  "country": "US"
                }
              }],
              "template": "Congratulations! You just sent your first message"
            } '
        - lang: JavaScript
          source: |
            var request = require("request");
            var options = { method: 'POST',
              url: 'https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/messages',
              headers: 
               { 'Authorization': 'Bearer {{TOKEN}}',
                 Accept: 'application/json',
                 'Content-Type': 'application/json' },
              body: 
               { contacts: [ { mobile: { number: '+1234567890', country: 'US' } } ],
                 template: 'Congratulations! You just sent your first message' },
              json: true };

            request(options, function (error, response, body) {
              if (error) throw new Error(error);

              console.log(body);
            });

        - lang: PHP
          source: |
            <?php
              $request = new HttpRequest();
              $request->setUrl('https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/messages');
              $request->setMethod(HTTP_METH_POST);
              
              $request->setHeaders(array(
                'Authorization' => 'Bearer {{TOKEN}}',
                'Accept' => 'application/json',
                'Content-Type' => 'application/json'
              ));
              
              $request->setBody('{
                "contacts": [{
                  "mobile": {
                    "number": "+1234567890",
                    "country": "US"
                  }
                }],
                "template": "Congratulations! You just sent your first message"
              } ');
              
              try {
                $response = $request->send();
              
                echo $response->getBody();
              } catch (HttpException $ex) {
                echo $ex;
              }

  /v1/accounts/{accountId}/messages/{messageId}:
    get:
      tags:
        - messages
      summary: Fetch message by id
      description: Returns a single messag
      operationId: messages.fetch
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - name: messageId
          in: path
          description: ID of message to return
          required: true
          schema:
            type: string
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MessageResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []
      x-code-samples:
        - lang: CURL
          source: |
            curl -X GET \
              https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/messages/{{MESSAGE_ID}} \
              -H 'Authorization: Bearer {{TOKEN}}'
        - lang: JavaScript
          source: |
            var request = require("request");
            var options = { method: 'GET',
              url: 'https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/messages/{{MESSAGE_ID}}',
              headers: 
               { 'Authorization': 'Bearer {{TOKEN}}' } };

            request(options, function (error, response, body) {
              if (error) throw new Error(error);

              console.log(body);
            });

        - lang: PHP
          source: |
            <?php
              $request = new HttpRequest();
              $request->setUrl('https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/messages/{{MESSAGE_ID}}');
              $request->setMethod(HTTP_METH_GET);
              
              $request->setHeaders(array(
                'Authorization' => 'Bearer {{TOKEN}}'
              ));
              
              try {
                $response = $request->send();
              
                echo $response->getBody();
              } catch (HttpException $ex) {
                echo $ex;
              }

  /v1/accounts/{accountId}/templates:
    get:
      tags:
        - templates
      summary: Fetch templates
      operationId: templates.fetchAll
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/offset"
        - $ref: "#/components/parameters/limit"
        - $ref: "#/components/parameters/name"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TemplatesResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []
      x-code-samples:
        - lang: CURL
          source: |
            curl -X GET \
              https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/templates \
              -H 'Authorization: Bearer {{TOKEN}}'
        - lang: JavaScript
          source: |
            var request = require("request");
            var options = { method: 'GET',
              url: 'https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/templates',
              headers: 
               { 'Authorization': 'Bearer {{TOKEN}}' } };

            request(options, function (error, response, body) {
              if (error) throw new Error(error);

              console.log(body);
            });

        - lang: PHP
          source: |
            <?php
              $request = new HttpRequest();
              $request->setUrl('https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/templates');
              $request->setMethod(HTTP_METH_GET);
              
              $request->setHeaders(array(
                'Authorization' => 'Bearer {{TOKEN}}'
              ));
              
              try {
                $response = $request->send();
              
                echo $response->getBody();
              } catch (HttpException $ex) {
                echo $ex;
              }

    post:
      tags:
        - templates
      summary: Create template
      operationId: templates.create
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Template"
      responses:
        201:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TemplatesResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []
      x-code-samples:
        - lang: CURL
          source: |
            curl -X POST \
              https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/templates \
              -H 'Authorization: Bearer {{TOKEN}}' \
              -H 'Content-Type: application/json' \
              -d '{
              "name": "Test Template",
              "template": "Hi {{ firstName }}, Welcome to Sakari!",
              "type": "SMS"
            }'
        - lang: JavaScript
          source: |
            var request = require("request");
            var options = { method: 'POST',
              url: 'https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/templates',
              headers: 
               { 'Content-Type': 'application/json' },
              body: 
               { name: 'Test Template',
                 template: 'Hi {{ firstName }}, Welcome to Sakari!',
                 type: 'SMS' },
              json: true };

            request(options, function (error, response, body) {
              if (error) throw new Error(error);

              console.log(body);
            });

        - lang: PHP
          source: |
            <?php
              $request = new HttpRequest();
              $request->setUrl('https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/templates');
              $request->setMethod(HTTP_METH_POST);
              
              $request->setHeaders(array(
                'Authorization' => 'Bearer {{TOKEN}}',
                'Content-Type' => 'application/json'
              ));
              
              $request->setBody('{
                "name": "Test Template",
                "template": "Hi {{ firstName }}, Welcome to Sakari!",
                "type": "SMS"
              }');
              
              try {
                $response = $request->send();
              
                echo $response->getBody();
              } catch (HttpException $ex) {
                echo $ex;
              }

  /v1/accounts/{accountId}/templates/{templateId}:
    get:
      tags:
        - templates
      summary: Fetch template by ID
      operationId: templates.fetch
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - name: templateId
          in: path
          description: ID of template to return
          required: true
          schema:
            type: string
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TemplateResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []
      x-code-samples:
        - lang: CURL
          source: |
            curl -X GET \
              https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/templates/{{TEMPLATE_ID}} \
              -H 'Authorization: Bearer {{TOKEN}}'
        - lang: JavaScript
          source: |
            var request = require("request");
            var options = { method: 'GET',
              url: 'https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/templates/{{TEMPLATE_ID}}',
              headers: 
               { Authorization: 'Bearer {{TOKEN}}' } };

            request(options, function (error, response, body) {
              if (error) throw new Error(error);

              console.log(body);
            });

        - lang: PHP
          source: |
            <?php
              $request = new HttpRequest();
              $request->setUrl('https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/templates/{{TEMPLATE_ID}}');
              $request->setMethod(HTTP_METH_GET);
              
              $request->setHeaders(array(
                'Authorization' => 'Bearer {{TOKEN}}'
              ));
              
              try {
                $response = $request->send();
              
                echo $response->getBody();
              } catch (HttpException $ex) {
                echo $ex;
              }
    put:
      tags:
        - templates
      summary: Updates a template
      operationId: templates.update
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - name: templateId
          in: path
          description: ID of template
          required: true
          schema:
            type: string
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TemplateResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []
      x-code-samples:
        - lang: CURL
          source: |
            curl -X PUT \
              https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/templates/{{TEMPLATE_ID}} \
              -H 'Authorization: Bearer {{TOKEN}}' \
              -H 'Content-Type: application/json' \
              -d '{
              "name": "Test Template",
              "template": "Hi {{ firstName }}, Welcome to Sakari!",
              "type": "SMS"
            }'
        - lang: JavaScript
          source: |
            var request = require("request");

            var options = { method: 'PUT',
              url: 'https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/templates/{{TEMPLATE_ID}}',
              headers: 
               { Authorization: 'Bearer {{TOKEN}}',
                 'Content-Type': 'application/json' },
              body: 
               { name: 'Test Template',
                 template: 'Hi {{ firstName }}, Welcome to Sakari!',
                 type: 'SMS' },
              json: true };

            request(options, function (error, response, body) {
              if (error) throw new Error(error);

              console.log(body);
            });

        - lang: PHP
          source: |
            <?php
              $request = new HttpRequest();
              $request->setUrl('https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/templates/{{TEMPLATE_ID}}');
              $request->setMethod(HTTP_METH_PUT);
              
              $request->setHeaders(array(
                'Authorization' => 'Bearer {{TOKEN}}',
                'Content-Type' => 'application/json'
              ));
              
              $request->setBody('{
                "name": "Test Template",
                "template": "Hi {{ firstName }}, Welcome to Sakari!",
                "type": "SMS"
              }');
              
              try {
                $response = $request->send();
              
                echo $response->getBody();
              } catch (HttpException $ex) {
                echo $ex;
              }
    delete:
      tags:
        - templates
      summary: Deletes a template
      operationId: templates.remove
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - name: templateId
          in: path
          description: Template id to delete
          required: true
          schema:
            type: string
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []
      x-code-samples:
        - lang: CURL
          source: |
            curl -X DELETE \
              https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/templates/{{TEMPLATE_ID}} \
              -H 'Authorization: Bearer {{TOKEN}}'
        - lang: JavaScript
          source: |
            var request = require("request");

            var options = { method: 'DELETE',
              url: 'https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/templates/{{TEMPLATE_ID}}',
              headers: 
               { Authorization: 'Bearer {{TOKEN}}' } };

            request(options, function (error, response, body) {
              if (error) throw new Error(error);

              console.log(body);
            });

        - lang: PHP
          source: |
            <?php
              $request = new HttpRequest();
              $request->setUrl('https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/templates/{{TEMPLATE_ID}}');
              $request->setMethod(HTTP_METH_DELETE);
              
              $request->setHeaders(array(
                'Authorization' => 'Bearer {{TOKEN}}'
              ));
              
              try {
                $response = $request->send();
              
                echo $response->getBody();
              } catch (HttpException $ex) {
                echo $ex;
              }

  /v1/accounts/{accountId}/campaigns:
    get:
      tags:
        - campaigns
      summary: Fetch campaigns
      operationId: campaigns.fetchAll
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/offset"
        - $ref: "#/components/parameters/limit"
        - $ref: "#/components/parameters/name"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CampaignsResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []
      x-code-samples:
        - lang: CURL
          source: |
            curl -X GET \
              https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/campaigns \
              -H 'Authorization: Bearer {{TOKEN}}'
        - lang: JavaScript
          source: |
            var request = require("request");
            var options = { method: 'GET',
              url: 'https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/campaigns',
              headers: 
               { Authorization: 'Bearer {{TOKEN}}' } };

            request(options, function (error, response, body) {
              if (error) throw new Error(error);

              console.log(body);
            });

        - lang: PHP
          source: |
            <?php
              $request = new HttpRequest();
              $request->setUrl('https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/campaigns');
              $request->setMethod(HTTP_METH_GET);
              
              $request->setHeaders(array(
                'Authorization' => 'Bearer {{TOKEN}}'
              ));
              
              try {
                $response = $request->send();
              
                echo $response->getBody();
              } catch (HttpException $ex) {
                echo $ex;
              }

    post:
      tags:
        - campaigns
      summary: Create campaign
      operationId: campaigns.create
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CampaignRequest"
      responses:
        201:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CampaignResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []
      x-code-samples:
        - lang: CURL
          source: |
            curl -X POST \
              https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/campaigns \
              -H 'Authorization: Bearer {{TOKEN}}' \
              -H 'Content-Type: application/json' \
              -d '{
              "name": "Marketing Campaign",
              "trigger": {
                "code":"M"
              },
              "template":"Hi {{{contact.firstName}}}",
              "reporting":{"when":"NoReport"}
            }'
        - lang: JavaScript
          source: |
            var request = require("request");
            var options = { method: 'POST',
              url: 'https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/campaigns',
              headers: 
               { Authorization: 'Bearer {{TOKEN}}',
                 'Content-Type': 'application/json' },
              body: 
               { name: 'Marketing Campaign',
                 trigger: { code: 'M' },
                 template: 'Hi {{{contact.firstName}}}',
                 reporting: { when: 'NoReport' } },
              json: true };

            request(options, function (error, response, body) {
              if (error) throw new Error(error);

              console.log(body);
            });

        - lang: PHP
          source: |
            <?php
              $request = new HttpRequest();
              $request->setUrl('https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/campaigns');
              $request->setMethod(HTTP_METH_POST);
              
              $request->setHeaders(array(
                'Authorization' => 'Bearer {{TOKEN}}',
                'Content-Type' => 'application/json'
              ));
              
              $request->setBody('{
                "name": "Marketing Campaign",
                "trigger": {
                  "code":"M"
                },
                "template":"Hi {{{contact.firstName}}}",
                "reporting":{"when":"NoReport"}
              }');
              
              try {
                $response = $request->send();
              
                echo $response->getBody();
              } catch (HttpException $ex) {
                echo $ex;
              }

  /v1/accounts/{accountId}/quickcampaigns:
    post:
      tags:
        - campaigns
      summary: Create and Execute a campaign
      operationId: campaigns.createandexecute
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/QuickCampaignRequest"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/QuickCampaignResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/billing:
    put:
      tags:
        - accounts
      summary: update the account's business info
      operationId: accounts.update
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/BillingInfo"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "./accounts.yaml#/responses/BillingInfoResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/campaigns/{campaignId}:
    get:
      tags:
        - campaigns
      summary: Fetch campaign by ID
      operationId: campaigns.fetch
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - name: campaignId
          in: path
          description: ID of campaign to return
          required: true
          schema:
            type: string
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CampaignResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []
      x-code-samples:
        - lang: CURL
          source: |
            curl -X GET \
              https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/campaigns/{{CAMPAIGN_ID}} \
              -H 'Authorization: Bearer {{TOKEN}}'
        - lang: JavaScript
          source: |
            var request = require("request");
            var options = { method: 'GET',
              url: 'https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/campaigns/{{CAMPAIGN_ID}}',
              headers: 
               { Authorization: 'Bearer {{TOKEN}}' } };

            request(options, function (error, response, body) {
              if (error) throw new Error(error);

              console.log(body);
            });

        - lang: PHP
          source: |
            <?php
              $request = new HttpRequest();
              $request->setUrl('https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/campaigns/{{CAMPAIGN_ID}}');
              $request->setMethod(HTTP_METH_GET);
              
              $request->setHeaders(array(
                'Authorization' => 'Bearer {{TOKEN}}'
              ));
              
              try {
                $response = $request->send();
              
                echo $response->getBody();
              } catch (HttpException $ex) {
                echo $ex;
              }
    put:
      tags:
        - campaigns
      summary: Updates a campaign
      operationId: campaigns.update
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - name: campaignId
          in: path
          description: ID of campaign
          required: true
          schema:
            type: string
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CampaignResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []
      x-code-samples:
        - lang: CURL
          source: |
            curl -X POST \
              https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/campaigns/{{CAMPAIGN_ID}} \
              -H 'Authorization: Bearer {{TOKEN}}' \
              -H 'Content-Type: application/json' \
              -d '{
              "name": "Marketing Campaign",
              "trigger": {
                "code":"M"
              },
              "template":"Hi {{{contact.firstName}}}",
              "reporting":{"when":"NoReport"}
            }'
        - lang: JavaScript
          source: |
            var request = require("request");
            var options = { method: 'POST',
              url: 'https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/campaigns/{{CAMPAIGN_ID}}',
              headers: 
               { Authorization: 'Bearer {{TOKEN}}',
                 'Content-Type': 'application/json' },
              body: 
               { name: 'Marketing Campaign',
                 trigger: { code: 'M' },
                 template: 'Hi {{{contact.firstName}}}',
                 reporting: { when: 'NoReport' } },
              json: true };

            request(options, function (error, response, body) {
              if (error) throw new Error(error);

              console.log(body);
            });

        - lang: PHP
          source: |
            <?php
              $request = new HttpRequest();
              $request->setUrl('https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/campaigns/{{CAMPAIGN_ID}}');
              $request->setMethod(HTTP_METH_POST);
              
              $request->setHeaders(array(
                'Authorization' => 'Bearer {{TOKEN}}',
                'Content-Type' => 'application/json'
              ));
              
              $request->setBody('{
                "name": "Marketing Campaign",
                "trigger": {
                  "code":"M"
                },
                "template":"Hi {{{contact.firstName}}}",
                "reporting":{"when":"NoReport"}
              }');
              
              try {
                $response = $request->send();
              
                echo $response->getBody();
              } catch (HttpException $ex) {
                echo $ex;
              }
    delete:
      tags:
        - campaigns
      summary: Deletes a campaign
      operationId: campaigns.remove
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - name: campaignId
          in: path
          description: Campaign id to delete
          required: true
          schema:
            type: string
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []
      x-code-samples:
        - lang: CURL
          source: |
            curl -X DELETE \
              https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/campaigns/{{CAMPAIGN_ID}} \
              -H 'Authorization: Bearer {{TOKEN}}'
        - lang: JavaScript
          source: |
            var request = require("request");
            var options = { method: 'DELETE',
              url: 'https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/campaigns/{{CAMPAIGN_ID}}',
              headers: 
               { Authorization: 'Bearer {{TOKEN}}' } };

            request(options, function (error, response, body) {
              if (error) throw new Error(error);

              console.log(body);
            });

        - lang: PHP
          source: |
            <?php
              $request = new HttpRequest();
              $request->setUrl('https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/campaigns/{{CAMPAIGN_ID}}');
              $request->setMethod(HTTP_METH_DELETE);
              
              $request->setHeaders(array(
                'Authorization' => 'Bearer {{TOKEN}}'
              ));
              
              try {
                $response = $request->send();
              
                echo $response->getBody();
              } catch (HttpException $ex) {
                echo $ex;
              }

  /v1/accounts/{accountId}/conversations:
    get:
      tags:
        - conversations
      summary: Fetch conversations
      operationId: conversations.fetchAll
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/offset"
        - $ref: "#/components/parameters/limit"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ConversationsResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []
      x-code-samples:
        - lang: CURL
          source: |
            curl -X GET \
              https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/conversations \
              -H 'Authorization: Bearer {{TOKEN}}'
        - lang: JavaScript
          source: |
            var request = require("request");
            var options = { method: 'GET',
              url: 'https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/conversations',
              headers: 
               { Authorization: 'Bearer {{TOKEN}}' } };

            request(options, function (error, response, body) {
              if (error) throw new Error(error);

              console.log(body);
            });

        - lang: PHP
          source: |
            <?php
              $request = new HttpRequest();
              $request->setUrl('https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/conversations');
              $request->setMethod(HTTP_METH_GET);
              
              $request->setHeaders(array(
                'Authorization' => 'Bearer {{TOKEN}}'
              ));
              
              try {
                $response = $request->send();
              
                echo $response->getBody();
              } catch (HttpException $ex) {
                echo $ex;
              }

  /v1/accounts/{accountId}/conversations/{conversationId}:
    get:
      tags:
        - conversations
      summary: Fetch conversation by ID
      operationId: conversations.fetch
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - name: conversationId
          in: path
          description: ID of template to return
          required: true
          schema:
            type: string
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ConversationResponse"
      security:
        - sakari_auth: []
      x-code-samples:
        - lang: CURL
          source: |
            curl -X GET \
              https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/conversations/{{CONVERSATION_ID}} \
              -H 'Authorization: Bearer {{TOKEN}}'
        - lang: JavaScript
          source: |
            var request = require("request");
            var options = { method: 'GET',
              url: 'https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/conversations/{{CONVERSATION_ID}}',
              headers: 
               { Authorization: 'Bearer {{TOKEN}}' } };

            request(options, function (error, response, body) {
              if (error) throw new Error(error);

              console.log(body);
            });

        - lang: PHP
          source: |
            <?php
              $request = new HttpRequest();
              $request->setUrl('https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/conversations/{{CONVERSATION_ID}}');
              $request->setMethod(HTTP_METH_GET);
              
              $request->setHeaders(array(
                'Authorization' => 'Bearer {{TOKEN}}'
              ));
              
              try {
                $response = $request->send();
              
                echo $response->getBody();
              } catch (HttpException $ex) {
                echo $ex;
              }

  /v1/accounts/{accountId}/conversations/{conversationId}/close:
    put:
      tags:
        - conversations
      summary: Closes a conversation
      operationId: conversations.close
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - name: conversationId
          in: path
          description: ID of conversation
          required: true
          schema:
            type: string
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ConversationResponse"
      security:
        - sakari_auth: []
      x-code-samples:
        - lang: CURL
          source: |
            curl -X GET \
              https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/conversations/{{CONVERSATION_ID}}/close \
              -H 'Authorization: Bearer {{TOKEN}}'
        - lang: JavaScript
          source: |
            var request = require("request");
            var options = { method: 'GET',
              url: 'https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/conversations/{{CONVERSATION_ID}}/close',
              headers: 
               { Authorization: 'Bearer {{TOKEN}}' } };

            request(options, function (error, response, body) {
              if (error) throw new Error(error);

              console.log(body);
            });

        - lang: PHP
          source: |
            <?php
              $request = new HttpRequest();
              $request->setUrl('https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/conversations/{{CONVERSATION_ID}}/close');
              $request->setMethod(HTTP_METH_PUT);
              
              $request->setHeaders(array(
                'Authorization' => 'Bearer {{TOKEN}}',
                'Content-Type' => 'application/json'
              ));
              
              $request->setBody('{
                "name": "Test Template",
                "template": "Hi {{ firstName }}, Welcome to Sakari!",
                "type": "SMS"
              }');
              
              try {
                $response = $request->send();
              
                echo $response->getBody();
              } catch (HttpException $ex) {
                echo $ex;
              }

  /v1/accounts/{accountId}/links:
    get:
      tags:
        - links
      summary: Fetch links
      operationId: links.fetch
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/q"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/LinksResponse"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/links/{linkId}:
    get:
      tags:
        - links
      summary: Fetch link by ID
      operationId: links.fetchById
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/linkIdPath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/LinkResponse"
      security:
        - sakari_auth: []
    delete:
      tags:
        - links
      summary: Delete link by ID
      operationId: links.deleteById
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/linkIdPath"
      responses:
        204:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "./common.yaml#/schemas/BasicResponse"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/links/{linkId}/sources:
    get:
      tags:
        - links
      summary: Fetch link sources
      operationId: links.fetchSources
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/linkIdPath"
        - name: sources
          in: query
          description: Sources to analyse
          required: false
          schema:
            type: string
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/LinkSourcesResponse"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/links/{linkId}/sources/{sourceId}:
    get:
      tags:
        - links
      summary: Fetch link source by ID
      operationId: links.fetchSourceById
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - name: linkId
          in: path
          description: ID of link to return
          required: true
          schema:
            type: string
        - name: sourceId
          in: path
          description: Source to analyse
          required: true
          schema:
            type: string
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/LinkSourceResponse"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/links/{linkId}/sources/{sourceId}/stats:
    get:
      tags:
        - links
      summary: Fetch link source by ID
      operationId: links.fetchSourceStatsById
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - name: linkId
          in: path
          description: ID of link to return
          required: true
          schema:
            type: string
        - name: sourceId
          in: path
          description: Source to analyse
          required: true
          schema:
            type: string
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/LinkSourceStatsResponse"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/forms:
    get:
      tags:
        - forms
      summary: Fetch all lead forms
      operationId: forms.fetchAll
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/q"
        - $ref: "#/components/parameters/offset"
        - $ref: "#/components/parameters/limit"
        - $ref: "#/components/parameters/orderBy"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FormsResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []
    post:
      tags:
        - forms
      summary: Create lead form
      operationId: forms.create
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/formTemplateId"
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Form"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FormResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/forms/templates:
    get:
      tags:
        - forms
      summary: Fetch all lead form templates
      operationId: forms.templates.fetchAll
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/q"
        - $ref: "#/components/parameters/offset"
        - $ref: "#/components/parameters/limit"
        - $ref: "#/components/parameters/orderBy"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FormsResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/forms/{formId}:
    get:
      tags:
        - forms
      summary: Fetch lead form info
      operationId: forms.fetch
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/formIdPath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FormResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []
    put:
      tags:
        - forms
      summary: Update lead form
      operationId: forms.update
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/formIdPath"
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Form"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FormResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []
    delete:
      tags:
        - forms
      summary: Delete a lead form
      operationId: forms.delete
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/formIdPath"
      responses:
        204:
          description: successful operation
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/forms/{formId}/activate:
    put:
      tags:
        - forms
      summary: Activate an existing form
      operationId: forms.activate
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/formIdPath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FormResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/forms/{formId}/deactivate:
    put:
      tags:
        - forms
      summary: Deactivate an existing form
      operationId: forms.deactivate
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/formIdPath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FormResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/forms/{formId}/conversions:
    get:
      tags:
        - forms
      summary: Fetch lead form conversion data
      operationId: forms.fetchConversions
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/formIdPath"
        - $ref: "#/components/parameters/start"
        - $ref: "#/components/parameters/end"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FormConversionsResponse"
            text/csv:
              schema:
                type: string
                example: >
                  ip,page_url,contact_first_name,contact_last_name,contact_mobile,contact_country,contact_email,submitted,submitted_mobile
                  127.0.0.1,https://sakari.io,Niel,Papworth,+15555550123,US,help@sakari.io,2024-07-24T16:37:06.282Z,+15555550123
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/forms/{formId}/analytics:
    get:
      tags:
        - forms
      summary: Fetch lead form analytic data
      operationId: forms.fetchAnalytics
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/formIdPath"
        - $ref: "#/components/parameters/start"
        - $ref: "#/components/parameters/end"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FormAnalyticsResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/tools/sharefile:
    post:
      tags:
        - tools
      summary: Share file - use to host a file and generate a short link to be used directly in a message or as a link to media for a MMS
      operationId: tools.shareFile
      requestBody:
        required: true
        content:
          application/octet-stream:
            schema:
              type: string
              format: binary
          multipart/form-data:
            schema:
              type: object
              properties:
                media:
                  type: string
                  format: binary
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ShareFileResponse"
        4XX:
          description: invalid request
          content:
            application/json:
              schema:
                $ref: "./common.yaml#/schemas/BasicResponse"
        5XX:
          description: invalid request
          content:
            application/json:
              schema:
                $ref: "./common.yaml#/schemas/BasicResponse"
      security:
        - sakari_auth: []

  # /v1/accounts/{accountId}/supportinfo:
  #   put:
  #     tags:
  #     - accounts
  #     summary: update the account's support info
  #     operationId: accounts.update
  #     parameters:
  #     - $ref: '#/components/parameters/accountIdPath'
  #     requestBody:
  #       required: true
  #       content:
  #         application/json:
  #           schema:
  #             $ref: '#/components/schemas/SupportInfo'
  #     responses:
  #       200:
  #         description: successful operation
  #         content:
  #           application/json:
  #             schema:
  #               $ref: '#/components/schemas/SupportInfoResponse'
  #       4XX:
  #         $ref: '#/responses/4XX'
  #       5XX:
  #         $ref: '#/responses/5XX'
  #     security:
  #     - sakari_auth: []

  /v1/accounts/{accountId}/webhooks:
    get:
      tags:
        - webhooks
      summary: Fetch active webhooks
      description: When messages are acknowledge by carriers, a notification is sent to the specified URL
      operationId: webhooks.fetchAll
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WebhooksResponse"
      security:
        - sakari_auth: []
      x-code-samples:
        - lang: CURL
          source: |
            curl -X GET \
              https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/webhooks \
              -H 'Authorization: Bearer {{TOKEN}}' \
              -d '{
              "url": "https://requestbin.io"
            }'
        - lang: JavaScript
          source: |
            var settings = {
              "async": true,
              "crossDomain": true,
              "url": "https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/webhooks",
              "method": "GET",
              "headers": {
                "Authorization": "Bearer {{TOKEN}}"
              },
              "data": "{\n\t\"url\": \"https://requestbin.io\"\n}"
            }

            $.ajax(settings).done(function (response) {
              console.log(response);
            });
        - lang: PHP
          source: |
            <?php
              $request = new HttpRequest();
              $request->setUrl('https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/webhooks');
              $request->setMethod(HTTP_METH_GET);
              
              $request->setHeaders(array(
                'Authorization' => 'Bearer {{TOKEN}}'
              ));
              
              $request->setBody('{
                "url": "https://requestbin.io"
              }');
              
              try {
                $response = $request->send();
              
                echo $response->getBody();
              } catch (HttpException $ex) {
                echo $ex;
              }
    post:
      tags:
        - webhooks
      summary: Subscribe to message events
      description: When messages are acknowledge by carriers, a notification is sent to the specified URL
      operationId: webhooks.subscribe
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                url: # Callback URL
                  type: string
                  format: uri
                  example: https://myserver.com/send/callback/here
                eventTypes:
                  type: array
                  items:
                    type: string
                    enum:
                      [
                        "contact-created",
                        "contact-updated",
                        "contact-removed",
                        "message-received",
                        "message-sent",
                        "message-status",
                        "conversation-started",
                        "contact-opt-out",
                        "contact-opt-in",
                        "list-opt-out",
                        "list-opt-in",
                      ]
              required:
                - callbackUrl
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WebhookResponse"
      security:
        - sakari_auth: []
      x-code-samples:
        - lang: CURL
          source: |
            curl -X POST \
              https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/webhooks \
              -H 'Authorization: Bearer {{TOKEN}}' \
              -H 'Content-Type: application/json' \
              -d '{
              "url": "https://requestbin.io",
              "eventTypes": ["message-received"]
            }'
        - lang: JavaScript
          source: |
            var request = require("request");
            var options = { method: 'POST',
              url: 'https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/webhooks',
              headers: 
               { Authorization: 'Bearer {{TOKEN}}',
                 'Content-Type': 'application/json' },
              body: { url: 'https://requestbin.io', eventTypes: [ 'message-received' ] },
              json: true };

            request(options, function (error, response, body) {
              if (error) throw new Error(error);

              console.log(body);
            });

        - lang: PHP
          source: |
            <?php
              $request = new HttpRequest();
              $request->setUrl('https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/webhooks');
              $request->setMethod(HTTP_METH_POST);
              
              $request->setHeaders(array(
                'Authorization' => 'Bearer {{TOKEN}}',
                'Content-Type' => 'application/json'
              ));
              
              $request->setBody('{
                "url": "https://requestbin.io",
                "eventTypes": ["message-received"]
              }');
              
              try {
                $response = $request->send();
              
                echo $response->getBody();
              } catch (HttpException $ex) {
                echo $ex;
              }

  /v1/accounts/{accountId}/webhooks/{url}:
    delete:
      tags:
        - webhooks
      summary: Unsubscribe to message events
      description: Delete subscription for receiving notifications
      operationId: webhooks.unsubscribe
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - name: url
          in: path
          description: Account to apply operations to
          required: true
          schema:
            type: string
      responses:
        204:
          description: successful operation
      security:
        - sakari_auth: []
      x-code-samples:
        - lang: CURL
          source: |
            curl -X DELETE \
              https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/webhooks/{{URL_ENCODED CALLBACK_URL}} \
              -H 'Authorization: Bearer {{TOKEN}}'
        - lang: JavaScript
          source: |
            var request = require("request");
            var options = { method: 'DELETE',
              url: 'https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/webhooks/{{URL_ENCODED CALLBACK_URL}}',
              headers: 
               { Authorization: 'Bearer {{TOKEN}}' };

            request(options, function (error, response, body) {
              if (error) throw new Error(error);

              console.log(body);
            });

        - lang: PHP
          source: |
            <?php
              $request = new HttpRequest();
              $request->setUrl('https://api.sakari.io/v1/accounts/{{ACCOUNT_ID}}/webhooks/{{URL_ENCODED CALLBACK_URL}}');
              $request->setMethod(HTTP_METH_DELETE);
              
              $request->setHeaders(array(
                'Authorization' => 'Bearer {{TOKEN}}'
              ));
              
              try {
                $response = $request->send();
              
                echo $response->getBody();
              } catch (HttpException $ex) {
                echo $ex;
              }

  /v1/accounts/{accountId}/workflows:
    get:
      tags:
        - workflows
      summary: Fetch Account Workflows
      operationId: accounts.workflows.fetchAll
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/offset"
        - $ref: "#/components/parameters/limit"
        - $ref: "#/components/parameters/workflowType"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WorkflowsResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

    post:
      tags:
        - workflows
      summary: Create a workflow
      operationId: workflows.create
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateWorkflowRequest"

      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WorkflowResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/workflows/{workflowId}:
    get:
      tags:
        - workflows
      summary: Fetch a workflow
      operationId: workflows.fetch
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/workflowIdPath"

      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WorkflowResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

    put:
      tags:
        - workflows
      summary: Edit a workflow
      operationId: workflows.update
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/workflowIdPath"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Workflow"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WorkflowResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

    delete:
      tags:
        - workflows
      summary: Deletes a workflow
      operationId: workflows.delete
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/workflowIdPath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                properties:
                  success:
                    type: boolean
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/workflows/{workflowId}/versions:
    post:
      tags:
        - workflows
      summary: Clone a version of a workflow
      operationId: workflows.versions.clone
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/workflowIdPath"

      requestBody:
        content:
          application/json:
            schema:
              anyOf:
                - $ref: "#/components/schemas/Workflow"

      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WorkflowVersionResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

    get:
      tags:
        - workflows
      summary: Get All Versions of a Workflow
      operationId: workflows.versions
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/workflowIdPath"

      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WorkflowVersionsResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/workflows/{workflowId}/clone:
    post:
      tags:
        - workflows
      summary: Duplicate a workflow
      operationId: workflows.duplicate
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/workflowIdPath"

      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                version:
                  type: number

      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WorkflowResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/workflows/{workflowId}/versions/{versionId}:
    get:
      tags:
        - workflows
      summary: Get a version of a Workflow
      operationId: workflows.versions.get
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/workflowIdPath"
        - $ref: "#/components/parameters/workflowVersionIdPath"

      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WorkflowVersionResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

    put:
      tags:
        - workflows
      summary: Edit a version of a Workflow
      operationId: workflows.versions.update
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/workflowIdPath"
        - $ref: "#/components/parameters/workflowVersionIdPath"

      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WorkflowDefinition"

      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WorkflowVersionResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

    delete:
      tags:
        - workflows
      summary: Remove a version of a Workflow
      operationId: workflows.versions.delete
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/workflowIdPath"
        - $ref: "#/components/parameters/workflowVersionIdPath"

      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/workflows/{workflowId}/versions/{versionId}/properties:
    post:
      tags:
        - workflows
      summary: Create a workflow property for a version of a workflow
      operationId: workflows.versions.properties.create
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/workflowIdPath"
        - $ref: "#/components/parameters/workflowVersionIdPath"

      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WorkflowProperty"

      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WorkflowPropertyResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

    get:
      tags:
        - workflows
      summary: Fetch All Workflow Properties for a Version
      operationId: workflows.versions.properties.fetchAll
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/workflowIdPath"
        - $ref: "#/components/parameters/workflowVersionIdPath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WorkflowPropertiesResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/workflows/{workflowId}/nodes:
    post:
      tags:
        - workflows
      summary: Create a node for a version of the workflow
      operationId: workflows.versions.nodes.create
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/workflowIdPath"

      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WorkflowNode"

      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WorkflowNodeResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/workflows/{workflowId}/nodes/{nodeId}:
    put:
      tags:
        - workflows
      summary: Update a node for a version of the workflow
      operationId: workflows.versions.nodes.update
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/workflowIdPath"
        - $ref: "#/components/parameters/workflowNodeIdPath"

      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EditWorkflowNodeRequest"
              # $ref: '#/components/schemas/WorkflowNodeConfig'

      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WorkflowNode"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

    delete:
      tags:
        - workflows
      summary: Delete a node for a version of the workflow
      operationId: workflows.versions.nodes.delete
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/workflowIdPath"
        - $ref: "#/components/parameters/workflowNodeIdPath"
        - $ref: "#/components/parameters/workflowNodeEdgeRemoveBehavior"
        - $ref: "#/components/parameters/nodeToConnect"

      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                properties:
                  success:
                    type: boolean
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/workflows/{workflowId}/edges:
    post:
      tags:
        - workflows
      summary: Create an Edge for a version of the workflow
      operationId: workflows.versions.edges.create
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/workflowIdPath"

      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WorkflowEdgeResponse"

      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WorkflowEdgeResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/workflows/{workflowId}/edges/{edgeId}:
    put:
      tags:
        - workflows
      summary: Update an Edge for a version of the workflow
      operationId: workflows.versions.edges.update
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/workflowIdPath"
        - $ref: "#/components/parameters/workflowEdgeIdPath"

      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WorkflowEdgeResponse"

      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WorkflowEdge"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

    delete:
      tags:
        - workflows
      summary: Delete an Edge for a version of the workflow
      operationId: workflows.versions.edges.delete
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/workflowIdPath"
        - $ref: "#/components/parameters/workflowEdgeIdPath"

      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                properties:
                  success:
                    type: boolean
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/workflows/{workflowId}/publish:
    post:
      tags:
        - workflows
      summary: Publish a Workflow
      operationId: workflows.versions.publish
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/workflowIdPath"

      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                properties:
                  success:
                    type: boolean
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/workflows/{workflowId}/deactivate:
    delete:
      tags:
        - workflows
      summary: Deactivate a Workflow
      operationId: workflows.versions.deactivate
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/workflowIdPath"

      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                properties:
                  success:
                    type: boolean
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/workflowtemplates:
    get:
      tags:
        - workflowtemplates
      summary: Fetch Workflow Templates
      operationId: workflowtemplates.fetchAll
      parameters:
        - $ref: "#/components/parameters/offset"
        - $ref: "#/components/parameters/limit"
        - $ref: "#/components/parameters/workflowType"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WorkflowTemplatesResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/workflowtemplates/{workflowTemplateId}:
    get:
      tags:
        - workflowtemplates
      summary: Fetch a Workflow Template
      operationId: workflowtemplates.fetch
      parameters:
        - $ref: "#/components/parameters/workflowTemplateIdPath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WorkflowTemplateResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

      # callbacks:
      #   event: # Event name
      #     '{$request.body#/callbackUrl}': # The callback URL, Refers to the passed URL
      #       post:
      #         requestBody: # Contents of the callback message
      #           required: true
      #           content:
      #             application/json:
      #               schema:
      #                 $ref: '#/components/schemas/Event'
      #         responses: # Expected responses to the callback message
      #           '200':
      #             description: Your server returns this code if it accepts the callback

  /v1/accounts/{accountId}/workflows/{workflowId}/executions:
    get:
      tags:
        - workflows
      summary: Fetch Workflow Summary for a Single Contact
      operationId: accounts.workflows.executions.fetchAll
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/offset"
        - $ref: "#/components/parameters/limit"
        - $ref: "#/components/parameters/workflowIdPath"
        - $ref: "#/components/parameters/contactId"
        - $ref: "#/components/parameters/status"
        - $ref: "#/components/parameters/start"
        - $ref: "#/components/parameters/end"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WorkflowExecutionsResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/workflows/{workflowId}/executions/{executionId}:
    get:
      tags:
        - workflows
      summary: Fetch A Detailed Summary for a Workflow Execution for a Contact
      operationId: accounts.workflows.executions.fetch
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/workflowIdPath"
        - $ref: "#/components/parameters/executionIdPath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WorkflowDetailedExecutionResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/workflows/{workflowId}/versions/{versionId}/metrics:
    get:
      tags:
        - workflows
      summary: Fetch A General Summary of Edges traveled
      operationId: accounts.workflows.executions.metrics
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/workflowIdPath"
        - $ref: "#/components/parameters/workflowVersionIdPath"
        - $ref: "#/components/parameters/start"
        - $ref: "#/components/parameters/end"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WorkflowVersionMetricsResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/prices:
    get:
      tags:
        - pricing
      summary: get cost per segment based on your desired plan commitment
      operationId: pricing.fetch
      parameters:
        - $ref: "#/components/parameters/plan"
        - $ref: "#/components/parameters/country"
        - $ref: "#/components/parameters/frequency"
        - $ref: "#/components/parameters/commitment"
        - $ref: "#/components/parameters/credit"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PricingResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"

  /v1/accounts/{accountId}/dripcampaigns:
    post:
      tags:
        - dripcampaigns
      summary: Create a Drip Campaign
      operationId: accounts.dripcampaigns.create
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateUpdateDripCampaign"

      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DripCampaignResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

    get:
      tags:
        - dripcampaigns
      summary: Fetch Account Drip Campaigns
      operationId: accounts.dripcampaigns.fetchAll
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/offset"
        - $ref: "#/components/parameters/limit"

      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DripCampaignsResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"

  /v1/accounts/{accountId}/dripcampaigns/{dripCampaignId}:
    get:
      tags:
        - dripcampaigns
      summary: Fetch a drip campaign
      operationId: accounts.dripcampaigns.fetch
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/dripCampaignIdPath"

      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DripCampaignResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

    put:
      tags:
        - dripcampaigns
      summary: Edit a Drip Campaign
      operationId: accounts.dripcampaigns.update
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/dripCampaignIdPath"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateUpdateDripCampaign"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DripCampaignResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

    delete:
      tags:
        - dripcampaigns
      summary: Deletes a drip campaign
      operationId: accounts.dripcampaigns.delete
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/dripCampaignIdPath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                properties:
                  success:
                    type: boolean
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/dripcampaigns/{dripCampaignId}/duplicate:
    post:
      tags:
        - dripcampaigns
      summary: Duplicate a Drip Campaign
      operationId: accounts.dripcampaigns.duplicate
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/dripCampaignIdPath"

      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DripCampaignResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/dripcampaigns/{dripCampaignId}/activate:
    put:
      tags:
        - dripcampaigns
      summary: Activate a Drip Campaign
      operationId: accounts.dripcampaigns.activate
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/dripCampaignIdPath"

      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                properties:
                  success:
                    type: boolean
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/dripcampaigns/{dripCampaignId}/deactivate:
    put:
      tags:
        - dripcampaigns
      summary: Deactivate a drip campaign
      operationId: accounts.dripcampaigns.deactivate
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/dripCampaignIdPath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                properties:
                  success:
                    type: boolean
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/dripcampaigns/{dripCampaignId}/migrate:
    put:
      tags:
        - dripcampaigns
      summary: Transform a drip campaign to a workflow
      operationId: accounts.dripcampaigns.migrate
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/dripCampaignIdPath"
      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WorkflowResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  # /v1/accounts/{accountId}/dripcampaigns/{dripCampaignId}/stats:
  #   get:
  #     tags:
  #       - dripcampaigns
  #     summary: Fetch reports for a drip campaign
  #     operationId: accounts.dripcampaigns.stats
  #     parameters:
  #       - $ref: "#/components/parameters/accountIdPath"
  #       - $ref: "#/components/parameters/dripCampaignIdPath"
  #       - $ref: "#/components/parameters/versionId"

  #     responses:
  #       200:
  #         description: successful operation
  #         content:
  #           application/json:
  #             schema:
  #               $ref: "#/components/schemas/DripCampaignReportResponse"
  #       4XX:
  #         $ref: "./common.yaml#/responses/4XX"
  #       5XX:
  #         $ref: "./common.yaml#/responses/5XX"
  #     security:
  #       - sakari_auth: []

  /v1/accounts/{accountId}/dripcampaigns/{dripCampaignId}/executions:
    get:
      tags:
        - dripcampaigns
      summary: Fetch executions for dripcampaigns
      operationId: accounts.dripcampaigns.executions
      parameters:
        - $ref: "#/components/parameters/accountIdPath"
        - $ref: "#/components/parameters/dripCampaignIdPath"
        - $ref: "#/components/parameters/versionId"
        - $ref: "#/components/parameters/offset"

      responses:
        200:
          description: successful operation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DripCampaignExecutionsResponse"
        4XX:
          $ref: "./common.yaml#/responses/4XX"
        5XX:
          $ref: "./common.yaml#/responses/5XX"
      security:
        - sakari_auth: []

  /v1/accounts/{accountId}/meetings:
    $ref: "./meetings.yaml#/paths/Meetings"
  
  /v1/accounts/{accountId}/meetings/{meetingId}:
    $ref: "./meetings.yaml#/paths/Meeting"

  /v1/accounts/{accountId}/meetings/{meetingId}/cancel:
    $ref: "./meetings.yaml#/paths/CancelMeeting"

  /v1/accounts/{accountId}/meetingevents:
    $ref: "./meetings.yaml#/paths/MeetingEvents"

  /v1/accounts/{accountId}/meetingevents/{meetingEventId}:
    $ref: "./meetings.yaml#/paths/MeetingEvent"

  /v1/accounts/{accountId}/meetingevents/{meetingEventId}/enable:
    $ref: "./meetings.yaml#/paths/EnableMeetingEvent"

  /v1/accounts/{accountId}/meetingevents/{meetingEventId}/disable:
    $ref: "./meetings.yaml#/paths/DisableMeetingEvent"

  /v1/accounts/{accountId}/meetingevents/{meetingEventId}/duplicate:
    $ref: "./meetings.yaml#/paths/DuplicateMeetingEvent"

  # API to Check to see if slug is available for a meeting
  /v1/slugs/meetingevents/{slug}:
    $ref: "./meetings.yaml#/paths/CheckSlugAvailability"

externalDocs:
  description: Find out more about Sakari
  url: "https://sakari.io"

components:
  parameters:
    # path params
    accountIdPath:
      name: accountId
      in: path
      description: Account to apply operations to
      required: true
      schema:
        type: string

    attributeTypePath:
      name: attributeType
      in: path
      description: Type of custom attribute
      required: true
      schema:
        type: string
        enum:
          - contacts
          - deals
          - tickets

    attributeIdPath:
      name: attributeId
      in: path
      description: ID of attribute
      required: true
      schema:
        type: string

    autoresponderIdPath:
      name: autoresponderId
      in: path
      description: Autoresponder to apply operations to
      required: true
      schema:
        type: string

    contactIdPath:
      name: contactId
      in: path
      description: Contact ID
      required: true
      schema:
        type: string

    countryPath:
      name: country
      in: path
      description: Country in question
      required: true
      schema:
        type: string

    linkIdPath:
      name: linkId
      in: path
      description: ID of link
      required: true
      schema:
        type: string

    formIdPath:
      name: formId
      in: path
      description: Lead Form to apply operations to
      required: true
      schema:
        type: string

    workflowIdPath:
      name: workflowId
      in: path
      description: Workflow to apply operations to
      required: true
      schema:
        type: string

    workflowVersionIdPath:
      name: versionId
      in: path
      description: Workflow version to apply operations to
      required: true
      schema:
        type: string

    workflowNodeIdPath:
      name: nodeId
      in: path
      description: Node id for a version of a workflow
      required: true
      schema:
        type: string

    workflowEdgeIdPath:
      name: edgeId
      in: path
      description: Edge id for a version of a workflow
      required: true
      schema:
        type: string

    workflowTemplateIdPath:
      name: workflowTemplateId
      in: path
      description: Workflow Template Id used
      required: true
      schema:
        type: string

    executionIdPath:
      name: executionId
      in: path
      description: Id for a workflow Execution
      required: true
      schema:
        type: string

    dripCampaignIdPath:
      name: dripCampaignId
      in: path
      description: Drip Campaign to apply operations to
      required: true
      schema:
        type: string

    # query params
    offset:
      name: offset
      in: query
      description: Results to skip when paginating through a result set
      required: false
      schema:
        type: integer
        format: int64
        minimum: 0

    limit:
      name: limit
      in: query
      description: Maximum number of results to return
      required: false
      schema:
        type: integer
        format: int64
        minimum: 1
        maximum: 100

    orderBy:
      name: orderBy
      in: query
      description: Sort the return results
      required: false
      schema:
        type: string

    callId:
      name: callId
      in: path
      description: ID of call
      required: true
      schema:
        type: string

    recordingId:
      name: recordingId
      in: path
      description: ID of recording
      required: true
      schema:
        type: string

    contactId:
      name: contactId
      in: query
      description: ID of contact
      required: false
      schema:
        type: string

    phonenumberId:
      name: phonenumberId
      in: query
      description: ID of the Sakari phone number
      required: false
      schema:
        type: string

    userId:
      name: userId
      in: query
      description: ID of user
      required: false
      schema:
        type: string

    groupId:
      name: groupId
      in: query
      description: ID of group
      required: false
      schema:
        type: string

    callDirection:
      name: direction
      in: query
      description: Direction of call
      required: false
      schema:
        $ref: "#/components/schemas/CallDirection"

    callStatus:
      name: status
      in: query
      description: Status of call
      required: false
      schema:
        $ref: "#/components/schemas/CallStatus"

    from:
      name: from
      in: query
      description: Start date
      required: false
      schema:
        type: string
        format: date-time

    to:
      name: to
      in: query
      description: End date
      required: false
      schema:
        type: string
        format: date-time

    firstName:
      name: firstName
      in: query
      description: Filter by first name or part of
      required: false
      schema:
        type: string

    lastName:
      name: lastName
      in: query
      description: Filter by last name or part of
      required: false
      schema:
        type: string

    name:
      name: name
      in: query
      description: Filter by name or part of
      required: false
      schema:
        type: string

    mobile:
      name: mobile
      in: query
      description: Filter by mobile or part of
      required: false
      schema:
        type: string

    email:
      name: email
      in: query
      description: Filter by email or part of
      required: false
      schema:
        type: string

    tags:
      name: tags
      in: query
      description: Filter by tag(s)
      required: false
      schema:
        type: string

    conversationId:
      name: conversationId
      in: query
      description: ID of conversation
      required: false
      schema:
        type: string

    country:
      name: country
      in: query
      description: Country in question
      required: false
      schema:
        type: string

    type:
      name: type
      in: query
      description: Phone number type
      required: false
      schema:
        type: string

    features:
      name: features
      in: query
      description: Features for phone number
      required: false
      schema:
        type: string

    areaCode:
      name: areaCode
      in: query
      description: Area Code for phone number
      required: false
      schema:
        type: string

    contains:
      name: contains
      in: query
      description: What should be in the string
      required: false
      schema:
        type: string

    postalCode:
      name: postalCode
      in: query
      description: Postal code for Number
      required: false
      schema:
        type: string

    workflowType:
      name: type
      in: query
      description: Type of Workflow
      required: false
      schema:
        type: string

    workflowNodeEdgeRemoveBehavior:
      name: behavior
      in: query
      description: Deletion Behavior for a Node or Edge
      schema:
        type: string

    nodeToConnect:
      name: path
      in: query
      description: Node to connect to on node delete
      schema:
        type: string

    q:
      name: q
      in: query
      description: General search term that searchs accross multiple fields
      schema:
        type: string

    start:
      name: start
      in: query
      description: General search term that specifies start date
      schema:
        type: string

    end:
      name: end
      in: query
      description: General search term that specifies end date
      schema:
        type: string

    status:
      name: status
      in: query
      description: General search term that specifies status
      schema:
        type: string

    checkoutSuccessUrl:
      name: success_url
      in: query
      description: after successful checkout redirect to this url
      schema:
        type: string

    checkoutCancelUrl:
      name: cancel_url
      in: query
      description: after cancelling checkout redirect to this url
      schema:
        type: string

    plan:
      name: plan
      in: query
      description: name of the desired plan. defaults to standard
      schema:
        type: string

    versionId:
      name: versionId
      in: query
      description: versionId of the desired Workflow Version
      required: false
      schema:
        type: string

    frequency:
      name: frequency
      in: query
      description: billing frequency of desired plan. either monthly or annual
      schema:
        type: string

    commitment:
      name: commitment
      in: query
      description: commitment you wish to pay for desired plan
      schema:
        type: number

    credit:
      name: credit
      in: query
      description: amount of credit you would like for desired plan
      schema:
        type: number

    formTemplateId:
      name: template
      in: query
      description: Id of the form template you wish to clone
      required: false
      schema:
        type: string

    meetingEventIdPath:
      $ref: "./meetings.yaml#/components/parameters/meetingEventIdPath"
    meetingIdPath:
      $ref: "./meetings.yaml#/components/parameters/meetingIdPath"
    slug: 
      $ref: "./meetings.yaml#/components/parameters/slug"
    attendee: 
      $ref: "./meetings.yaml#/components/parameters/attendee"
    mhost: 
      $ref: "./meetings.yaml#/components/parameters/mhost"
    # name: 
    #   $ref: "./meetings.yaml#/components/parameters/name"
    date: 
      $ref: "./meetings.yaml#/components/parameters/date"
    duration: 
      $ref: "./meetings.yaml#/components/parameters/duration"
    # status: 
    #   $ref: "./meetings.yaml#/components/parameters/status"

    # eventType:
    #   type: string
    #   example: message
    #   enum:
    #   - account
    #   - message

  schemas:
    #Common
    Address:
      $ref: "./common.yaml#/schemas/Address"
    BasicResponse:
      $ref: "./common.yaml#/schemas/BasicResponse"
    Country:
      $ref: "./common.yaml#/schemas/Country"
    Error:
      $ref: "./common.yaml#/schemas/Error"
    ErrorResponse:
      $ref: "./common.yaml#/schemas/ErrorResponse"
    Pagination:
      $ref: "./common.yaml#/schemas/Pagination"
    PaginatedResponse:
      $ref: "./common.yaml#/schemas/PaginatedResponse"
    TaxType:
      $ref: "./common.yaml#/schemas/TaxType"
    UpdatedBy:
      $ref: "./common.yaml#/schemas/UpdatedBy"
    Updated:
      $ref: "./common.yaml#/schemas/Updated"

    # Accounts
    AccountBalance:
      $ref: "./accounts.yaml#/schemas/AccountBalance"
    AccountDefaults:
      $ref: "./accounts.yaml#/schemas/AccountDefaults"
    AutoEnroll:
      $ref: "./accounts.yaml#/schemas/AutoEnroll"
    AutoTopup:
      $ref: "./accounts.yaml#/schemas/AutoTopup"
    Domain:
      $ref: "./accounts.yaml#/schemas/Domain"
    SupportInfo:
      $ref: "./accounts.yaml#/schemas/SupportInfo"
    BillingInfo:
      $ref: "./accounts.yaml#/schemas/BillingInfo"
    TaxInfo:
      $ref: "./accounts.yaml#/schemas/TaxInfo"
    AccountIntegration:
      $ref: "./accounts.yaml#/schemas/AccountIntegration"
    AccountOptions:
      $ref: "./accounts.yaml#/schemas/AccountOptions"
    ActiveCampaign:
      $ref: "./accounts.yaml#/schemas/ActiveCampaign"
    ApiCredential:
      $ref: "./accounts.yaml#/schemas/ApiCredential"
    Account:
      $ref: "./accounts.yaml#/schemas/Account"
    AccountResponse:
      $ref: "./accounts.yaml#/responses/AccountResponse"
    AccountsResponse:
      $ref: "./accounts.yaml#/responses/AccountsResponse"
    
    # Pricing:
    Plan:
      $ref: "./pricing.yaml#/schemas/Plan"
    Pricing:
      $ref: "./pricing.yaml#/schemas/Pricing"
    RegulatoryPricing:
      $ref: "./pricing.yaml#/schemas/RegulatoryPricing"
    PlanResponse: 
      $ref: "./pricing.yaml#/responses/PlanResponse"
    
    # Authentication
    TokenRequest:
      type: object
      properties:
        grant_type:
          type: string
          example: client_credentials
        client_id:
          type: string
          example: 00000000-0000-0000-0000-00000000000
        client_secret:
          type: string
          example: 00000000-0000-0000-0000-00000000000

    TokenResponse:
      type: object
      properties:
        access_token:
          type: string
        token_type:
          type: string

    # Common
    AccountId:
      type: string

    DataType:
      type: string
      enum:
        - string
        - boolean
        - number
        - date

    Role:
      type: string
      enum:
        - Administrator
        - CampaignManager
        - Sender
        - ReadOnly

    # EventType:
    #   type: string
    #   example: message
    #   enum:
    #   - account
    #   - messageStatus
    #   - messageIncoming

    WorkflowTemplateStatus:
      type: string
      enum:
        - active
        - internal

    InternationalNumber:
      $ref: "./common.yaml#/schemas/InternationalNumber"

    PaginationRequest:
      type: object
      properties:
        limit:
          type: number
        offset:
          type: number
        orderBy:
          type: string

    SearchablePaginationRequest:
      allOf:
        - $ref: "#/components/schemas/PaginationRequest"
        - type: object
          properties:
            q:
              type: string

    Time:
      $ref: "./common.yaml#/schemas/Time"

    Hours:
      $ref: "./common.yaml#/schemas/Hours"

    Times:
      $ref: "./common.yaml#/schemas/Times"

    AccountAttribute:
      $ref: "./customproperties.yaml#/schemas/AccountAttribute"

    AccountAttributeType:
      $ref: "./customproperties.yaml#/schemas/AccountAttributeType"

    AccountAttributeDataType:
      $ref: "./customproperties.yaml#/schemas/AccountAttributeDataType"

    Autoresponder:
      type: object
      properties:
        id:
          type: string
          readOnly: true
        match:
          type: string
        response:
          type: string
        advanced:
          type: boolean
          default: false
        scheduleType:
          type: string
          enum:
            - OOO
            - in office
            - custom
        customObject:
          type: object
        group:
          type: string
      required:
        - id
        - match
        - response

    # Integrations
    AvailableIntegration:
      $ref: "./integrations.yaml#/schemas/AvailableIntegration"
    AuthenticationParameter:
      $ref: "./integrations.yaml#/schemas/AuthenticationParameter"

    # Voice
    CallDirection:
      $ref: "./voice.yaml#/schemas/CallDirection"
    CallStatus:
      $ref: "./voice.yaml#/schemas/CallStatus"
    CallHistory:
      $ref: "./voice.yaml#/schemas/CallHistory"
    Recording:
      $ref: "./voice.yaml#/schemas/Recording"
    RecordingType:
      $ref: "./voice.yaml#/schemas/RecordingType"

    # Campaigns
    CampaignRequest:
      $ref: "./campaigns.yaml#/schemas/CampaignRequest"
    QuickCampaignRequest:
      $ref: "./campaigns.yaml#/schemas/QuickCampaignRequest"
    Campaign:
      $ref: "./campaigns.yaml#/schemas/Campaign"
    CampaignExecution:
      $ref: "./campaigns.yaml#/schemas/CampaignExecution"
    CampaignFilter:
      $ref: "./campaigns.yaml#/schemas/CampaignFilter"
    Schedule:
      $ref: "./campaigns.yaml#/schemas/Schedule"

    CloseAccount:
      type: object
      properties:
        reason:
          type: string
          enum:
            - price
            - difficultyOfUse
            - functionality
            - competitor
            - endingUsage
            - other
        feedback:
          type: string
        functionality:
          type: string
        competitor:
          type: string
        difficultyOfUse:
          type: array
          items:
            type: string
        endingUsage:
          type: array
          items:
            type: string
        discount:
          type: boolean
        followUp:
          type: boolean

    WorkflowDataReference:
      type: object
      properties:
        type:
          type: string
          enum:
            - workflow
            - output
            - contact
            - event
        nodeId:
          type: string
        name:
          type: string
        path:
          type: string
      required:
        - type
        - name

    Condition:
      $ref: "./common.yaml#/schemas/Condition"

    ConnectionInfo:
      type: object
      properties:
        token:
          type: string
        from:
          type: string
          example: "+14155550100"
        to:
          type: string
          example: "+12425551234"
        sessionId:
          type: string

    ContactList:
      $ref: "./contacts.yaml#/schemas/ContactList"

    Contact:
      $ref: "./contacts.yaml#/schemas/Contact"

    ContactFilter:
      $ref: "./contacts.yaml#/schemas/ContactFilter"

    ContactTag:
      type: object
      properties:
        tag:
          type: string
        scheme:
          type: string
        visible:
          type: boolean

    ContactToken:
      type: object
      properties:
        name:
          type: string
        label:
          type: string
        value:
          type: string
        type:
          type: string
      required:
        - name
        - label
        - value
        - type

    Conversation:
      type: object
      properties:
        id:
          type: string
          readOnly: true
        contact:
          $ref: "#/components/schemas/Contact"
        closed:
          type: string
          format: date-time
          readOnly: true
        lastMessage:
          $ref: "#/components/schemas/Message"
          readOnly: true
        phoneNumber:
          $ref: "#/components/schemas/PhoneNumber"
          readOnly: true
        group:
          $ref: "#/components/schemas/BasicGroup"
        unread:
          type: array
          items:
            type: string
        type:
          type: string
        created:
          $ref: "#/components/schemas/Updated"
        updated:
          $ref: "#/components/schemas/Updated"
      required:
        - closed
        - lastMessage

    DripCampaignStats:
      type: object
      properties:
        entered:
          type: number
        active:
          type: number
        errored:
          type: number
        noAction:
          type: number
        optOut:
          type: number
        engaged:
          type: number

    DripCampaignMessage:
      type: object
      properties:
        id:
          type: string
          readOnly: true
        message:
          type: string
        media:
          type: array
          items:
            $ref: "#/components/schemas/Media"
        delay:
          $ref: "#/components/schemas/Delay"
        stats:
          $ref: "#/components/schemas/DripCampaignStats"
      required:
        - message
        - delay

    DripCampaignDetailedStats:
      type: object
      properties:
        overview:
          $ref: "#/components/schemas/DripCampaignStats"
        messages:
          type: array
          items:
            $ref: "#/components/schemas/DripCampaignMessage"

    DripCampaign:
      type: object
      properties:
        id:
          type: string
          readOnly: true
        name:
          type: string
        description:
          type: string
        trigger:
          type: object
          properties:
            type:
              type: string
            message:
              type: string
            groups:
              type: array
              items:
                $ref: "#/components/schemas/Group"
            list:
              $ref: "#/components/schemas/List"
            group:
              $ref: "#/components/schemas/Group"
            delay:
              $ref: "#/components/schemas/Delay"
          required:
            - type
            - delay
        messages:
          type: array
          items:
            $ref: "#/components/schemas/DripCampaignMessage"
        active:
          type: boolean
          readOnly: true
        maxDuration:
          type: number
          readOnly: true
        stats:
          $ref: "#/components/schemas/DripCampaignStats"
        created:
          $ref: "#/components/schemas/Updated"
          readOnly: true
        updated:
          $ref: "#/components/schemas/Updated"
          readOnly: true
      required:
        - name
        - group
        - trigger
        - messages

    CreateUpdateDripCampaign:
      allOf:
        - $ref: "#/components/schemas/DripCampaign"
        - type: object
          properties:
            activate:
              type: boolean

    # DripCampaignWithReport:
    #   allOf:
    #     - $ref: "#/components/schemas/DripCampaign"
    #     - type: object
    #       properties:
    #         report:
    #           type: object
    #           properties:
    #             numDays:
    #               type: number
    #             entered:
    #               type: number
    #             completed:
    #               type: number
    #             active:
    #               type: number

    # DripCampaignReport:
    #   type: object
    #   properties:
    #     entered:
    #       type: number
    #     active:
    #       type: number
    #     engaged:
    #       type: number
    #     noResponse:
    #       type: number
    #     messages:
    #       type: array
    #       items:
    #         type: object
    #         properties:
    #           sent:
    #             type: number
    #           engaged:
    #             type: number
    #           noResponse:
    #             type: number

    DripCampaignExecution:
      type: object
      required:
        - id
        - status
        - entered
      properties:
        id:
          type: string
          readOnly: true
        status:
          type: string
        contact:
          $ref: "#/components/schemas/Contact"
        entered:
          type: string
          format: date-time

    EventType:
      type: string
      enum:
        - message-received
        - message-status
        - message-sent
        - conversation-started
        - conversation-closed
        - contact-created
        - contact-updated
        - contact-removed
        - contact-opt-out
        - contact-opt-in

    ExecutionReport:
      type: object
      properties:
        statistics:
          type: array
          items:
            $ref: "#/components/schemas/ExecutionReportStatistic"
      required:
        - statistics

    ExecutionReportStatistic:
      type: object
      properties:
        status:
          type: string
        count:
          type: number
      required:
        - status
        - count


    FieldMapping:
      $ref: "./campaigns.yaml#/schemas/FieldMapping"

    FormDetail:
      allOf:
        - $ref: "#/components/schemas/Form"
        - type: object
          properties:
            views:
              type: object
              additionalProperties:
                type: array
                items:
                  $ref: "#/components/schemas/FormField"
            styling:
              type: object
              additionalProperties:
                type: string
            settings:
              $ref: "#/components/schemas/FormSettings"

    Form:
      type: object
      properties:
        id:
          type: string
          readOnly: true
        name:
          type: string
        active:
          type: string
          format: date-time
          readOnly: true
        impressions:
          type: number
          readOnly: true
        conversions:
          type: number
          readOnly: true
        created:
          $ref: "#/components/schemas/Updated"
          readOnly: true
        updated:
          $ref: "#/components/schemas/Updated"
          readOnly: true
      required:
        - id
        - name
        - impressions
        - conversions

    FormField:
      type: object
      properties:
        name:
          type: string
        color:
          type: string
        bgColor:
          type: string
        value:
          type: string
        type:
          type: string
        mandatory:
          type: boolean
        size:
          type: string
      required:
        - name
        - type

    FormSettings:
      type: object
      properties:
        list:
          type: object
          properties:
            id:
              type: string
            name:
              type: string
          required:
            - id
        trigger:
          type: number
        repeat:
          type: number
        display:
          type: object
          properties:
            start:
              type: string
              format: date-time
            end:
              type: string
              format: date-time

    FormConversion:
      type: object
      properties:
        id:
          type: string
          readOnly: true
        ip:
          type: string
        pageUrl:
          type: string
        submitted:
          type: string
          format: date-time
        contact:
          type: object
          properties:
            id:
              type: string
            firstName:
              type: string
            lastName:
              type: string
            mobile:
              type: string
            country:
              type: string
            email:
              type: string
        submittedFields:
          additionalProperties:
            type: string

    FormAnalytics:
      type: object
      properties:
        impressions:
          type: number
        conversions:
          type: number
        data:
          type: array
          items:
            $ref: "#/components/schemas/FormImpressionAggregateData"

    FormImpressionAggregateData:
      type: object
      properties:
        impressions:
          type: number
        conversions:
          type: number
        date:
          type: string
      required:
        - impressions
        - conversions
        - date

    # Groups
    BasicGroup:
      $ref: "./groups.yaml#/schemas/BasicGroup"
    Group:
      $ref: "./groups.yaml#/schemas/Group"
    GroupNotification:
      $ref: "./groups.yaml#/schemas/GroupNotification"
    GroupOfficeHours:
      $ref: "./groups.yaml#/schemas/GroupOfficeHours"

    InstalledIntegration:
      allOf:
        - $ref: "#/components/schemas/AvailableIntegration"
        - type: object
          properties:
            status:
              type: string

    IntegrationChannel:
      type: object
      properties:
        id:
          type: string
        creator:
          type: string
        name:
          type: string
      required:
        - id
        - creator
        - name

    IntegrationProperty:
      type: object
      properties:
        name:
          type: string
        label:
          type: string
        type:
          type: string
      required:
        - name
        - label
        - type

    Invoice:
      type: object
      properties:
        id:
          type: string
        description:
          type: string
        subtotal:
          type: number
        total:
          type: number
        additionalCredit:
          type: number
        attempts:
          type: number
        currency:
          type: string
        date:
          type: string
        paid:
          type: boolean
        period:
          type: object
          properties:
            start:
              type: string
              format: date-time
            end:
              type: string
              format: date-time
        status:
          type: string
        invoicePdf:
          type: string
        receipt:
          type: string
        lines:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
              amount:
                type: number
              description:
                type: string
              productName:
                type: string
              plan:
                type: object
                properties:
                  id:
                    type: string
                  nickname:
                    type: string
                  metadata:
                    type: object
                  amount:
                    type: number
                  currency:
                    type: string
              period:
                type: object
                properties:
                  start:
                    type: string
                    format: date-time
                  end:
                    type: string
                    format: date-time
              proration:
                type: boolean
        invoiceId:
          type: string
        error:
          type: string
      required:
        - id

    Lead:
      type: object
      properties:
        id:
          type: string
        domain:
          type: string
        email:
          type: string
        status:
          type: string
          enum:
            - "active"
            - "expired"
        firstName:
          type: string
        lastName:
          type: string
        mobile:
          type: string
        website:
          type: string
        notes:
          type: string
        created:
          $ref: "#/components/schemas/Updated"

    # LineType:
    #   type: object
    #   properties:
    #     id:
    #       type: string
    #     type:
    #       type: string
    #     name:
    #       type: string
    #     info:
    #       type: array
    #       items:
    #         type: string
    #     pricing:
    #       $ref: '#/components/schemas/Pricing'
    #     links?:
    #       type: array
    #       items:
    #         $ref: '#/components/schemas/Link'
    #     search:
    #       type: array
    #       items:
    #         $ref: '#/components/schemas/SearchType'
    #     speed:
    #       type: string
    #       enum:
    #         - low
    #         - medium
    #         - high
    #     supported:
    #       type: string
    #   required:
    #     - type
    #     - name
    #     - pricing
    #     - search

    LineTypeMetaData:
      type: object
      properties:
        id:
          type: string
          readOnly: true
        type:
          type: string
        country:
          type: string
        provider:
          type: string
        supported:
          type: string
          enum:
            - "SELF_SERVICE"
            - "TICKET"
        features:
          type: array
          items:
            type: string
        search:
          type: array
          items:
            type: object
            properties:
              type:
                type: string
              parameters:
                type: object
                properties:
                  minLength:
                    type: number
                  maxLength:
                    type: number
                required:
                  - minLength
                  - maxLength
        requiredInformation:
          type: array
          items:
            type: object
            properties:
              type:
                type: string
              documents:
                type: array
                items:
                  type: string
        pricing:
          type: object
          properties:
            price:
              type: number
            setup:
              type: number
            regulatory:
              type: object
              properties:
                min:
                  type: number
                max:
                  type: number
                setup:
                  type: number
        info:
          type: array
          items:
            type: string
        links:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
              url:
                type: string
        speed:
          type: string
          enum: [low, medium, high]
      required:
        - country
        - type

    Media:
      $ref: "./common.yaml#/schemas/Media"

    Message:
      type: object
      properties:
        id:
          type: string
          readOnly: true
        contact:
          $ref: "#/components/schemas/Contact"
        conversation:
          $ref: "#/components/schemas/Conversation"
        group:
          $ref: "#/components/schemas/Group"
        type:
          type: string
        message:
          type: string
        template:
          type: string
        outgoing:
          type: boolean
        phoneNumber:
          type: string
          example: "+1234567890"
        price:
          type: number
        segments:
          type: number
        read:
          type: boolean
        status:
          type: string
          #TODO enum
        media:
          type: array
          description: List of media objects attached to message
          items:
            $ref: "#/components/schemas/Media"
        sendAt:
          type: string
          format: date-time
        error:
          $ref: "./common.yaml#/schemas/Error"
        created:
          $ref: "#/components/schemas/Updated"
        updated:
          $ref: "#/components/schemas/Updated"
      required:
        - id
        - status
        - created
        # - updated

    MessengerChannel:
      allOf:
        - $ref: "#/components/schemas/Channel"

    NotificationSettings:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        browser:
          type: boolean
        email:
          type: boolean
        sms:
          type: boolean

    NumberDetails:
      type: object
      properties:
        number:
          type: string
        country:
          type: string
        verification:
          type: object
          properties:
            id:
              type: string
            key:
              type: string
          required:
            - id
            - key
      required:
        - number
        - country

    OfficeHours:
      type: object
      properties:
        timezone:
          type: string
        times:
          $ref: "./common.yaml#/schemas/Times"
      required:
        - timezone
        - times

    Partner:
      type: object
      properties:
        contact:
          $ref: "#/components/schemas/Contact"
        info:
          type: object
          properties:
            linkedInURL:
              type: string
            numberClients:
              type: string
            numberEmployees:
              type: string
            customerLocation:
              type: string
            country:
              type: string
            joinDescription:
              type: string
          required:
            - numberClients
            - numberEmployees
            - customerLocation
            - country
            - joinDescription
        status:
          type: string
        paypalEmail:
          type: string

    PaymentMethod:
      type: object
      properties:
        id:
          type: string
          readOnly: true
        last4:
          type: string
        brand:
          type: string
        expiry:
          type: object
          properties:
            month:
              type: number
            year:
              type: number
          required:
            - month
            - year
        default:
          type: boolean
      required:
        - id
        - expiry
        - brand
        - last4
        
    # Lists
    List:
      $ref: "./lists.yaml#/schemas/List"

    # Senders
    AvailablePhoneNumber:
      $ref: "./senders.yaml#/schemas/AvailablePhoneNumber"
    Channel:
      $ref: "./senders.yaml#/schemas/Channel"
    ChannelTypes:
      $ref: "./senders.yaml#/schemas/ChannelTypes"
    PhoneNumber:
      $ref: "./senders.yaml#/schemas/PhoneNumber"
    PhoneNumberChannels:
      $ref: "./senders.yaml#/schemas/PhoneNumberChannels"
    Sender:
      $ref: "./senders.yaml#/schemas/Sender"
    SmsChannel:
      $ref: "./senders.yaml#/schemas/SmsChannel"
    SmsRegulatory:
      $ref: "./senders.yaml#/schemas/SmsRegulatory"
    SupportedDestinations:
      $ref: "./senders.yaml#/schemas/SupportedDestinations"
    VoiceChannel:
      $ref: "./senders.yaml#/schemas/VoiceChannel"
    WhatsappChannel:
      $ref: "./senders.yaml#/schemas/WhatsappChannel"
    
    Referral:
      type: object
      properties:
        name:
          type: string
        status:
          type: string
          enum:
            - "expired"
            - "pending"
            - "active"
        plan:
          type: object
          properties:
            name:
              type: string
            price:
              type: string
        created:
          $ref: "#/components/schemas/Updated"

    SearchType:
      type: object
      properties:
        type:
          type: string
        parameters:
          type: object
          properties:
            minLength:
              type: number
            maxLength:
              type: number
          required:
            - minLength
            - maxLength
      required:
        - type
        - parameters

    Link:
      type: object
      properties:
        id:
          type: string
          readOnly: true
        name:
          type: string
        keyId:
          type: string
          readOnly: true
        domain:
          type: object
          readOnly: true
          properties:
            id:
              type: string
            name:
              type: string
        destinationUrl:
          type: string
        shortenedUrl:
          type: string
          readOnly: true
        contactTracking:
          type: boolean
        sourceTracking:
          type: boolean
        stats:
          type: object
          readOnly: true
          properties:
            totalClicks:
              type: number
            uniqueClicks:
              type: number
            ctr:
              type: number
        created:
          $ref: "#/components/schemas/Updated"
        updated:
          $ref: "#/components/schemas/Updated"
      required:
        - keyId
        - destinationUrl
        - shortenedUrl

    LinkSource:
      type: object
      properties:
        id:
          type: string
          readOnly: true
        name:
          type: string
          readOnly: true
        stats:
          type: object
          readOnly: true
          properties:
            totalClicks:
              type: number
            uniqueClicks:
              type: number
            ctr:
              type: number
      required:
        - name
        - stats

    LinkSourceStat:
      type: object
      properties:
        date:
          type: string
          format: date-time
        value:
          type: number
      required:
        - date
        - value

    # SupportInfo:
    #   type: object
    #   properties:
    #     name:
    #       type: string
    #     website:
    #       type: string
    #     phone:
    #       type: string
    #     email:
    #       type: string
    #     address:
    #       $ref: '#/schemas/Address'
    Person:
      $ref: "./common.yaml#/schemas/Person"

    PersonWithId:
      $ref: "./common.yaml#/schemas/PersonWithId"

    Tag:
      type: object
      properties:
        tag:
          type: string
        visible:
          type: boolean

    Template:
      type: object
      properties:
        id:
          type: string
          readOnly: true
        name:
          type: string
        type:
          $ref: "#/components/schemas/TemplateType"
        template:
          type: string
          example: Hi {{{firstName}}}. Grab 20% off today only at ABC Shoes
        media:
          type: array
          description: List of media objects attached to message
          items:
            $ref: "#/components/schemas/Media"
        created:
          $ref: "#/components/schemas/Updated"
        updated:
          $ref: "#/components/schemas/Updated"

    TemplateType:
      type: string
      example: SMS
      enum:
        - SMS
        - Web

    TenDlcUseCase:
      type: string
      enum:
        - 2FA
        - ACCOUNT_NOTIFICATION
        - AGENTS_FRANCHISES
        - CARRIER_EXEMPT
        - CHARITY
        - CUSTOMER_CARE
        - DELIVERY_NOTIFICATION
        - EMERGENCY
        - FRAUD_ALERT
        - HIGHER_EDUCATION
        - K12_EDUCATION
        - LOW_VOLUME
        - MARKETING
        - MIXED
        - POLITICAL
        - POLLING_VOTING
        - PROXY
        - PUBLIC_SERVICE_ANNOUNCEMENT
        - SECURITY_ALERT
        - SOCIAL
        - SOLE_PROPRIETOR
        - SWEEPSTAKE
        - TRIAL
        - UCAAS_HIGH
        - UCAAS_LOW

    TenDlcBrand:
      type: object
      properties:
        id:
          type: string
          readOnly: true
        address:
          type: object
          properties:
            street:
              type: string
            city:
              type: string
            state:
              type: string
            postalCode:
              type: string
            country:
              type: string
          required:
            - street
            - city
            - state
            - postalCode
            - country
        companyName:
          type: string
        displayName:
          type: string
        entityType:
          type: string
        phone:
          type: string
        email:
          type: string
        website:
          type: string
        tax:
          type: object
          properties:
            id:
              type: string
            country:
              type: string
          required:
            - id
            - country
        stock:
          type: object
          properties:
            symbol:
              type: string
            exchange:
              type: string
          required:
            - symbol
            - exchange
        vertical:
          type: string
        owner:
          type: object
          properties:
            firstName:
              type: string
            lastName:
              type: string
            mobile:
              type: string
          required:
            - firstName
            - lastName
            - mobile
        status:
          type: string
        submitted:
          type: string
          format: date-time
      required:
        - id
        - address
        - companyName
        - displayName
        - entityType
        - phone
        - email
        - website
        - vertical
        - tax
        - stock

    TenDlcSupportingDocument:
      type: object
      properties:
        url:
          type: string
        filename:
          type: string
        status:
          type: string
      required:
        - url
        - filename
        - status

    TenDlcCampaign:
      type: object
      properties:
        id:
          type: string
        campaignId:
          type: string
        brandId:
          type: string
        description:
          type: string
        useCase:
          $ref: "#/components/schemas/TenDlcUseCase"
        subUseCases:
          type: array
          items:
            $ref: "#/components/schemas/TenDlcUseCase"
        messageFlow:
          type: string
        features:
          type: object
          properties:
            ageGated:
              type: boolean
            directLending:
              type: boolean
            embeddedLink:
              type: boolean
            embeddedPhone:
              type: boolean
            numberPool:
              type: boolean
            subscriberHelp:
              type: boolean
            subscriberOptin:
              type: boolean
            subscriberOptout:
              type: boolean
            termsAndConditions:
              type: boolean
          required:
            - ageGated
            - directLending
            - embeddedLink
            - embeddedPhone
            - numberPool
            - subscriberHelp
            - subscriberOptin
            - subscriberOptout
            - termsAndConditions
        samples:
          type: array
          items:
            type: string
        optin:
          type: object
          properties:
            message:
              type: string
            keywords:
              type: array
              items:
                type: string
          required:
            - message
            - keywords
        optout:
          type: object
          properties:
            message:
              type: string
            keywords:
              type: array
              items:
                type: string
          required:
            - message
            - keywords
        help:
          type: object
          properties:
            message:
              type: string
            keywords:
              type: array
              items:
                type: string
          required:
            - message
            - keywords
        privacyPolicyLink:
          type: string
        termsAndConditionsLink:
          type: string
        embeddedLinkSample:
          type: string
        supportingDocuments:
          type: array
          items:
            $ref: "#/components/schemas/TenDlcSupportingDocument"
        numbers:
          type: array
          items:
            type: string
        score:
          type: string
        status:
          type: string
        submitted:
          type: string
          format: date-time
        approved:
          type: string
          format: date-time
        rejected:
          type: string
          format: date-time
        expired:
          type: string
          format: date-time
        rejection:
          type: object
          properties:
            code:
              type: string
            description:
              type: string
      required:
        - brandId
        - description
        - useCase
        - messageFlow
        - features
        - samples
        - optin
        # - optout
        # - help

    TollFreeVerificationRequest:
      type: object
      properties:
        phoneNumbers:
          type: array
          items:
            type: string
        name:
          type: string
        website:
          type: string
        address:
          type: object
          properties:
            line1:
              type: string
            line2:
              type: string
            city:
              type: string
            state:
              type: string
            zip:
              type: string
        contact:
          type: object
          properties:
            firstName:
              type: string
            lastName:
              type: string
            email:
              type: string
            phoneNumber:
              type: string
        messageVolume:
          type: number
        useCase:
          type: string
        useCaseSummary:
          type: string
        messageContent:
          type: string
        optInWorkflow:
          type: object
          properties:
            description:
              type: string
            imageUrls:
              type: array
              items:
                type: string
        additionalInformation:
          type: string
      required:
        - phoneNumbers
        - name
        - website
        - address
        - contact
        - messageVolume
        - useCase
        - useCaseSummary
        - messageContent
        - optInWorkflow

    User:
      $ref: "./common.yaml#/schemas/User"

    UserInvite:
      type: object
      properties:
        email:
          type: string
        role:
          type: string
      required:
        - email
        - role

    Webhook:
      type: object
      properties:
        id:
          type: string
          readOnly: true
        # url:
        #   type: string
        type:
          type: string
        eventTypes:
          type: array
          items:
            $ref: "#/components/schemas/EventType"
        destination:
          type: string
      required:
        - eventTypes
        - destination

    Workflow:
      type: object
      required:
        - id
        - name
        - account
        - created
        - updated
      properties:
        id:
          type: string
          readOnly: true
        name:
          type: string
        # publishedVersion:
        #   type: string
        # paused:
        #   type: string
        #   format: date-time
        # current: #TODO decommission
        #   $ref: '#/components/schemas/WorkflowVersion'
        # draft: #TODO decommission
        #   $ref: '#/components/schemas/WorkflowVersion'
        versions:
          type: array
          items:
            $ref: "#/components/schemas/WorkflowVersion"
        created:
          $ref: "#/components/schemas/Updated"
        updated:
          $ref: "#/components/schemas/Updated"

    WorkflowDefinition:
      type: object
      properties:
        # id:
        #   type: string
        nodes:
          type: array
          items:
            $ref: "#/components/schemas/WorkflowNode"
        edges:
          type: array
          items:
            $ref: "#/components/schemas/WorkflowEdge"
        properties:
          $ref: "#/components/schemas/WorkflowProperties"
      required:
        - nodes
        - edges

    WorkflowEdgeType:
      type: string
      enum: [standard, timeout, error]

    WorkflowEdge:
      type: object
      properties:
        id:
          type: string
        type:
          $ref: "#/components/schemas/WorkflowEdgeType"
        source:
          type: string
        target:
          type: string
        value:
          anyOf:
            - type: string
            - type: boolean
            - type: number
      required:
        - source
        - id
        - type

    WorkflowProperties:
      type: array
      items:
        $ref: "#/components/schemas/WorkflowProperty"

    WorkflowProperty:
      type: object
      properties:
        name:
          type: string
        dataType:
          type: string
          enum: [string, number, boolean, date]
        created:
          type: object
          properties:
            at:
              type: string
              format: date-time
      required:
        - name
        - dataType

    WorkflowAttributeReference:
      type: object
      properties:
        type:
          type: string
          enum:
            - contact
            - workflow
            - output
        name:
          type: string

    WorkflowNode:
      type: object
      properties:
        id:
          type: string
        type:
          $ref: "#/components/schemas/WorkflowNodeType"
        config:
          $ref: "#/components/schemas/WorkflowNodeConfig"
        # version:
        #   type: number
      required:
        - id
        - type
        - config
      # - version

    # TRIGGER NODE CONFIGS
    MessageReceivedTriggerConfig:
      type: object
      properties:
        message:
          type: string
        groups:
          type: array
          items:
            $ref: "#/components/schemas/Group"

    LinkClickedTriggerConfig:
      type: object
      properties:
        link:
          $ref: "#/components/schemas/Link"

    # PipedriveContactUpdatesTriggerConfig:
    #   type: object
    #   properties:
    #     group:
    #       type: string

    MessageStatusTriggerConfig:
      type: object
      properties:
        status:
          type: string
          enum: [sent, error]
        errors:
          type: array
          items:
            $ref: "./common.yaml#/schemas/Error"

    ListTriggerConfig:
      type: object
      properties:
        list:
          $ref: "#/components/schemas/List"

    MissedCallTriggerConfig:
      type: object
      properties:
        groups:
          type: array
          items:
            $ref: "#/components/schemas/Group"

    ContactUpdatedTriggerConfig:
      type: object
      properties:
        condition:
          $ref: "#/components/schemas/WorkflowCondition"

    ContactCreatedTriggerConfig:
      type: object

    MeetingCreatedTriggerConfig:
      type: object
      properties:
        meetingEvents:
          type: array
          items:
            type: string

    MeetingRescheduledTriggerConfig:
      type: object
      properties:
        meetingEvents:
          type: array
          items:
            type: string

    MeetingCancelledTriggerConfig:
      type: object
      properties:
        meetingEvents:
          type: array
          items:
            type: string

    FormSubmittedTriggerConfig:
      type: object
      properties:
        form:
          $ref: "#/components/schemas/Form"

    ChoiceNodeConfig:
      type: object
      properties:
        property:
          $ref: "#/components/schemas/WorkflowDataReference"
      required:
        - property

    ABTestNodeConfig:
      type: object
      properties:
        split:
          type: number

    FilterNodeConfig:
      type: object
      properties:
        conditions:
          type: array
          items:
            $ref: "#/components/schemas/WorkflowCondition"

    IfThenNodeConfig:
      type: object
      properties:
        conditions:
          type: array
          items:
            $ref: "#/components/schemas/WorkflowCondition"

    #TODO needs work
    ListNodeConfig:
      type: object
      properties:
        contact:
          $ref: "#/components/schemas/WorkflowDataReference"
        list:
          $ref: "#/components/schemas/List"

    Property:
      type: object
      properties:
        name:
          type: string
        label:
          type: string
        dataType:
          $ref: "#/components/schemas/DataType"

    ContactUpdate:
      type: object
      properties:
        property:
          $ref: "#/components/schemas/Property"
        value:
          type: string

    UpdateContactNodeConfig:
      type: object
      properties:
        contact:
          $ref: "#/components/schemas/WorkflowDataReference"
        updates:
          type: array
          items:
            $ref: "#/components/schemas/ContactUpdate"

    WorkflowExecutionOverview:
      type: object
      properties:
        id:
          type: string
        status:
          type: string
          enum: [completed, error, cancelled, awaiting, inProgress]
        version:
          type: object
          properties:
            id:
              type: string
            name:
              type: string
          required:
            - id
        start:
          type: string
          format: date-time
        end:
          type: string
          format: date-time
      required:
        - id
        - version
        - start
        - status

    WorkflowNodeContext:
      type: object
      properties:
        id:
          type: string
        type:
          $ref: "#/components/schemas/WorkflowNodeType"
        context:
          type: object
      required:
        - id
        - type

    WorkflowExecutionStep:
      type: object
      properties:
        id:
          type: string
        start:
          type: string
          format: date-time
        end:
          type: string
          format: date-time
        node:
          $ref: "#/components/schemas/WorkflowNodeContext"
        edge:
          $ref: "#/components/schemas/WorkflowEdge"
      required:
        - id
        - start
        - end
        - node

    WorkflowExecution:
      allOf:
        - $ref: "#/components/schemas/WorkflowExecutionOverview"
        - type: object
          properties:
            steps:
              type: array
              items:
                $ref: "#/components/schemas/WorkflowExecutionStep"
          required:
            - steps

    WorkflowVersionMetrics:
      type: object
      properties:
        total:
          type: number
        paths:
          type: array
          items:
            type: object
            properties:
              edge:
                type: string
              count:
                type: number
      required:
        - total
        - paths

    Delay:
      type: object
      properties:
        days:
          type: number
        hours:
          type: number
        minutes:
          type: number
      required:
        - days
        - hours
        - minutes

    DayOfWeek:
      type: number
      enum: [0, 1, 2, 3, 4, 5, 6]

    AdvancedDelayDays:
      type: array
      items:
        $ref: "#/components/schemas/DayOfWeek"

    AdvancedDelayTime:
      type: object
      required:
        - hour
        - minute
      properties:
        hour:
          type: number
        minute:
          type: number

    AdvancedDelay:
      type: object
      properties:
        initialDelay:
          $ref: "#/components/schemas/Delay"
        additionalTime:
          type: object
          properties:
            timezone:
              type: string
            days:
              $ref: "#/components/schemas/AdvancedDelayDays"
            time:
              $ref: "#/components/schemas/AdvancedDelayTime"

    DelayNodeConfig:
      type: object
      properties:
        delay:
          $ref: "#/components/schemas/AdvancedDelay"

    IncrDecrementNodeConfig:
      type: object
      properties:
        operation:
          type: string
          enum: [add, subtract]
        property:
          type: string
        value:
          type: number
      required:
        - property
        - value

    SendMessageToType:
      type: string
      enum:
        - contact
        - custom
        - group
        - user

    SendMessageNodeConfig:
      type: object
      properties:
        from:
          type: object
          properties:
            type:
              type: string
              enum: [group, custom]
            group:
              $ref: "#/components/schemas/Group"
            custom:
              type: string
          required:
            - type
          # - group
        to:
          type: object
          properties:
            type:
              $ref: "#/components/schemas/SendMessageToType"
            mobile:
              $ref: "#/components/schemas/InternationalNumber"
            group:
              $ref: "#/components/schemas/Group"
            user:
              $ref: "#/components/schemas/User"
            contact:
              $ref: "#/components/schemas/WorkflowDataReference"
        message:
          type: object
          properties:
            message:
              type: string
            media:
              type: array
              description: List of media objects attached to message
              items:
                $ref: "#/components/schemas/Media"

    SetWorkflowPropertyNodeConfig:
      type: object
      properties:
        property:
          type: string
        value:
          anyOf:
            - type: string
            - type: number
      required:
        - property
        - value

    LinkClickedNodeConfig:
      type: object
      properties:
        link:
          $ref: "#/components/schemas/Link"
        timeout:
          $ref: "#/components/schemas/Delay"

    MessageReceivedNodeConfig:
      type: object
      properties:
        group:
          $ref: "#/components/schemas/Group"
        timeout:
          $ref: "#/components/schemas/Delay"

    GoogleSheetTab:
      type: object
      properties:
        id:
          type: number
        name:
          type: string

    UserIntegration:
      $ref: "./users.yaml#/schemas/UserIntegration"

    GoogleSheet:
      type: object
      properties:
        connection:
          $ref: "#/components/schemas/UserIntegration"
        id:
          type: string
        name:
          type: string
        tabs:
          type: array
          items:
            $ref: "#/components/schemas/GoogleSheetTab"
        tab:
          $ref: "#/components/schemas/GoogleSheetTab"

    GoogleSheetColumn:
      type: object
      properties:
        index:
          type: number
        name:
          type: string
      required:
        - index
        - name

    GoogleSheetColumnMapping:
      type: object
      properties:
        column:
          $ref: "#/components/schemas/GoogleSheetColumn"
        value:
          type: string

    GoogleSheetsExportNodeConfig:
      type: object
      properties:
        googlesheet:
          $ref: "#/components/schemas/GoogleSheet"
        properties:
          type: array
          items:
            $ref: "#/components/schemas/GoogleSheetColumnMapping"
        userId:
          type: string

    GoogleSheetsLookupNodeConfig:
      type: object
      properties:
        googlesheet:
          $ref: "#/components/schemas/GoogleSheet"
        searchColumn:
          $ref: "#/components/schemas/GoogleSheetColumn"
        outputColumn:
          $ref: "#/components/schemas/GoogleSheetColumn"
        searchValue:
          type: string
        userId:
          type: string

    WorkflowCondition:
      type: object
      properties:
        attribute:
          $ref: "#/components/schemas/WorkflowDataReference"
        comparator:
          type: string
        value:
          oneOf:
            - type: array
              items:
                type: string
            - type: array
              items:
                type: number
            - type: string
            - type: number
      required:
        - attribute
        - comparator
        - value

    WorkflowNodeConfig:
      type: object
      oneOf:
        # TRIGGERS
        # Message Received Trigger Configuration
        - $ref: "#/components/schemas/MessageReceivedTriggerConfig"

        # Link Clicked Trigger Configuration
        - $ref: "#/components/schemas/LinkClickedTriggerConfig"

        # Message Status Trigger Configuration
        - $ref: "#/components/schemas/MessageStatusTriggerConfig"

        # List Add/Remove Trigger Configuration
        - $ref: "#/components/schemas/ListTriggerConfig"

        # Contact Created Trigger Configuration
        - $ref: "#/components/schemas/ContactCreatedTriggerConfig"

        # Contact Updated Trigger Configuration
        - $ref: "#/components/schemas/ContactUpdatedTriggerConfig"

        # Form Submitted Trigger Configuration
        - $ref: "#/components/schemas/FormSubmittedTriggerConfig"

        # ACTIONS
        # Add to list node configuration
        - $ref: "#/components/schemas/ListNodeConfig"

        # AB Test
        - $ref: "#/components/schemas/ABTestNodeConfig"

        # Choice
        - $ref: "#/components/schemas/ChoiceNodeConfig"

        # Delay Node Configuration
        - $ref: "#/components/schemas/DelayNodeConfig"

        - $ref: "#/components/schemas/FilterNodeConfig"

        - $ref: "#/components/schemas/IfThenNodeConfig"

        # Increment/decrement Node Configuration
        - $ref: "#/components/schemas/IncrDecrementNodeConfig"

        # Send Message node configuration
        - $ref: "#/components/schemas/SendMessageNodeConfig"

        # SetWorkflow Node Configuration
        - $ref: "#/components/schemas/SetWorkflowPropertyNodeConfig"

        # Update Contact Node Configuration
        - $ref: "#/components/schemas/UpdateContactNodeConfig"

        # Google Export
        - $ref: "#/components/schemas/GoogleSheetsExportNodeConfig"

        # Google Sheets Lookup
        - $ref: "#/components/schemas/GoogleSheetsLookupNodeConfig"

        # INLINE TRIGGERS
        # Link Clicked Node Configuration
        - $ref: "#/components/schemas/LinkClickedNodeConfig"

        # Received Message Node Configuration
        - $ref: "#/components/schemas/MessageReceivedNodeConfig"

    WorkflowNodePropertyType:
      type: string
      enum:
        - basictext
        - number
        - text
        - textarea
        - password
        - checkbox
        - dropdown
        - apidropdown
        - split
        - form
        - groups
        - group
        - dynamicgroup
        - lists
        - list
        - to
        - composer
        - contactattributecondition
        - filtercondition
        - edges
        - property
        - update
        - link
        - delay
        - simpledelay
        - workflowproperty
        - messagestatusanderror
        - dynamicgroup
        - errors
        - googlesheet
        - googlesheetcolumnmappings
        - googlesheetcolumn
        - timeout
        - contactselect
        - userintegration
        - url
        - code
        - readonlytext
        - buttongroup
        - cron
        - phonenumber
        - image

    WorkflowNodePropertyCondition:
      type: object
      properties:
        property:
          type: string
        comparator:
          type: string
        value:
          type: string
      required:
        - property
        - comparator
        - value

    SelectOption:
      type: object
      properties:
        value:
          type: string
        label:
          type: string

    WorkflowNodeProperty:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "#/components/schemas/WorkflowNodePropertyBaseObject"
        - type: object
          properties:
            name:
              type: string
            conditions:
              type: array
              items:
                $ref: "#/components/schemas/WorkflowNodePropertyCondition"
          required:
            - name

    EdgeValidation:
      type: object
      properties:
        type:
          type: string
          enum:
            - timeout
            - standard
            - error
        value:
          type: object
          properties:
            mandatory:
              type: boolean
            editable:
              type: boolean
            value:
              oneOf:
                - type: string
                - type: number
                - type: boolean
            default:
              oneOf:
                - type: string
                - type: number
                - type: boolean
        multiple:
          type: boolean
        defaultEdge:
          type: boolean

    NumEdgeConditions:
      type: string
      enum:
        - exactly
        - "at least"

    WorkflowNodeTypeValidation:
      type: object
      properties:
        numEdgeCondition:
          $ref: "#/components/schemas/NumEdgeConditions"
        numEdges:
          type: number
        edges:
          type: array
          items:
            $ref: "#/components/schemas/EdgeValidation"
      readOnly: true

    WorkflowNodeType:
      type: object
      properties:
        id:
          type: string
          readOnly: true
        type:
          type: string
          readOnly: true
        group:
          type: string
          properties:
            id:
              type: string
              readOnly: true
            label:
              type: string
              readOnly: true
          readOnly: true
        name:
          type: string
          readOnly: true
        label:
          type: string
          readOnly: true
        description:
          type: string
          readOnly: true
        icon:
          type: string
          readOnly: true
        properties:
          type: array
          items:
            $ref: "#/components/schemas/WorkflowNodeProperty"
          readOnly: true
        outputs:
          type: array
          items:
            $ref: "#/components/schemas/WorkflowNodeTypeOutput"
          readOnly: true
        validation:
          $ref: "#/components/schemas/WorkflowNodeTypeValidation"
        supportsReenrollment:
          type: boolean
          readOnly: true
        color:
          type: string
          readOnly: true
        status:
          type: string
          readOnly: true
        supportLink:
          type: string
          readOnly: true
      required:
        - id
        - name
        - type

    WorkflowTemplateGroup:
      type: object
      properties:
        label:
          type: string
        description:
          type: string
        parameters:
          type: array
          readOnly: true
          items:
            allOf: # Combines the BasicErrorModel and the inline model
              - $ref: "#/components/schemas/WorkflowNodePropertyBaseObject"
              - type: object
                properties:
                  id:
                    type: string
            required:
              - id
              - label
      required:
        - parameters

    WorkflowTemplate:
      type: object
      required:
        - id
        - name
        - status
        - description
        - groups
      properties:
        id:
          type: string
          readOnly: true
        name:
          type: string
          readOnly: true
        status:
          $ref: "#/components/schemas/WorkflowTemplateStatus"
        tags:
          type: array
          readOnly: true
          items:
            type: string
        description:
          type: string
        groups:
          type: array
          readOnly: true
          items:
            $ref: "#/components/schemas/WorkflowTemplateGroup"
        integrations:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
              installed:
                type: boolean

    WorkflowVersions:
      type: object
      additionalProperties:
        $ref: "#/components/schemas/WorkflowVersion"

    WorkflowVersion:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        definition:
          $ref: "#/components/schemas/WorkflowDefinition"
        readonly:
          type: boolean
        active:
          type: string
          format: date-time
        lastActive:
          type: string
          format: date-time
        created:
          $ref: "#/components/schemas/Updated"
        updated:
          $ref: "#/components/schemas/Updated"
      required:
        - id
        - version
        - definition
        - created
        - updated

    # Requests
    AddNumbersRequest:
      type: object
      properties:
        provider:
          type: string
        type:
          type: string
        country:
          type: string
        quantity:
          type: number
        numbers:
          type: array
          items:
            $ref: "#/components/schemas/NumberDetails"
        hosted:
          type: boolean
        state:
          type: string
        areaCode:
          type: string
        nxx:
          type: string
        registrationInfo:
          type: object
      required:
        - provider
        - type

    SendMessagesRequest:
      type: object
      properties:
        #TODO consider using 'oneOf'
        conversations:
          type: array
          description: List of conversation ids to send messages to
          items:
            type: string
        contacts:
          type: array
          items:
            $ref: "#/components/schemas/Contact"
        filters:
          type: object
          properties:
            tags:
              type: array
              items:
                type: string
            attributes:
              type: array
              items:
                type: object
        phoneNumberFilter:
          type: object
          properties:
            group:
              type: object
              properties:
                id:
                  type: string
        template:
          type: string
        type:
          type: string
          enum:
            - SMS
            - MMS
        media:
          type: array
          description: List of media objects to attach to message
          items:
            type: object
            properties:
              url:
                type: string

    WorkflowNodeTypeOutputDataType:
      type: string
      enum:
        - boolean
        - call
        - contact
        - country
        - date
        - file
        - group
        - link
        - list
        - message
        - number
        - object
        - payload
        - phonenumber
        - string
        - tweet

    WorkflowNodePropertyBaseObject:
      type: object
      properties:
        label:
          type: string
        helperText:
          type: string
        link:
          type: string
        type:
          $ref: "#/components/schemas/WorkflowNodePropertyType"
        mandatory:
          type: boolean
        args:
          type: array
          items:
            type: string
        options:
          type: array
          items:
            $ref: "#/components/schemas/SelectOption"
        min:
          type: number
        max:
          type: number
        defaultValue:
          anyOf:
            - type: string
            - type: boolean
            - type: number
            - type: object
      required:
        - type

    WorkflowNodeTypeOutput:
      type: object
      required:
        - path
        - name
        - dataType
      properties:
        default:
          type: boolean
        path:
          type: string
        name:
          type: string
        dataType:
          $ref: "#/components/schemas/WorkflowNodeTypeOutputDataType"

    EditWorkflowNodeRequest:
      type: object
      properties:
        config:
          $ref: "#/components/schemas/WorkflowNodeConfig"
        type:
          type: string

    EnterpriseInquiryRequest:
      type: object
      properties:
        volume:
          type: string
        message:
          type: string

    CheckoutRequest:
      type: object
      properties:
        plan:
          type: string
        commitment:
          type: number
        frequency:
          type: string
        name:
          type: string
        email:
          type: string
        address:
          $ref: "./common.yaml#/schemas/Address"
        tax:
          $ref: "#/components/schemas/TaxInfo"
        segmentUnderstanding:
          type: boolean

    UpdatePlanRequest:
      type: object
      properties:
        name:
          type: string
          description: name of the plan you want
        commitment:
          type: number
        frequency:
          type: string

    CreateWorkflowRequest:
      type: object
      properties:
        name:
          type: string
        definition:
          $ref: "#/components/schemas/WorkflowDefinition"
        templateId:
          type: string
        # template:
        #   $ref: "#/components/schemas/WorkflowRequestTemplate"
        parameters:
          type: array
          items:
            $ref: "#/components/schemas/WorkflowTemplateParamValue"
      required:
        - name

    WorkflowTemplateParamValue:
      type: object
      properties:
        id:
          type: string
        value:
          anyOf:
            - type: string
            - type: boolean
            - type: number
            - type: object
      required:
        - id
        - value

    # Calendar
    MeetingEvent:
      $ref: "./meetings.yaml#/schemas/MeetingEvent"

    UpdateMeetingEventRequest:
      $ref: "./meetings.yaml#/schemas/UpdateMeetingEventRequest"

    MeetingEventRequest:
      $ref: "./meetings.yaml#/schemas/MeetingEventRequest"
      
    Meeting:
      $ref: "./meetings.yaml#/schemas/Meeting"

    MeetingEventResponse:
      $ref: "./meetings.yaml#/responses/MeetingEventResponse"
      
    MeetingResponse:
      $ref: "./meetings.yaml#/responses/MeetingResponse"
      
    # Responses
    AccountAttributesResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/PaginatedResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/AccountAttribute"
      required:
        - data

    AccountIntegrationsResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/PaginatedResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "./accounts.yaml#/schemas/AccountIntegration"
      required:
        - data

    AutoresponderResponse:
      allOf:
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/Autoresponder"
      required:
        - data

    AutorespondersResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/PaginatedResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/Autoresponder"
      required:
        - data

    AutoTopupResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/AutoTopup"
      required:
        - data

    AvailablePhoneNumbersResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/AvailablePhoneNumber"
          required:
            - data

    BalanceResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/AccountBalance"

    CallHistoriesResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/PaginatedResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/CallHistory"
      required:
        - data

    CallHistoryResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/CallHistory"
      required:
        - data

    CampaignResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/Campaign"
      required:
        - data

    CampaignsResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/PaginatedResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/Campaign"
      required:
        - data

    ConnectionInfoResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/ConnectionInfo"
      required:
        - data

    ContactResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/Contact"
      required:
        - data

    ContactsResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/PaginatedResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/Contact"
      required:
        - data

    ContactUploadResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              type: object
              properties:
                contacts:
                  type: array
                  items:
                    $ref: "#/components/schemas/Contact"
                  description: "Uploaded contacts"
                errors:
                  type: array
                  items:
                    $ref: "#/components/schemas/Contact"
                  description: "Contacts that failed validation"
                #filters:
                #  $ref: '#/components/schemas/ContactFilter'
                submitted:
                  type: integer #TODO review
                inserted:
                  type: integer #TODO review
                updated:
                  type: integer #TODO review
                success:
                  type: integer #TODO review
      required:
        - data

    ConversationResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/Conversation"
      required:
        - data

    ConversationsResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/PaginatedResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/Conversation"
      required:
        - data

    MessageResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/Message"
      required:
        - data

    MessagesResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/PaginatedResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/Message"
      required:
        - data

    FormResponse:
      allOf:
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/Form"
      required:
        - data

    FormsResponse:
      allOf:
        - $ref: "./common.yaml#/schemas/PaginatedResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/Form"
      required:
        - data

    FormConversionsResponse:
      allOf:
        - $ref: "./common.yaml#/schemas/PaginatedResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/FormConversion"
      required:
        - data

    FormAnalyticsResponse:
      allOf:
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/FormAnalytics"
      required:
        - data

    PartnerCreatedResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              type: boolean
      required:
        - data

    CheckoutResponse:
      allOf:
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              type: string
      required:
        - data

    EnterpriseInquiryResponse:
      allOf:
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              type: object
              properties:
                requested:
                  type: boolean
      required:
        - data

    SendMessagesResponse:
      allOf:
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              type: object
              properties:
                messages:
                  type: array
                  items:
                    $ref: "#/components/schemas/Message"
                jobId:
                  type: string
                requested:
                  type: integer
                valid:
                  type: integer
                invalid:
                  type: array
                  items:
                    $ref: "#/components/schemas/Contact"
                estimatedPrice:
                  type: number
                  format: double
      required:
        - data

    ShareFileResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              type: object
              properties:
                link:
                  type: string
                expires:
                  type: string
                  format: date-time
              required:
                - link
          required:
            - data

    LinksResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/PaginatedResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/Link"
      required:
        - data

    LinkResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/Link"
      required:
        - data

    LinkSourcesResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/PaginatedResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/LinkSource"
      required:
        - data

    LinkSourceResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/LinkSource"
      required:
        - data

    LinkSourceStatsResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/PaginatedResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/LinkSourceStat"
      required:
        - data

    # SupportInfoResponse:
    #   allOf:     # Combines the BasicErrorModel and the inline model
    #     - $ref: './common.yaml#/components/schemas/BasicResponse'
    #     - type: object
    #       properties:
    #         data:
    #           $ref: '#/components/schemas/SupportInfo'
    #   required:
    #     - data

    QuickCampaignResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              type: object
              properties:
                campaign:
                  $ref: "#/components/schemas/Campaign"
                job:
                  $ref: "#/components/schemas/CampaignExecution"
      required:
        - data

    TemplateResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/Template"
      required:
        - data

    TemplatesResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/PaginatedResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/Template"
      required:
        - data

    AttributeFilter:
      type: object
      properties:
        name:
          type: string
        comparator:
          type: string
          enum:
            - "="
            - "<"
            - "<="
            - ">"
            - ">="
            - "!="
        value:
          type: string

    # AccountEvent:
    #   type: object
    #   properties:
    #       type:
    #         $ref: '#/components/schemas/EventType'
    #       accountId:
    #         $ref: '#/components/schemas/AccountId'

    WebhookResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/Webhook"
      required:
        - data

    WebhooksResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/PaginatedResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/Webhook"
      required:
        - data

    WorkflowEdgeResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/WorkflowEdge"
          required:
            - data

    WorkflowResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/Workflow"
          required:
            - data

    WorkflowsResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/PaginatedResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/Workflow"
          required:
            - data

    WorkflowNodeResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              type: object
              properties:
                node:
                  $ref: "#/components/schemas/WorkflowNode"
                edges:
                  type: array
                  items:
                    $ref: "#/components/schemas/WorkflowEdge"
          required:
            - data

    WorkflowPropertyResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/WorkflowProperty"
          required:
            - data

    WorkflowPropertiesResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/WorkflowProperties"
          required:
            - data

    WorkflowTemplateResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/WorkflowTemplate"

    WorkflowTemplatesResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/PaginatedResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/WorkflowTemplate"

    WorkflowVersionResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/WorkflowVersion"
          required:
            - data

    WorkflowVersionsResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/WorkflowVersions"
          required:
            - data

    WorkflowExecutionsResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/PaginatedResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/WorkflowExecutionOverview"
          required:
            - data

    WorkflowDetailedExecutionResponse:
      allOf:
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/WorkflowExecution"
          required:
            - data

    WorkflowVersionMetricsResponse:
      allOf:
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/WorkflowVersionMetrics"
          required:
            - data

    DripCampaignsResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/PaginatedResponse"
        - type: object
          properties:
            data:
              type: array
              items:
                $ref: "#/components/schemas/DripCampaign"
          required:
            - data

    DripCampaignResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/DripCampaign"
          required:
            - data

    # DripCampaignStatsResponse:
    #   allOf: # Combines the BasicErrorModel and the inline model
    #     - $ref: "./common.yaml#/schemas/BasicResponse"
    #     - type: object
    #       properties:
    #         data:
    #           type: object
    #           properties:
    #             current:
    #               $ref: "#/components/schemas/DripCampaignStats"
    #             lifetime:
    #               $ref: "#/components/schemas/DripCampaignStats"
    #       required:
    #         - data

    # DripCampaignReportResponse:
    #   allOf: # Combines the BasicErrorModel and the inline model
    #     - $ref: "./common.yaml#/schemas/BasicResponse"
    #     - type: object
    #       properties:
    #         data:
    #           $ref: "#/components/schemas/DripCampaignReport"
    #       required:
    #         - data

    DripCampaignExecutionsResponse:
      allOf: # Combines the BasicErrorModel and the inline model
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/DripCampaignExecution"
          required:
            - data

    PricingResponse:
      allOf:
        - $ref: "./common.yaml#/schemas/BasicResponse"
        - type: object
          properties:
            data:
              type: object
              properties:
                pricing:
                  type: object
                  additionalProperties:
                    type: object
                    properties:
                      sms:
                        type: string
                      mms:
                        type: string
                credit:
                  type: number
                commitment:
                  type: number
                minCommitment:
                  type: number
      required:
        - data

    # Event:
    #   type: object
    #   properties:
    #     eventId:
    #       type: string
    #     type:
    #       $ref: '#/components/schemas/EventType'
    #     accountId:
    #       $ref: '#/components/schemas/AccountId'
    #     data:
    #       oneOf:
    #         - $ref: '#/components/schemas/AccountEventPayload'
    #         - $ref: '#/components/schemas/MessageEventPayload'

    # AccountEventPayload:
    #   type: object
    #   properties:
    #     balance:
    #       type: number
    #       format: double

    # MessageEventPayload:
    #   type: object
    #   properties:
    #     contact:
    #       $ref: '#/components/schemas/Contact'
    #     message:
    #       type: string
    #     status:
    #       type: string
    #     error:
    #       type: string

  # requestBodies:
  #   Contact:
  #     content:
  #       application/json:
  #         schema:
  #           $ref: '#/components/schemas/ContactRequest'
  #     required: true
  #   Contacts:
  #     content:
  #       application/json:
  #         schema:
  #           type: array
  #           items:
  #             $ref: '#/components/schemas/ContactRequest'
  #     description: List of contacts
  #     required: true

  responses: 
    4XX:
      $ref: "./common.yaml#/responses/4XX"
    5XX:
      $ref: "./common.yaml#/responses/5XX"

  securitySchemes:
    sakari_auth:
      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: "/oauth2/token"
          scopes:
            "messages:send": Send messages
