openapi: "3.0.1"
info:
  title: "Gladly API"
  version: "1.0"
  description: |
    # Introducing the Gladly API

    At Gladly, we believe that customer service is best when it's a conversation.
    That means more than just helping customers with one-off questions or issues: it's about making them feel known, valued, and respected for the individuals they are.

    The Gladly API was built to help facilitate those relationships, providing agents with the rich customer context
    they need to deliver seamless experiences that make customers feel like they're more than just a number in a sea of others.

    # Overview

    You can integrate easily with Gladly by calling Gladly's [REST API](#section/Overview/REST-API)
    and implementing the [Lookup API](#section/Overview/Lookup-API) to provide data from your own services.

    Some examples of what you do through Gladly APIs include managing customer profile data, interacting with a customer's timeline,
    providing the latest information about a customer's orders, and more.

    ## REST API

    Clients can access the **REST API** via HTTPS at your organization's Gladly domain (e.g. `https://{organization}.gladly.com`).

    Resources follow REST semantics and utilize industry-standard HTTP verbs, response codes, and authentication schemes.
    In addition, all responses and payloads are in JSON with consistent error codes and formats.

    ## Lookup API

    The Gladly **Lookup API** allows your organization to provide data services to power the agent's experience with a complete view of your customers'
    information, transactions, and activity. You can provide a web service that implements the Lookup API and Gladly will call it when that data is needed.

    Like the REST API, the Lookup API is specified using REST semantics, and exchanges JSON requests and responses authenticated and signed with secure keys.

    Gladly will perform lookups when certain activities occur within Gladly, such as when a customer's profile is loaded.

    A detailed overview of Lookup Adaptor architecture, requests, resposnes and more can be found [here](https://help.gladly.com/developer/docs/lookup-adapter-introduction).

    ## Testing

    Test the myriad possibilities of the Gladly API in a safe, secure space. We'll enable the Gladly API in a separate sandbox environment, so you can experiment freely without impacting your production environment (or vice versa).

    Your sandbox environment is accessible at `https://{organization}.gladly.qa`, where `organization` is your company name. For specific API endpoints, see documentation below.

    # Getting Started

    Think of this section as getting the keys to unlocking your access to the Gladly APIs.
    First, you'll need to set up an account with the necessary API [permissions](#/section/Getting-Started/Permissions).
    With these permissions, you can then go on to create the [API Token(s)](#section/Getting-Started/Creating-API-Tokens) you need to access Gladly's API [resources](#section/Overview/Resources).

    ## Permissions

    Gladly Administrators can set API permissions on an agent-by-agent basis.
    We'll discuss how this maps to API access in the section on [authentication](#section/Authentication) below.

    To allow a user to create API tokens and access the API:
    1. Log in to your Gladly instance.
    2. Open the menu on the top left-hand corner of the page.
    3. Navigate to **Settings** > **Users*
    4. Search and click the user profile you wish to give access to.
    5. You'll see a permission called **API User**. Select it, while making sure to keep the user's **Agent** role intact.
    6. Hit **Save** to give access.

    ![Agent profile screen](assets/permissions-agent.png)

    We recommend creating a dedicated user to make API calls, whose account won't be used for agent and organization management.
    This will help you with any future audits of API activity vs. agent activity.

    ## Creating API Tokens

    You must create an API token to access Gladly API resources (see above [Permissions](#/section/Getting-Started/Permissions)).
    If your profile already has access to the **API User** permission, you'll see a menu item titled **More settings**. Click **More settings**:

    ![API Token Menu](assets/permissions-token-nav.png)

    Click **API Tokens**, then the **Create Token** button on the upper right-hand corner of the page:

    ![API Token Add](assets/permissions-token-add.png)

    A token will be generated and named, by default, **New Token** (though depending on whether you have existing tokens, it may be named New Token 2, or New Token 3, etc.).
    You can rename the token to something more easily referenceable by clicking the name to edit.

    This token will be associated with your agent profile, which we refer to as the API User in this document.

    ![API Token View](assets/permissions-token-view.png)

    For security purposes, you'll only see a new token once before you navigate away from the page.

    ## Replacing/Rotating API Tokens

    Should you lose this token, or wish to rotate your application keys, you can do the following:

    1. Generate a new token.
    2. Store the new token in a secure location.
    3. Delete the old token.
    4. Update your applications/scripts with the new token.

servers:
  - url: "https://organization.gladly.com"
tags:
  - name: Agents
    description: |
      An **Agent** represents the user profile of a person who helps customers in Gladly.
      The API allows you to lookup Agents who participated in conversations with customers.

  - name: Public Answer
    description: |
      A **Public Answer** in Gladly represents a consumer-facing Answer.

      The Public Answers API allows you to search and retrieve Public Answers (created
      directly in the Gladly UI), which you can display in the Chat
      web widget, use to build your website's help center/FAQ page, or publish
      on any page on your website.

      This API can be used without an API token because it only provides access to
      public content. You may also work with Gladly Support to
      enable [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
      access so the API can be used directly from client-side javascript.

      ### How a user creates a public answer in Gladly

      ![](assets/create-public-answer.png)

      ### How that answer is searched and displayed on the Chat Web widget

      ![](assets/sidekick-answer-search.png)

  - name: Answer Management
    description: |
      The **Answer Management API** allows you to create, update, and delete Answers in Gladly. To create an Answer with content, two calls would be needed. 
      One call to create an Answer and subsequent call(s) to add content(s)

  - name: Audiences
    description: |
      An **Audience** represents a brand (or segment) specially for a multi-brand company. They are used to categorize Answers, Help Centers and Chats for the specific brands.
      The API allows you to lookup the audiences that have been created for the organization.

  - name: Communications
    description: |
      Communications API enables you to programmatically send messages to your customers. These messages are non-routable and non-searchable.

      ### Agent View
      ![Agent View](assets/agent-sms.png)

      ### Consumer View
      ![Customer View](assets/consumer-sms.png)

  - name: Customers
    description: |
      A **Customer** in Gladly represents information about a customer of your organization including their profile, contact information,
      notes, and transactions.

      Customers API allows you to add, update, and get customer profile data.

      ### Error Handling
      Id, mobile phone number, and email address must be unique across customer records. 409 errors returned will
      include details on any conflicts, such as a field being taken.

      Additionally, errors may be returned due to customer profiles being merged. If a customer has been merged into
      another, requests to get a customer by id will return 301 errors specifying the new id of the customer, and
      requests to delete a customer by id will return 410 errors specifying the same. Requests to update a customer
      by id do not resolve the merged id and return 404 errors.

  - name: Conversations
    description: |
      ## Conversation

      A **Conversation** in Gladly contains the timeline of activity for a customer including communications to and from your organization along with other internal and external activity.
      Conversations API enables you to interact with the customer conversation timeline.

      ### Error Handling

      Conversations can be merged into one another when their customers are merged. An endpoint
      that resolves a conversation or customer id which was merged away does not return `404`;
      it reports the surviving id in `meta.new` of a `moved` error.

      `GET /api/v1/conversations/{conversationId}` returns `301` with a `Location` header, so
      clients that follow redirects transparently receive the surviving conversation. The other
      endpoints that resolve a merged id return `410 Gone` with no `Location` header; reissue
      the request against the id in `meta.new`. Each operation lists `410` among its responses
      where this applies.

      Endpoints addressed by a conversation item id, and those that list conversations for a
      customer, do not resolve the merged id and are unaffected.

      ## Conversation Items

      A number of different types of items may appear in a customer's timeline. Each is described below.

      | Item Type                     | Item Definition | Create | Read | Update | Delete | Media  |
      |-------------------------------|----------------|--------|------|--------|--------|--------|
      | Chat Message                  | A message sent/received via the [Chat](https://help.gladly.com/docs/add-and-configure-chat-entry-points#) channel | Yes    | Yes  | No     | No     | No     |
      | Conversation Status Change    | Conversation status changed (e.g.: from OPEN to WAITING, or OPEN to CLOSED) | Yes    | Yes  | Yes    | No     | No     |
      | Customer Activity             | Non-routable customer activity added to customer timeline via API | Yes    | Yes  | No     | Yes    | No     |
      | Email                         | A message sent/received via the [Email](https://help.gladly.com/docs/add-and-configure-email-entry-point) channel | Yes    | Yes  | No     | No     | No     |
      | Facebook Messenger Message    | A message sent/received via the [Facebook Messenger](https://help.gladly.com/docs/set-up-and-configure-facebook-messenger) channel | Yes    | Yes  | No     | No     | No     |
      | Instagram Direct              | A message sent/received via the [Instagram](https://help.gladly.com/docs/set-up-and-configure-instagram-messaging) channel | No     | Yes  | No     | No     | No     |
      | Note                          | An internal [Note](https://help.gladly.com/docs/add-a-note-to-a-conversation) on the Customer conversation | Yes    | Yes  | No     | No     | No     |
      | Phone Call                    | A [Phone Call](https://help.gladly.com/docs/add-and-configure-voice-entry-points) placed/received on Gladly | No     | Yes  | No     | No     | Yes    |
      | SMS Message                   | A message sent/received via the [SMS](https://help.gladly.com/docs/add-and-configure-sms-entry-points) channel | Yes    | Yes  | No     | No     | No     |
      | Task                          | A [Task](https://help.gladly.com/docs/what-is-a-task) on a Customer's profile | Yes    | Yes  | Yes    | No     | No     |
      | Topic Change                  | A [Topic](https://help.gladly.com/docs/what-are-topics) added or removed on a Conversation | Yes    | Yes  | No     | Yes    | No     |
      | Twitter (decommissioned as of 04/20/23)                       | A message sent/received via the [Twitter](https://help.gladly.com/docs/setup-and-configure-twitter-direct-messages) channel | No     | Yes  | No     | Yes    | No     |
      | Voice AI Message              | A spoken message exchanged with Gladly's voice AI during a voice AI session | No     | Yes  | No     | No     | No     |
      | Voicemail                     | A Voicemail received | No     | Yes  | No     | No     | Yes    |
      | WhatsApp                      | A message sent/received via the WhatsApp channel | No     | Yes  | No     | No     | No     |


      ### Chat Message

      Content of messages sent between Gladly and customers through Gladly Chat.

      ### Conversation Status Change

      Record of a change in the status of a conversation.

      ### Customer Activity

      Information about activities customers participated in, for example, emails they received, issues in another system, or customer satisfaction surveys they answered.
      These can be created through the API to bring in information from other systems.
      Adding an activity to the customer timeline is not customer facing.
      For example, posting an email activity to the timeline does not send an email to the customer.
      ![Customer Activity](assets/customer-activity.png)

      ### Email

      Content of emails sent between Gladly and customers.

      ###  Facebook Messenger Message

      Content of messages sent between Gladly and customers on Facebook Messenger.

      ### Instagram Direct

      Content of messages sent between Gladly and customers on Instagram Direct.

      ###  Note

      Content of the note recorded in Gladly.

      ### Phone Call

      Information about phone calls that took place between Gladly and customers.

      ### SMS Message

      Content of SMS text messages sent between Gladly and customers.
      To send SMS messages to customers through the API, see [Send SMS](#operation/sendSMS).

      ### Task

      Interacting with tasks through the conversations API is deprecated. Use [Tasks API](#tag/Tasks) instead.

      ### Topic Change

      Record of an agent adding or removing a topic from a conversation in Gladly.

      ### Twitter (decommissioned as of 04/20/23)

      Content of messages sent between Gladly and customers on Twitter.

      ### Voice AI Message

      A spoken message exchanged between a customer and Gladly's voice AI during a voice AI session.

      ### Voicemail

      Information about voicemail left by customers in Gladly.

      ### WhatsApp

      Content of messages sent between Gladly and customers on WhatsApp.

  - name: Export
    description: |
      Export API is a simple, comprehensive, file-based data export. You can export the lifetime of your customers' conversations in Gladly to a central data repository such as your data warehouse or data lake. You can export all communications successfully delivered within a specified date range.  The export date range could be the past hour, the past 24 hours, or a custom data range. Please note, for one-time exports covering a period greater than six months, a service fee may apply.

      Job results can be deleted once downloaded.  Delete will remove all result files along with the job metadata.  Files older than 14 days are removed from Gladly and jobs older than 14 days are not available from the API.  If you discover that you need the deleted files later, please contact Gladly Support to regenerate them for you.

      ### SCHEDULING EXPORT JOBS

      You can schedule a one-time or repeating - hourly or daily - data export job.  By default, each organization has a daily export job configured.  To schedule a one-time job or change the job frequency, please contact Gladly Support.

  - name: Endpoints
    description: |
      An **Endpoint** represents an inbound address that customers use to reach your organization — for example an email address, a phone number, or a chat channel. Each endpoint has a `channel` describing the type of contact it receives (`EMAIL`, `SMS`, `VOICE`, `CHAT`, and so on).

      The Endpoints API is read-only. It allows you to retrieve the endpoints configured for your organization so you can programmatically discover which channels and addresses your organization is set up to receive customer contacts on.

  - name: Events
    description: |
      An **Event** is something that has happened in Gladly. The Events API allows you to extract event details from the past 24 hours.

  - name: Freeform Topics
    description: |
      Freeform Topics allow you to associate granular data like Order Number to a Conversation. This data can be accessed for analysis via APIs, Webhooks, and AWS EventBridge. They are powered by custom attributes as you will see throughout this API, the Conversations API, the Events API and events used in Webhooks. 

      Note: These attributes are associated to the Conversation and Task entities and are therefore different from customAttributes listed under the Customer entity. See the Customer API for more information on Customer custom attributes.

  - name: Reports
    description: |
      A **Report** in Gladly contains metrics that you need to run the contact center. Reports API allows you to access Gladly's reports programatically.

  - name: Organization
    description: |
      An **Organization** contains metadata about your company that Gladly is configured with.

  - name: Inboxes
    description: |
      An **Inbox** receives customer communications in Gladly. The communications route to the inbox according to channel and destination endpoint configuration.
      For example, all calls to a specific phone number or emails to a specific address may go to an inbox.

  - name: Proactive Conversations
    description: |
      A proactive conversation consists of a **campaign** and **recipients**. This APIs intended use-case would be to provide status updates to a customer and not for marketing purposes.

  - name: Tasks
    description: |
      A task is a way to create and do internal follow-up work for a customer within Gladly. Tasks have a due date, an assignee, a description of what is needed for a customer, and can be commented on. Tasks can also be assigned topics and freeform topics. These can be created through the API to assign items to work within Gladly.
      ![Task](assets/task.png)

  - name: Teams
    description: |
      A **Team** represents a group of Agents. They may handle particular **Inboxes** or types of work within Gladly.

  - name: Business Hours
    description: |
      **Business Hours** define the operating schedule for your organization. They determine when your organization is available to handle customer communications and can be used to control routing, auto-responses, and other time-sensitive workflows.

      Business hours configurations include:
      - **Schedule blocks** for each day of the week specifying start and end times
      - **Timezone** in IANA format (e.g., America/Los_Angeles)
      - **Exceptions** for holidays or special dates

      One business hours configuration is marked as **primary** and serves as the default schedule for your organization. The primary business hours cannot be deleted.

  - name: Topics
    description: |
      A **Topic** is a way of labeling a conversation in Gladly for specific business purposes. For example, an agent may apply the topic "Return" to a conversation where a customer returns merchandise.
      Topics are used for reporting and to control various workflows.

      Topics can be configured to have a nested hierarchy. For instance, the topic "Return" could be a parent of "Size" and "Color" child topics. Visit our [Help Pages](https://help.gladly.com/docs/principles-of-hierarchical-topics) to learn more about Hierarchical Topics.

  - name: Webhooks
    description: |
      A **Webhook** is a way to send notifications about Gladly events as a POST request to the endpoint of your choice.

  - name: Summary
    description: |
      Gladly **webhooks** are an easy way to send notifications about Gladly events and have them delivered to the endpoint of your choice, giving you a streamlined method to trigger associated actions in external systems that respond to events in Gladly.

      Simply choose where to send notifications about events that you are interested in (e.g. when a conversation is closed), and they’ll be delivered to the endpoint of your choice.

      Configure webhooks using the [Webhooks API](#operation/createWebhook) or the Webhooks Admin Page.

      Users with API User permissions can configure webhooks by navigating to Integrations > Webhooks.

      ![Webhooks admin page](assets/webhooks-admin.png)

      ## Securing Webhooks
      We provide two methods for your web service to authenticate requests from Gladly.
      We recommend implementing at least one **authentication** option.

      ### Basic Authentication

      For this method you will supply a username and password with the webhooks `credentials` field. This will be sent with each request. You may optionally supply a realm if needed.

      ### Header Based Token Authentication

      For this method you will configure one or more HTTP headers with the webhook's `headers` field. Gladly will send in each request to your web service.

      ## Ping Event
      Whenever you enable a webhook or update a webhook's URL, we'll send you a special `PING` event.

      Your web service is expected to respond with a 200 status code to this event. If it does not respond or times out, the webhook create or update will not succeed.

      ## Retry Policy

      **Effective 6/28/23**

      If your service responds to an event with a response code outside the 2XX range or times out after 15 seconds, Gladly considers that delivery as failed and will resend the request up to 4 times over an hour. After the fourth attempt, we will deactivate the webhook and wil notify all API Users in your organization's environment via email. 

      To reactivate the webhook, your team will first need to investigate the issue and make the necessary changes for the webhook to start working again. Once the issue is resolved, you will be able to re-activate the webhook via the Settings > Webhooks page.

      The following table shows the intervals between each retry attempt.

      | Attempt | Retry interval           |
      | ------- | ------------------------ |
      | 1       | 30 seconds               |
      | 2       | 5 minutes                |
      | 3       | 30 minutes               |
      | 4       | 1 hour                   |

      ## Logs
      We provide the last 100 HTTP request logs for a webhook that occurred during the past month. Logs can take up to 30 seconds to view and require you to refresh the page.

      ![Webhook Logs](assets/webhook-log.png)

      Each log displays the status, event type and occurred at timestamp for a given request. You can expand the log for more details about the request and response.
      For more information about webhook logs, please see our [Help Documentation](https://connect.gladly.com/docs/help-documentation/article/reactivate-deactivated-webhooks/?highlight=webhook).

      ## Payloads
      Gladly payloads are intentionally small: they contain only Gladly IDs and event names rather than the object/data that has been modified or created

      This helps Gladly webhooks perform more quickly when many events occur throughout the day. This also assists with security, so if you misconfigure a webhook, it does not send sensitive information to an outside service.

      To retrieve more information about the object in question, you may make an additional Gladly API call to retrieve the Gladly object. For example, to know more about conversationId whose status was updated, call the [GET Conversation API](#operation/getConversation) or the [List Items in Conversation API](#operation/getConversationItems).

      ## Available Events
      Please see the [Help Documentation](https://help.gladly.com/docs/reporting-concepts) for more information about many of the events listed below.

      | Event                         |  Triggered by Gladly when:                                    |
      | ------------------------------| --------------------------------------------------------------|
      | AGENT_AVAILABILITY/UPDATED         | an Agent's availability is updated |
      | AGENT_STATUS/CHANGED_ACTIVE_REASON | an Agent's active reason is updated |
      | AGENT_STATUS/LOGGED_IN             | an Agent logs in |
      | AGENT_STATUS/LOGGED_OUT            | an Agent logs out |
      | AGENT_STATUS/RETURNED_FROM_AWAY    | an Agent returns from away |
      | AGENT_STATUS/WENT_AWAY             | an Agent goes away |
      | CONTACT/ENDED                      | a Contact is ended |
      | CONTACT/FULFILLED                  | a Contact's SLA is fulfilled |
      | CONTACT/HOLD_ENDED                 | a Contact's hold is ended |
      | CONTACT/HOLD_STARTED               | a Contact's hold is started |
      | CONTACT/JOINED                     | an Agent joins a Contact |
      | CONTACT/MESSAGE_RECEIVED           | a Message is received |
      | CONTACT/MESSAGE_SENT               | a Message is sent |
      | CONTACT/OFFER_ACCEPTED             | a Contact's offer is accepted |
      | CONTACT/OFFERED                    | a Contact is offered |
      | CONTACT/OFFER_REJECTED             | a Contact's offer is rejected |
      | CONTACT/STARTED                    | a Contact is started |
      | CONTACT/TRANSFERRED                | a Contact is transferred |
      | CONVERSATION/CLOSED                | a Conversation is closed                                      |
      | CONVERSATION/CREATED               | a new Conversation is created                                 |
      | CONVERSATION/CUSTOM_ATTRIBUTE_ADDED | a custom attribute has been added to the conversation                                 |
      | CONVERSATION/CUSTOM_ATTRIBUTE_REMOVED | a custom attribute has been removed from the conversation                                 |
      | CONVERSATION/NOTE_CREATED          | a Note is added to a Conversation |
      | CONVERSATION/REOPENED              | a Conversation is reopened
      | CONVERSATION/TOPIC_ADDED           | a topic is added to a Conversation |
      | CONVERSATION/TOPIC_REMOVED         | a Conversation's topic is removed |
      | CONVERSATION_ASSIGNEE/UPDATED      | a Conversation's assignee (inbox and/or Agent) changes         |
      | CONVERSATION_STATUS/UPDATED        | a Conversation changes statuses (e.g.: from OPEN to CLOSED)   |
      | CUSTOMER/MERGED                    | a Customer Profile is merged with another profile                 |
      | CUSTOMER_PROFILE/CREATED           | a Customer Profile is created                                 |
      | CUSTOMER_PROFILE/DELETED           | a Customer Profile is deleted                                 |
      | CUSTOMER_PROFILE/MERGED            | a Customer Profile is merged with another profile       |
      | CUSTOMER_PROFILE/UPDATED           | a Customer Profile is updated (e.g.: name is updated)         |
      | EXPORT_JOB/COMPLETED               | a [data export job](#operation/findJobs) is completed                               |
      | EXPORT_JOB/FAILED                  | a [data export job](#operation/findJobs) fails to complete                           |
      | PAYMENT_REQUEST/CREATED            | a payment request is created |
      | PAYMENT_REQUEST/STATUS_CHANGED     | a payment request's status changes |
      | PAYMENT_REQUEST/VIEWED             | a payment request is viewed by the Customer |
      | PING                               | a webhook is initially created to verify serivce availability |
      | TASK/ASSIGNEE_UPDATED              | a task's assignee is updated |
      | TASK/CLOSED                        | a task is closed |
      | TASK/COMMENT_ADDED                 | a comment is added to a task |
      | TASK/CONTENT_UPDATED               | the content of a task is updated |
      | TASK/CREATED                       | a task is created |
      | TASK/DUE_DATE_UPDATED              | the due date of a task is updated |
      | TASK/FOLLOWER_ADDED                | a follower is added to a task |
      | TASK/FOLLOWER_REMOVED              | a follower is removed from a task
      | TASK/REOPENED                      | a closed task is reopened |

  - name: Customer Lookup
    description: |
      **Customer Lookup** allows you to provide a web service to search and get customer profile data and transactions.

      To support Customer Lookup, your organization will deploy an adaptor service (aka Lookup Adaptor) running on your network that implements the Lookup API.

      From there you can can connect the service to internal systems providing customer and transaction data.

      ![Lookup Architecture](assets/lookup-adapter-arch.svg)

      ### Overview

      Building a Lookup Adaptor will allow you to showcase extended customer profile information and actions in Gladly. For example, you may extend the customer profile in Gladly with loyalty points and lifetime value to assist with VIP routing. You can also display historical orders in Gladly to allow agents to view frequently used directly in Gladly without having to go to another system. You can even extend Gladly with Actions so that agents can cancel orders or award loyalty points directly in Gladly!

      On a high-level, Gladly will perform a request to your Customer Lookup integration(s) to retrieve extended information from your system(s) about a Customer Profile in Gladly.

      To ensure performance, Gladly recommends that your Customer Lookup integration(s) be able to respond back to the Gladly POST request in < 5 seconds. Gladly will terminate the request in 15 seconds if it receives no response from your integration(s). Please note that if one Customer Lookup integration times out / responds with an error that Gladly will consider this an error for all Customer Lookup integration(s).

      ### Sample code

      Sample code for building a Customer Lookup integration can be found [here](https://github.com/gladly/lookup-practice).

      ### Architecture, Setup, Authentication, Sample Requests and More

      A detailed overview of Lookup Adaptor architecture, requests, resposnes and more can be found [here](https://help.gladly.com/developer/docs/lookup-adapter-introduction).

  - name: Versioning
    description: |
      As we evolve the Gladly API over time, changes will be either added to the current version of the API (i.e. **[backwards compatible changes](#backwards-compatible-changes)**),
      or result in a new version that you will need to integrate with afresh (i.e. **[non-backwards compatible changes](#non-backwards-compatible-changes)**).

      ## URL Path Versioning

      The various versions of the Gladly API will be differentiated via global versioning, with the relevant version number reflected within the path parameter of the URL:

          https://organization.gladly.com/api/v{major-version-number}/{resource path}

      ## Backwards Compatible Changes

      For the most part, changes to the API will be backwards compatible, such as adding resources, additional fields to response objects,
      new value types for enums, or expanding a validation constraint to be more accepting.

      Ensure your client can gracefully handle or ignore unfamiliar fields and values so it continues to operate smoothly over the lifespan of an API version.

      ## Non-Backwards Compatible Changes

      Versions will be upleveled when a non-backwards compatible change occurs. This should not happen often, but can occur in the case of:
      - a field being removed from an object
      - a resource path no longer being supported
      - changing the type of a field
      - adding a new required parameter for a resource
      - constricting the validation parameters for a request

      These will only occur when absolutely necessary and a summary of the changes from version to version can be viewed in the release notes.
      Previous versions will be supported for a period of time before being removed after providing ample advanced notice.

  - name: Error Handling
    description: |
      Wherever possible, Gladly uses standard HTTP status codes to signal the success or failure of a call.
      Generally speaking, `2xx` statuses indicate success, `3xx` statuses indicate the client must take further action such as redirection,
      `4xx` statuses indicate an error with the input supplied by the client, `5xx` statuses indicate an unexpected error from Gladly servers (these will be rare cases).

      ## Common Status Codes

      | HTTP Status | Description |
      | ----------- | ------------------------------------------------- |
      | 200         | Success with results in response body             |
      | 201         | Resource created                                  |
      | 204         | Success with empty response body                  |
      | 301         | The resource location has moved                   |
      | 400         | API usage error                                   |
      | 401         | Authentication not provided                       |
      | 403         | User does not have persmission to access resource |
      | 404         | Resource is not found                             |
      | 410         | Resource was merged into another and is gone      |
      | 429         | Rate limit reached                                |

      ## Programmatic Remediation
      In the case of a `400` response, there will be a structured list of `error` objects that will provide information to correct the error.
      The error object will contain a `code` to describe the problem.

      The most common codes are:

      | Code         | Description                            |
      | ------------ | -------------------------------------- |
      | blank        | Presence error                         |
      | invalid      | Format error                           |
      | moved        | This resource is now located elsewhere; `meta.new` carries the id to use |
      | not_a_number | Value not numeric error                |
      | present      | Absence error                          |
      | taken        | Uniqueness error                       |
      | too_long     | Exceeds permissible length error       |
      | wrong_length | Length is not equal to expected error  |

      Refer to the errors section of each endpoint for more information.

      Example:

          {"errors":[{"code":"blank","detail":"one of emailAddress, phoneNumber must be present"}]}

  - name: Rich Content
    description: |
      In some data properties, HTML markup is supported for formatting rich content to display within Gladly.
      For security and readability, only a limited set of HTML tags and attributes are allowed.

      | Tags                | Attributes                                                                          |
      | ------------------- | ----------------------------------------------------------------------------------- |
      | a                   | href, target                                                                        |
      | img                 | src, align, alt, height, width                                                      |
      | h1, h2, h3          |                                                                                     |
      | hr, br              |                                                                                     |
      | div                 | style                                                                               |
      | span, p             |                                                                                     |
      | font                | size, color                                                                         |
      | strong, em, b, i, u |                                                                                     |
      | ul, ol              | type                                                                                |
      | li                  | type, value                                                                         |
      | dl, dt, dd          |                                                                                     |
      | table               |                                                                                     |
      | tbody, tfoot        | align, valign                                                                       |
      | col, colgroup       | align, valign, height, width, span                                                  |
      | thead, tr           | align, valign                                                                       |
      | td, th              | align, valign, style, abbr, colspan, rowspan, headers, height, width, scope, nowrap |
      | caption             |                                                                                     |

      The `style` attribute may use style properties: `border-left`, `margin`, `padding-left`, `text-align`, `background-color`.

  - name: Launching Soon
    description: |
      We are continuously expanding Gladly's integration capabilities. To get early access to any of the following features, please contact Gladly Support.

      ## New Integrations

      Create customer service experiences that fit your business and delight your customers. We continue to build integrations with applications that your teams already rely on today. Customer satisfaction, quality assurance, workforce management, email marketing, and order management are application categories we're focusing on next. For the list of available integrations, see our [Integrations Library](https://www.gladly.com/integrations/).

      ## New APIs

      If you can't wait for native integrations mentioned above, you can integrate your apps with Gladly using a growing list of APIs and webhook events.  Sign up for our [release notes](https://gladly.com/product-release) to be notified of new developments.

  - name: Rate Limit
    description: |
      The number of requests for an **[organization](/rest/#tag/Organization)** is rate limited for all APIs to ensure that adequate resources are available for all customers.

      Gladly has two types of API rate limits:

      ### Request Limit
      Request limits are applied on a per-second basis and are implemented to protect against denial-of-service attacks. This ensures that adequate resources are available for all customers.

      ### Concurrency Limit
      Concurrency limits are applied on the number of simultaneous requests to the endpoint. For example, a few long-lasting requests to an API endpoint simultaneously might exceed the concurrent rate limit for that endpoint.

      ## Default Rate Limit

      Organizations that send many requests in quick succession may see error responses that show up as status code **`429`**.
      >Individual APIs may have their own API Rate Limit and will be documented as such. Otherwise, the following default rate limits apply.

      | Method              | Request Limit                     | Concurrency Limit           |
      | ------------------- | -----------------------------------|----------------------------------|
      | GET                 | 10 Requests per second             | Not Applicable                   |
      | POST                | 10 Requests per second             | Not Applicable                   |
      | PUT                 | 10 Requests per second             | Not Applicable                   |
      | PATCH               | 10 Requests per second             | Not Applicable                   |
      | DELETE              | 10 Requests per second             | Not Applicable                   |

      We may adjust limits to prevent abuse.

      If you have questions about rate limited requests, please contact [Gladly Support](https://help.gladly.com/docs/contact-gladly-support).

      ## Reporting API Rate Limit

      The [Reports](#tag/Reports) APIs have slightly different default rate limits than other APIs.

      | Method              | Request Limit                     | Concurrency Limit           |
      | ------------------- | -----------------------------------|----------------------------------|
      | POST                | 10 Requests per minute             | 2 concurrent requests at a time across the entire organization                   |

      ## Handling Rate Limit

      The Gladly API response headers include the organization's current rate limit and the number of requests remaining in the current second.
      The remaining limit is calculated using the total number of requests received from all clients with your organization's API tokens.

      ```json
        Ratelimit-Limit-Second
        Ratelimit-Remaining-Second
      ```

      You can anticipate hitting the rate limit by checking these headers.

      One technique for gracefully handling rate-limited requests is to watch for **`429`** status codes and implement a client-side retry mechanism with an exponential backoff schedule.
      We’d also recommend building some randomness into the backoff schedule to avoid a **[thundering herd effect](https://en.wikipedia.org/wiki/Thundering_herd_problem)**.

x-tagGroups:
  - name: REST API
    tags:
      - Agents
      - Public Answer
      - Answer Management
      - Audiences
      - Business Hours
      - Communications
      - Conversations
      - Customers
      - Endpoints
      - Events
      - Export
      - Freeform Topics
      - Inboxes
      - Organization
      - Proactive Conversations
      - Reports
      - Tasks
      - Teams
      - User Identity
      - Topics
      - Webhooks
  - name: Webhooks
    tags:
      - Summary
      - Payloads
  - name: Lookup API
    tags:
      - Customer Lookup
  - name: Resources
    tags:
      - Versioning
      - Error Handling
      - Rate Limit
      - Rich Content
      - Launching Soon
paths:
  # Communications API
  /api/v1/communications/sms:
    $ref: "communications/openapi.yaml#/paths/~1api~1v1~1communications~1sms"
  /api/v1/communications/email:
    $ref: "communications/openapi.yaml#/paths/~1api~1v1~1communications~1email"
  # Conversations API
  /api/v1/customers/{customerId}/conversations:
    $ref: "conversations/openapi.yaml#/paths/~1api~1v1~1customers~1{customerId}~1conversations"
  /api/v1/conversations/{conversationId}:
    $ref: "conversations/openapi.yaml#/paths/~1api~1v1~1conversations~1{conversationId}"
  /api/v1/conversation-items:
    $ref: "conversations/openapi.yaml#/paths/~1api~1v1~1conversation-items"
  /api/v1/conversation-items/{itemId}:
    $ref: "conversations/openapi.yaml#/paths/~1api~1v1~1conversation-items~1{itemId}"
  /api/v1/conversation-items/{itemId}/media/recording:
    $ref: "conversations/openapi.yaml#/paths/~1api~1v1~1conversation-items~1{itemId}~1media~1recording"
  /api/v1/conversation-items/{itemId}/voice-transcript:
    $ref: "conversations/openapi.yaml#/paths/~1api~1v1~1conversation-items~1{itemId}~1voice-transcript"
  /api/v1/conversation-items/{itemId}/attachments/{attachmentId}:
    $ref: "conversations/openapi.yaml#/paths/~1api~1v1~1conversation-items~1{itemId}~1attachments~1{attachmentId}"
  /api/v1/customers/{customerId}/conversation-items:
    $ref: "conversations/openapi.yaml#/paths/~1api~1v1~1customers~1{customerId}~1conversation-items"
  /api/v1/customers/{customerId}/conversation-items/{itemId}:
    $ref: "conversations/openapi.yaml#/paths/~1api~1v1~1customers~1{customerId}~1conversation-items~1{itemId}"
  /api/v1/conversations/{conversationId}/items:
    $ref: "conversations/openapi.yaml#/paths/~1api~1v1~1conversations~1{conversationId}~1items"
  /api/v1/conversations/{conversationId}/topics:
    $ref: "conversations/openapi.yaml#/paths/~1api~1v1~1conversations~1{conversationId}~1topics"
  /api/v1/conversations/{conversationId}/topics/{topicId}:
    $ref: "conversations/openapi.yaml#/paths/~1api~1v1~1conversations~1{conversationId}~1topics~1{topicId}"
  /api/v1/customer-history/{customerId}/conversations/{conversationId}/custom-attributes:
    $ref: "conversations/openapi.yaml#/paths/~1api~1v1~1customer-history~1{customerId}~1conversations~1{conversationId}~1custom-attributes"
  /api/v1/conversations/{conversationId}/notes:
    $ref: "conversations/openapi.yaml#/paths/~1api~1v1~1conversations~1{conversationId}~1notes"
  /api/v1/conversations/{conversationId}/notes/{noteId}:
    $ref: "conversations/openapi.yaml#/paths/~1api~1v1~1conversations~1{conversationId}~1notes~1{noteId}"
  /api/v1/conversation-items/{itemId}/reply:
    $ref: "conversations/openapi.yaml#/paths/~1api~1v1~1conversation-items~1{itemId}~1reply"
  /api/v1/conversation-items/{itemId}/redact:
    $ref: "conversations/openapi.yaml#/paths/~1api~1v1~1conversation-items~1{itemId}~1redact"

  # TASKS API
  /api/v1/tasks:
    $ref: "tasks/openapi.yaml#/paths/~1api~1v1~1tasks"
  /api/v1/customers/{customerId}/tasks:
    $ref: "tasks/openapi.yaml#/paths/~1api~1v1~1customers~1{customerId}~1tasks"
  /api/v1/tasks/{taskId}:
    $ref: "tasks/openapi.yaml#/paths/~1api~1v1~1tasks~1{taskId}"
  /api/v1/tasks/{taskId}/topic-associations:
    $ref: "tasks/openapi.yaml#/paths/~1api~1v1~1tasks~1{taskId}~1topic-associations"
  /api/v1/tasks/{taskId}/custom-attributes:
    $ref: "tasks/openapi.yaml#/paths/~1api~1v1~1tasks~1{taskId}~1custom-attributes"
  /api/v1/tasks/{taskId}/comments:
    $ref: "tasks/openapi.yaml#/paths/~1api~1v1~1tasks~1{taskId}~1comments"
  /api/v1/tasks/{taskId}/comments/{commentId}:
    $ref: "tasks/openapi.yaml#/paths/~1api~1v1~1tasks~1{taskId}~1comments~1{commentId}"

  # Custom Attributes API
  /api/v1/custom-attributes/:customAttributeId:
    $ref: "customAttributes/openapi.yaml#/paths/~1api~1v1~1custom-attributes~1{customAttributeId}"

  #Customers API
  /api/v1/customer-profiles:
    $ref: "customers/openapi.yaml#/paths/~1api~1v1~1customer-profiles"
  /api/v1/customer-profiles/{customerId}:
    $ref: "customers/openapi.yaml#/paths/~1api~1v1~1customer-profiles~1{customerId}"

  #User Identity API
  /api/v1/user-identity-jwt:
    $ref: "useridentity/openapi.yaml#/paths/~1api~1v1~1user-identity-jwt"

  #Answers API
  /api/v1/orgs/{orgId}/answers-search?q=search+terms:
    $ref: "answers/openapi.yaml#/paths/~1api~1v1~1orgs~1{orgId}~1answers-search?q=search+terms"
  /api/v1/orgs/{orgId}/answers?lng={lng}&audienceId={audienceId}:
    $ref: "answers/openapi.yaml#/paths/~1api~1v1~1orgs~1{orgId}~1answers?lng=lng&audienceId=audienceId"
  /api/v1/orgs/{orgId}/help-center/{helpCenterId}/answer-titles?lng={lng}&audienceId={audienceId}:
    $ref: "answers/openapi.yaml#/paths/~1api~1v1~1orgs~1{orgId}~1help-center~1{helpCenterId}~1answer-titles?lng=lng&audienceId=audienceId"
  /api/v1/orgs/{orgId}/answers/{answerId}:
    $ref: "answers/openapi.yaml#/paths/~1api~1v1~1orgs~1{orgId}~1answers~1{answerId}"
  /api/v1/answers:
    $ref: "answers/openapi.yaml#/paths/~1api~1v1~1answers"
  /api/v1/answers/{answerId}:
    $ref: "answers/openapi.yaml#/paths/~1api~1v1~1answers~1{answerId}"
  /api/v1/answers/{answerId}/languages/{language}/type/{type}:
    $ref: "answers/openapi.yaml#/paths/~1api~1v1~1answers~1{answerId}~1languages~1{language}~1type~1{type}"

  # Organization API
  /api/v1/agents:
    $ref: "organization/openapi.yaml#/paths/~1api~1v1~1agents"
  /api/v1/agents/{agentId}:
    $ref: "organization/openapi.yaml#/paths/~1api~1v1~1agents~1{agentId}"
  /api/v1/agents/{agentId}/call-recorder:
    $ref: "organization/openapi.yaml#/paths/~1api~1v1~1agents~1{agentId}~1call-recorder"

  # Audiences API
  /api/v1/audiences:
    $ref: "organization/openapi.yaml#/paths/~1api~1v1~1audiences"

  # Business Hours API
  /api/v1/business-hours:
    $ref: "businesshours/openapi.yaml#/paths/~1api~1v1~1business-hours"
  /api/v1/business-hours/{businessHoursId}:
    $ref: "businesshours/openapi.yaml#/paths/~1api~1v1~1business-hours~1{businessHoursId}"

  /api/v1/organization:
    $ref: "organization/openapi.yaml#/paths/~1api~1v1~1organization"

  /api/v1/inboxes:
    $ref: "organization/openapi.yaml#/paths/~1api~1v1~1inboxes"
  /api/v1/inboxes/{inboxId}:
    $ref: "organization/openapi.yaml#/paths/~1api~1v1~1inboxes~1{inboxId}"
  /api/v1/inboxes/{inboxId}/agents:
    $ref: "organization/openapi.yaml#/paths/~1api~1v1~1inboxes~1{inboxId}~1agents"

  /api/v1/teams:
    $ref: "organization/openapi.yaml#/paths/~1api~1v1~1teams"
  /api/v1/teams/{teamId}:
    $ref: "organization/openapi.yaml#/paths/~1api~1v1~1teams~1{teamId}"

  #Topics API
  /api/v1/topics:
    $ref: "topics/openapi.yaml#/paths/~1api~1v1~1topics"
  /api/v1/topics/{topicId}:
    $ref: "topics/openapi.yaml#/paths/~1api~1v1~1topics~1{topicId}"

  # Export API
  /api/v1/export/schedules:
    $ref: "export/openapi.yaml#/paths/~1api~1v1~1export~1schedules"
  /api/v1/export/jobs:
    $ref: "export/openapi.yaml#/paths/~1api~1v1~1export~1jobs"
  /api/v1/export/jobs/{jobId}:
    $ref: "export/openapi.yaml#/paths/~1api~1v1~1export~1jobs~1{jobId}"
  /api/v1/export/jobs/{jobId}/files/{filename}:
    $ref: "export/openapi.yaml#/paths/~1api~1v1~1export~1jobs~1{jobId}~1files~1{filename}"

  # Proactive Conversations API
  /api/v1/campaigns/{campaignId}/recipient-collections:
    $ref: "proactiveconversations/openapi.yaml#/paths/~1api~1v1~1campaigns~1{campaignId}~1recipient-collections"

  # Reports API
  /api/v1/reports:
    $ref: "reports/openapi.yaml#/paths/~1api~1v1~1reports"

  # Webhook API
  /api/v1/webhooks:
    $ref: "webhook/openapi.yaml#/paths/~1api~1v1~1webhooks"
  /api/v1/webhooks/{webhookId}:
    $ref: "webhook/openapi.yaml#/paths/~1api~1v1~1webhooks~1{webhookId}"

  /gladly/webhook:
    servers:
      - url: https://gateway.organization.com
        description: Web service hosted on your servers should be reachable from the Gladly cluster
    "$ref": "webhook/openapi.yaml#/paths/~1gladly~1webhook"

  # Work Session Report API
  /api/v1/reports/work-session-events:
    $ref: "worksessionevents/openapi.yaml#/paths/~1api~1v1~1reports~1work-session-events"

  # Events
  /api/v1/events:
    $ref: "events/openapi.yaml#/paths/~1api~1v1~1events"

  # Endpoints API
  /api/v1/endpoints:
    $ref: "endpoints/openapi.yaml#/paths/~1api~1v1~1endpoints"
  /api/v1/endpoints/{endpointId}:
    $ref: "endpoints/openapi.yaml#/paths/~1api~1v1~1endpoints~1{endpointId}"

components:
  examples:
    CustomerMovedErr:
      summary: "Error acting on a customer id that was merged into another customer"
      value:
        errors:
          - attr: "customerId"
            code: "moved"
            detail: "customer id has changed"
            meta:
              old: "wjotRA-fSU6feGCxdFwwNQ"
              new: "TX6f82W4S_ayp11kP4dhrQ"

  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic
      description: |
        Gladly API uses token-based **Basic Authentication**. API tokens are associated with designated Gladly users.
        To create and use an API token, your user must have the API User permission. An API token can be used to perform any API request without restriction.

        | user name   | password  |
        | ----------- | --------- |
        | agent email | API token |

        The credentials must be passed via an `Authorization` HTTP header. All requests must be made over HTTPS.

        ```shell
        curl -u user@organization.com:$GLADLY_API_TOKEN \
        https://organization.gladly.com/api/v1/organization
        ```
  schemas:
    Error:
      type: object
      properties:
        attr:
          type: string
          description: "Identifies the field causing the error"
        code:
          type: string
          description: "Code indicating the error type"
        detail:
          type: string
          description: "More details describing what went wrong"

    Errors:
      type: object
      properties:
        errors:
          type: array
          items:
            "$ref": "#/components/schemas/Error"
          example:
            [{ attr: content, code: blank, detail: content cannot be blank }]

    ErrorWithMeta:
      allOf:
        - "$ref": "#/components/schemas/Error"
        - type: object
          properties:
            meta:
              type: object
              additionalProperties: true
              description: "Additional information about the error"

    ErrorsWithMeta:
      type: object
      properties:
        errors:
          type: array
          items:
            "$ref": "#/components/schemas/ErrorWithMeta"
          example:
            [
              {
                attr: name,
                code: taken,
                detail: another entity with this name already exists,
                meta: { id: conflicting-id },
              },
            ]

    NotFoundErrors:
      type: object
      properties:
        errors:
          type: array
          items:
            "$ref": "#/components/schemas/Error"
          example: [{ code: not_exist, detail: entity does not exist }]
