openapi: 3.0.0
servers:
  - description: Sakari Production
    url: https://api.sakari.io
info:
  contact:
    email: support@sakari.io
  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/sakari-api-quickstart](https://sakari.io/blog/sakari-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
        "totalCount": 21
      }  
    }
    ```

    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.
  termsOfService: https://sakari.io/terms-service.html
  title: Sakari
  version: 1.0.1
  x-apisguru-categories:
    - messaging
  x-logo:
    url: https://sakari.io/wp-content/uploads/cropped-sakari-icon-512x512-180x180.png
  x-origin:
    - format: openapi
      url: https://developer.sakari.io/openapi.yaml
      version: "3.0"
  x-providerName: sakari.io
externalDocs:
  description: Find out more about Sakari
  url: https://sakari.io
tags:
  - 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....``
    name: authentication
  - description: Create, modify or delete contacts
    name: contacts
  - description: Send or track messages to one contact, a group of contacts or your entire address book
    name: messages
  - description: Define reusable message or web templates
    name: templates
  - description: Define reusable message campaigns with a predefined contact list/filter, template and schedule
    name: campaigns
  - description: Conversations group your message history with each contact into one thread
    name: conversations
  - description: Tools to assist with sending and receiving messages, such as file sharing, translation, etc.
    name: tools
  - 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: webhooks
paths:
  /oauth2/token:
    post:
      operationId: auth.token
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TokenRequest"
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TokenResponse"
          description: successful operation
      summary: Get token for accessing APIs
      tags:
        - authentication
      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/{accountId}/campaigns":
    get:
      operationId: campaigns.fetchAll
      parameters:
        - $ref: "#/components/parameters/accountId"
        - $ref: "#/components/parameters/offset"
        - $ref: "#/components/parameters/limit"
        - $ref: "#/components/parameters/nameFilter"
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CampaignsResponse"
          description: successful operation
        4XX:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
          description: invalid request
        5XX:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
          description: invalid request
      security:
        - sakari_auth: []
      summary: Fetch campaigns
      tags:
        - campaigns
      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:
      operationId: campaigns.create
      parameters:
        - $ref: "#/components/parameters/accountId"
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CampaignRequest"
      responses:
        "201":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CampaignResponse"
          description: successful operation
      security:
        - sakari_auth: []
      summary: Create campaign
      tags:
        - campaigns
      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}/campaigns/{campaignId}":
    delete:
      operationId: campaigns.remove
      parameters:
        - $ref: "#/components/parameters/accountId"
        - description: Campaign id to delete
          in: path
          name: campaignId
          required: true
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                properties:
                  success:
                    type: boolean
                type: object
          description: successful operation
      security:
        - sakari_auth: []
      summary: Deletes a campaign
      tags:
        - campaigns
      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;
              }
    get:
      operationId: campaigns.fetch
      parameters:
        - $ref: "#/components/parameters/accountId"
        - description: ID of campaign to return
          in: path
          name: campaignId
          required: true
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CampaignResponse"
          description: successful operation
      security:
        - sakari_auth: []
      summary: Fetch campaign by ID
      tags:
        - campaigns
      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:
      operationId: campaigns.update
      parameters:
        - $ref: "#/components/parameters/accountId"
        - description: ID of campaign
          in: path
          name: campaignId
          required: true
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CampaignResponse"
          description: successful operation
      security:
        - sakari_auth: []
      summary: Updates a campaign
      tags:
        - campaigns
      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;
              }
  "/v1/accounts/{accountId}/contacts":
    get:
      operationId: contacts.fetchAll
      parameters:
        - $ref: "#/components/parameters/accountId"
        - $ref: "#/components/parameters/offset"
        - $ref: "#/components/parameters/limit"
        - $ref: "#/components/parameters/firstNameFilter"
        - $ref: "#/components/parameters/lastNameFilter"
        - $ref: "#/components/parameters/mobileFilter"
        - $ref: "#/components/parameters/emailFilter"
        - $ref: "#/components/parameters/tagsFilter"
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ContactsResponse"
          description: successful operation
        4XX:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
          description: invalid request
        5XX:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
          description: invalid request
      security:
        - sakari_auth: []
      summary: Fetch contacts
      tags:
        - contacts
      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:
      operationId: contacts.create
      parameters:
        - $ref: "#/components/parameters/accountId"
        - description: Determines how existing contacts with matching mobile numbers are treated
          in: query
          name: mergeStrategy
          required: false
          schema:
            enum:
              - append
              - core
              - remove
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ContactRequest"
          text/csv:
            schema:
              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
              type: string
      responses:
        "201":
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/ContactsResponse"
                  - $ref: "#/components/schemas/ContactUploadResponse"
          description: successful operation
      security:
        - sakari_auth: []
      summary: Create contact
      tags:
        - contacts
      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}":
    delete:
      operationId: contacts.remove
      parameters:
        - $ref: "#/components/parameters/accountId"
        - description: Contact id to delete
          in: path
          name: contactId
          required: true
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                properties:
                  success:
                    type: boolean
                type: object
          description: successful operation
      security:
        - sakari_auth: []
      summary: Deletes a contact
      tags:
        - contacts
      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;
              }
    get:
      operationId: contacts.fetch
      parameters:
        - $ref: "#/components/parameters/accountId"
        - description: ID of contact to return
          in: path
          name: contactId
          required: true
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ContactResponse"
          description: successful operation
      security:
        - sakari_auth: []
      summary: Fetch contact by ID
      tags:
        - contacts
      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:
      operationId: contacts.update
      parameters:
        - $ref: "#/components/parameters/accountId"
        - description: ID of contact
          in: path
          name: contactId
          required: true
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ContactResponse"
          description: successful operation
      security:
        - sakari_auth: []
      summary: Updates a contact
      tags:
        - contacts
      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;
              }
  "/v1/accounts/{accountId}/conversations":
    get:
      operationId: conversations.fetchAll
      parameters:
        - $ref: "#/components/parameters/accountId"
        - $ref: "#/components/parameters/offset"
        - $ref: "#/components/parameters/limit"
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ConversationsResponse"
          description: successful operation
        4XX:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
          description: invalid request
        5XX:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
          description: invalid request
      security:
        - sakari_auth: []
      summary: Fetch conversations
      tags:
        - conversations
      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:
      operationId: conversations.fetch
      parameters:
        - $ref: "#/components/parameters/accountId"
        - description: ID of template to return
          in: path
          name: conversationId
          required: true
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ConversationResponse"
          description: successful operation
      security:
        - sakari_auth: []
      summary: Fetch conversation by ID
      tags:
        - conversations
      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:
      operationId: conversations.close
      parameters:
        - $ref: "#/components/parameters/accountId"
        - description: ID of conversation
          in: path
          name: conversationId
          required: true
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ConversationResponse"
          description: successful operation
      security:
        - sakari_auth: []
      summary: Closes a conversation
      tags:
        - conversations
      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}/messages":
    get:
      operationId: messages.fetchAll
      parameters:
        - $ref: "#/components/parameters/accountId"
        - $ref: "#/components/parameters/offset"
        - $ref: "#/components/parameters/limit"
        - $ref: "#/components/parameters/contactIdFilter"
        - $ref: "#/components/parameters/conversationIdFilter"
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MessagesResponse"
          description: successful operation
      security:
        - sakari_auth: []
      summary: Fetch messages
      tags:
        - messages
      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:
      operationId: messages.send
      parameters:
        - $ref: "#/components/parameters/accountId"
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SendMessagesRequest"
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SendMessagesResponse"
          description: successful operation
      security:
        - sakari_auth: []
      summary: Send Messages
      tags:
        - messages
      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:
      description: Returns a single messag
      operationId: messages.fetch
      parameters:
        - $ref: "#/components/parameters/accountId"
        - description: ID of message to return
          in: path
          name: messageId
          required: true
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MessageResponse"
          description: successful operation
      security:
        - sakari_auth: []
      summary: Fetch message by id
      tags:
        - messages
      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:
      operationId: templates.fetchAll
      parameters:
        - $ref: "#/components/parameters/accountId"
        - $ref: "#/components/parameters/offset"
        - $ref: "#/components/parameters/limit"
        - $ref: "#/components/parameters/nameFilter"
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TemplatesResponse"
          description: successful operation
        4XX:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
          description: invalid request
        5XX:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
          description: invalid request
      security:
        - sakari_auth: []
      summary: Fetch templates
      tags:
        - templates
      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:
      operationId: templates.create
      parameters:
        - $ref: "#/components/parameters/accountId"
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TemplateRequest"
      responses:
        "201":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TemplatesResponse"
          description: successful operation
      security:
        - sakari_auth: []
      summary: Create template
      tags:
        - templates
      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}":
    delete:
      operationId: templates.remove
      parameters:
        - $ref: "#/components/parameters/accountId"
        - description: Template id to delete
          in: path
          name: templateId
          required: true
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                properties:
                  success:
                    type: boolean
                type: object
          description: successful operation
      security:
        - sakari_auth: []
      summary: Deletes a template
      tags:
        - templates
      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;
              }
    get:
      operationId: templates.fetch
      parameters:
        - $ref: "#/components/parameters/accountId"
        - description: ID of template to return
          in: path
          name: templateId
          required: true
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TemplateResponse"
          description: successful operation
      security:
        - sakari_auth: []
      summary: Fetch template by ID
      tags:
        - templates
      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:
      operationId: templates.update
      parameters:
        - $ref: "#/components/parameters/accountId"
        - description: ID of template
          in: path
          name: templateId
          required: true
          schema:
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TemplateResponse"
          description: successful operation
      security:
        - sakari_auth: []
      summary: Updates a template
      tags:
        - templates
      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;
              }
  "/v1/accounts/{accountId}/webhooks":
    get:
      description: When messages are acknowledge by carriers, a notification is sent to the specified URL
      operationId: webhooks.fetchAll
      parameters:
        - $ref: "#/components/parameters/accountId"
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WebhooksResponse"
          description: successful operation
      security:
        - sakari_auth: []
      summary: Fetch active webhooks
      tags:
        - webhooks
      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:
      description: When messages are acknowledge by carriers, a notification is sent to the specified URL
      operationId: webhooks.subscribe
      parameters:
        - $ref: "#/components/parameters/accountId"
      requestBody:
        content:
          application/json:
            schema:
              properties:
                eventTypes:
                  items:
                    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
                    type: string
                  type: array
                url:
                  example: https://myserver.com/send/callback/here
                  format: uri
                  type: string
              required:
                - callbackUrl
              type: object
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WebhookResponse"
          description: successful operation
      security:
        - sakari_auth: []
      summary: Subscribe to message events
      tags:
        - webhooks
      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:
      callbacks:
        event:
          "{$request.body#/callbackUrl}":
            post:
              requestBody:
                content:
                  application/json:
                    schema:
                      $ref: "#/components/schemas/Event"
                required: true
              responses:
                "200":
                  description: Your server returns this code if it accepts the callback
      description: Delete subscription for receiving notifications
      operationId: webhooks.unsubscribe
      parameters:
        - $ref: "#/components/parameters/accountId"
        - description: Account to apply operations to
          in: path
          name: url
          required: true
          schema:
            type: string
      responses:
        "204":
          description: successful operation
      security:
        - sakari_auth: []
      summary: Unsubscribe to message events
      tags:
        - webhooks
      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/tools/sharefile:
    post:
      operationId: tools.shareFile
      requestBody:
        content:
          application/octet-stream:
            schema:
              format: binary
              type: string
          multipart/form-data:
            schema:
              properties:
                media:
                  format: binary
                  type: string
              type: object
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ShareFileResponse"
          description: successful operation
        4XX:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
          description: invalid request
        5XX:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
          description: invalid request
      security:
        - sakari_auth: []
      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
      tags:
        - tools
components:
  parameters:
    accountId:
      description: Account to apply operations to
      in: path
      name: accountId
      required: true
      schema:
        type: string
    contactIdFilter:
      description: ID of contact
      in: query
      name: contactId
      required: false
      schema:
        type: string
    conversationIdFilter:
      description: ID of conversation
      in: query
      name: conversationId
      required: false
      schema:
        type: string
    email:
      description: Email of contact
      in: query
      name: email
      required: false
      schema:
        type: string
    emailFilter:
      description: Filter by email or part of
      in: query
      name: email
      required: false
      schema:
        type: string
    firstName:
      description: First name of contact
      in: query
      name: firstName
      required: false
      schema:
        type: string
    firstNameFilter:
      description: Filter by first name or part of
      in: query
      name: firstName
      required: false
      schema:
        type: string
    lastName:
      description: Last name of contact
      in: query
      name: lastName
      required: false
      schema:
        type: string
    lastNameFilter:
      description: Filter by last name or part of
      in: query
      name: lastName
      required: false
      schema:
        type: string
    limit:
      description: Maximum number of results to return
      in: query
      name: limit
      required: false
      schema:
        format: int64
        maximum: 100
        minimum: 1
        type: integer
    mobile:
      description: Mobile of contact
      in: query
      name: mobile
      required: false
      schema:
        type: string
    mobileFilter:
      description: Filter by mobile or part of
      in: query
      name: mobile
      required: false
      schema:
        type: string
    nameFilter:
      description: Filter by name or part of
      in: query
      name: name
      required: false
      schema:
        type: string
    offset:
      description: Results to skip when paginating through a result set
      in: query
      name: offset
      required: false
      schema:
        format: int64
        minimum: 0
        type: integer
    tags:
      description: Tag of contact
      in: query
      name: tags
      required: false
      schema:
        type: string
    tagsFilter:
      description: Filter by tag(s)
      in: query
      name: tags
      required: false
      schema:
        type: string
  requestBodies:
    Contact:
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ContactRequest"
      description: Pet object that needs to be added to the store
      required: true
    Contacts:
      content:
        application/json:
          schema:
            items:
              $ref: "#/components/schemas/ContactRequest"
            type: array
      description: List of contacts
      required: true
  schemas:
    AccountEvent:
      properties:
        accountId:
          $ref: "#/components/schemas/AccountId"
        type:
          $ref: "#/components/schemas/EventType"
      type: object
    AccountEventPayload:
      properties:
        balance:
          format: double
          type: number
      type: object
    AccountId:
      type: string
    AttributeFilter:
      properties:
        comparator:
          enum:
            - =
            - <
            - <=
            - ">"
            - ">="
            - "!="
          type: string
        name:
          type: string
        value:
          type: string
      type: object
    Campaign:
      properties:
        id:
          type: string
      type: object
    CampaignRequest:
      properties:
        filters:
          properties:
            attributes:
              items:
                type: string
              type: array
            contacts:
              items:
                type: string
              type: array
            tags:
              items:
                type: string
              type: array
          type: object
        template:
          type: string
        trigger:
          properties:
            code:
              description: |
                Campaign type specifies how it sources contacts and what event triggers its execution  Sort order
                  * `M` - Manual
                  * `S` - Scheduled
                  * `FU` - File Upload
              enum:
                - M
                - S
                - FU
              type: string
          type: object
      type: object
    CampaignResponse:
      properties:
        data:
          $ref: "#/components/schemas/Campaign"
        success:
          type: boolean
      type: object
    CampaignsResponse:
      allOf:
        - $ref: "#/components/schemas/PaginatedResponse"
        - properties:
            data:
              items:
                $ref: "#/components/schemas/Campaign"
              type: array
          type: object
    Contact:
      allOf:
        - $ref: "#/components/schemas/ContactRequest"
        - properties:
            created:
              $ref: "#/components/schemas/Updated"
            error:
              $ref: "#/components/schemas/Error"
            updated:
              $ref: "#/components/schemas/Updated"
            valid:
              type: boolean
          type: object
    ContactIdentifiers:
      properties:
        email:
          example: chris@sakari.io
          type: string
        firstName:
          example: Chris
          type: string
        id:
          type: string
        lastName:
          example: Bloggs
          type: string
        mobile:
          properties:
            country:
              type: string
            number:
              example: 123-456-7890
              type: string
          type: object
      type: object
    ContactRequest:
      allOf:
        - $ref: "#/components/schemas/ContactIdentifiers"
        - properties:
            attributes:
              type: object
            tags:
              items:
                $ref: "#/components/schemas/Tag"
              type: array
          type: object
    ContactResponse:
      properties:
        data:
          $ref: "#/components/schemas/Contact"
        success:
          default: true
          type: boolean
      type: object
    ContactUploadResponse:
      properties:
        data:
          properties:
            contacts:
              description: Uploaded contacts
              items:
                $ref: "#/components/schemas/Contact"
              type: array
            errors:
              description: Contacts that failed validation
              items:
                $ref: "#/components/schemas/Contact"
              type: array
            inserted:
              type: integer
            submitted:
              type: integer
            success:
              type: integer
            updated:
              type: integer
          type: object
        success:
          default: true
          type: boolean
      type: object
    ContactsResponse:
      allOf:
        - $ref: "#/components/schemas/PaginatedResponse"
        - properties:
            data:
              items:
                $ref: "#/components/schemas/Contact"
              type: array
          type: object
    Conversation:
      properties:
        closed:
          type: boolean
        contact:
          $ref: "#/components/schemas/ContactIdentifiers"
        created:
          $ref: "#/components/schemas/Updated"
        id:
          type: string
        lastMessage:
          $ref: "#/components/schemas/Message"
        phoneNumber:
          $ref: "#/components/schemas/PhoneNumber"
        unread:
          items:
            type: string
          type: array
        updated:
          $ref: "#/components/schemas/Updated"
      type: object
    ConversationResponse:
      properties:
        data:
          $ref: "#/components/schemas/Conversation"
        success:
          type: boolean
      type: object
    ConversationsResponse:
      allOf:
        - $ref: "#/components/schemas/PaginatedResponse"
        - properties:
            data:
              items:
                $ref: "#/components/schemas/Conversation"
              type: array
          type: object
    Error:
      properties:
        code:
          example: CONT-010
          type: string
        description:
          example: Contact has requested no further communication
          type: string
      type: object
    ErrorResponse:
      properties:
        error:
          properties:
            code:
              example: CONV-001
              type: string
            message:
              example: Invalid conversation id
              type: string
          type: object
        success:
          default: false
          example: false
          type: boolean
      type: object
    Event:
      properties:
        accountId:
          $ref: "#/components/schemas/AccountId"
        data:
          oneOf:
            - $ref: "#/components/schemas/AccountEventPayload"
            - $ref: "#/components/schemas/MessageEventPayload"
        eventId:
          type: string
        type:
          $ref: "#/components/schemas/EventType"
      type: object
    EventType:
      enum:
        - account
        - messageStatus
        - messageIncoming
      example: message
      type: string
    Message:
      properties:
        contact:
          $ref: "#/components/schemas/ContactIdentifiers"
        conversation:
          properties:
            id:
              type: string
          type: object
        created:
          $ref: "#/components/schemas/Updated"
        error:
          $ref: "#/components/schemas/Error"
        id:
          type: string
        media:
          description: List of media objects attached to message
          items:
            properties:
              filename:
                type: string
              type:
                type: string
              url:
                type: string
            type: object
          type: array
        message:
          type: string
        outgoing:
          type: boolean
        phoneNumber:
          example: "+1234567890"
          type: string
        price:
          type: number
        read:
          type: boolean
        segments:
          type: number
        status:
          type: string
        template:
          type: string
        updated:
          $ref: "#/components/schemas/Updated"
      type: object
    MessageEventPayload:
      properties:
        contact:
          $ref: "#/components/schemas/ContactIdentifiers"
        error:
          type: string
        message:
          type: string
        status:
          type: string
      type: object
    MessageResponse:
      properties:
        data:
          $ref: "#/components/schemas/Message"
        success:
          type: boolean
      type: object
    MessagesResponse:
      allOf:
        - $ref: "#/components/schemas/PaginatedResponse"
        - properties:
            data:
              items:
                $ref: "#/components/schemas/Message"
              type: array
          type: object
    PaginatedResponse:
      properties:
        error:
          properties:
            code:
              type: string
            message:
              type: string
          type: object
        pagination:
          properties:
            limit:
              type: integer
            offset:
              type: integer
            totalCount:
              type: integer
          type: object
        success:
          type: boolean
      type: object
    PhoneNumber:
      properties:
        active:
          type: boolean
        country:
          type: string
        number:
          type: string
      type: object
    SendMessagesRequest:
      properties:
        contacts:
          items:
            $ref: "#/components/schemas/ContactRequest"
          type: array
        conversationStrategy:
          type: string
        conversations:
          description: List of conversation ids to send messages to
          items:
            type: string
          type: array
        filters:
          properties:
            attributes:
              items:
                type: object
              type: array
            tags:
              items:
                type: string
              type: array
          type: object
        media:
          description: List of media objects to attach to message
          items:
            properties:
              url:
                type: string
            type: object
          type: array
        phoneNumberFilter:
          properties:
            group:
              properties:
                id:
                  type: string
              type: object
          type: object
        template:
          type: string
        type:
          enum:
            - SMS
            - MMS
          type: string
      type: object
    SendMessagesResponse:
      properties:
        data:
          properties:
            estimatedPrice:
              format: double
              type: number
            invalid:
              items:
                $ref: "#/components/schemas/Contact"
              type: array
            jobId:
              type: string
            messages:
              items:
                $ref: "#/components/schemas/Message"
              type: array
            requested:
              type: integer
            valid:
              type: integer
          type: object
      type: object
    ShareFileResponse:
      properties:
        data:
          properties:
            expires:
              format: date-time
              type: string
            link:
              type: string
          type: object
        success:
          type: boolean
      type: object
    Tag:
      properties:
        tag:
          type: string
        visible:
          type: boolean
      type: object
    Template:
      allOf:
        - $ref: "#/components/schemas/TemplateRequest"
        - properties:
            id:
              type: string
          type: object
    TemplateRequest:
      properties:
        name:
          type: string
        template:
          example: Hi {{{firstName}}}. Grab 20% off today only at ABC Shoes
          type: string
        type:
          enum:
            - SMS
            - Web
          example: SMS
          type: string
      type: object
    TemplateResponse:
      properties:
        data:
          $ref: "#/components/schemas/Template"
        success:
          type: boolean
      type: object
    TemplatesResponse:
      allOf:
        - $ref: "#/components/schemas/PaginatedResponse"
        - properties:
            data:
              items:
                $ref: "#/components/schemas/Template"
              type: array
          type: object
    TokenRequest:
      properties:
        client_id:
          example: 00000000-0000-0000-0000-00000000000
          type: string
        client_secret:
          example: 00000000-0000-0000-0000-00000000000
          type: string
        grant_type:
          example: client_credentials
          type: string
      type: object
    TokenResponse:
      properties:
        access_token:
          type: string
        token_type:
          type: string
      type: object
    Updated:
      properties:
        at:
          format: date-time
          type: string
        by:
          properties:
            firstName:
              example: Joe
              type: string
            id:
              type: string
            lastName:
              example: Bloggs
              type: string
          type: object
      type: object
    Webhook:
      properties:
        eventTypes:
          items:
            enum:
              - message-received
              - message-status
              - message-sent
              - conversation-closed
              - contact-created
              - contact-updated
              - contact-removed
            type: string
          type: array
        url:
          type: string
      type: object
    WebhookResponse:
      properties:
        data:
          $ref: "#/components/schemas/Webhook"
        success:
          type: boolean
      type: object
    WebhooksResponse:
      allOf:
        - $ref: "#/components/schemas/PaginatedResponse"
        - properties:
            data:
              items:
                $ref: "#/components/schemas/Webhook"
              type: array
          type: object
  securitySchemes:
    sakari_auth:
      flows:
        clientCredentials:
          scopes:
            messages:send: Send messages
          tokenUrl: /oauth2/token
      type: oauth2
