openapi: 3.0.1 info: title: Gladly Agents Answer Management 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. # Authentication ' servers: - url: https://{organization}.gladly.com/api/v1 description: Production variables: organization: default: organization description: Your Gladly organization subdomain - url: https://{organization}.gladly.qa/api/v1 description: Sandbox variables: organization: default: organization description: Your Gladly QA organization subdomain security: - basicAuth: [] tags: - 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. \nOne call to create an Answer and subsequent call(s) to add content(s)\n" paths: /api/v1/answers: post: tags: - Answer Management summary: Add Answer description: 'Adds an answer to the list of answers. ' operationId: addAnswer requestBody: content: application/json: schema: properties: id: type: string description: unique answer id - optional (a new id will be generated if not provided) example: 1grfSzATQLa334VDLCWc4A name: type: string description: Customer facing answer name example: How to reset your password description: type: string description: Answer description gives more information about the answer to the Agent and appears in Answers Search when an Agent searches for an email or messaging answer. Only available for email and messaging content types example: This is my first answer audienceIds: type: array items: type: string description: List of Audience IDs to be associated with the answer example: - audience-1 - audience-2 examples: Sample Answer: summary: Example of an Answer value: name: How to reset your password description: This is my first answer audienceIds: - audience-1 - audience-2 responses: '200': description: Added answer content: application/json: schema: properties: id: type: string description: answer id example: 1grfSzATQLa334VDLCWc4A name: type: string description: Customer facing answer name example: How to reset your password description: type: string description: Answer description (visible in the UI for only certain content types) example: This is my first answer audienceIds: type: array items: type: string description: List of Audience IDs associated with the answer example: - audience-1 - audience-2 createdAt: type: string format: RFC3339 description: Time the answer was added example: '2024-06-13T15:16:29.894Z' '400': description: Bad Request content: application/json: schema: $ref: '#/components/schemas/Error' examples: id contains unsupported characters: value: errors: - attr: id code: invalid detail: id contains unsupported characters name cannot be blank or missing: value: errors: - attr: name code: blank detail: name cannot be blank name too long: value: errors: - attr: name code: too_long detail: name cannot be longer than 500 characters description too long: value: errors: - attr: description code: too_long detail: description cannot be longer than 10000 characters '409': description: Specified id is in use content: application/json: schema: $ref: '#/components/schemas/Error' examples: answer id already taken: value: errors: - attr: id code: taken detail: answer id already taken name already taken: value: errors: - attr: name code: taken detail: duplicate answer name /api/v1/answers/{answerId}: get: tags: - Answer Management summary: Get Answer description: 'Returns the answer requested. ' operationId: getAnswerById parameters: - name: answerId in: path description: id of the answer required: true schema: type: string example: 1grfSzATQLa334VDLCWc4A responses: '200': description: answer content: application/json: schema: properties: id: type: string description: answer id example: 1grfSzATQLa334VDLCWc4A name: type: string description: Customer facing answer name example: How to reset your password description: type: string description: Answer description (visible in the UI for only certain content types) example: This is my first answer audienceIds: type: array items: type: string description: List of Audience IDs associated with the answer example: - audience-1 - audience-2 updatedAt: type: string format: RFC3339 description: Time the answer was last modified example: '2024-06-13T15:16:29.894Z' createdAt: type: string format: RFC3339 description: Time the answer was added example: '2024-06-13T15:16:29.894Z' '404': description: Answer does not exist content: application/json: schema: $ref: '#/components/schemas/Errors' example: errors: code: not_exist detail: answer does not exist patch: tags: - Answer Management summary: Update Answer description: 'Updates the answer with the provided id. ' operationId: updateAnswer parameters: - name: answerId in: path description: id of the answer required: true schema: type: string example: 1grfSzATQLa334VDLCWc4A requestBody: content: application/json: schema: properties: name: type: string description: Customer facing answer name example: How to reset your password description: type: string description: Answer description gives more information about the answer to the Agent and appears in Answers Search when an Agent searches for an email or messaging answer. Only available for email and messaging content types example: This is my first answer audienceIds: type: array items: type: string description: List of Audience IDs to be associated with the answer. Updating this will replace the existing set of audience IDs. The Audience API can be used to retrieve the audience IDs created for the org. example: - audience-1 - audience-2 examples: Sample Answer: $ref: '#/paths/~1api~1v1~1answers/post/requestBody/content/application~1json/examples/Sample%20Answer' responses: '204': description: Answer updated '400': description: Bad Request content: application/json: schema: $ref: '#/components/schemas/Errors' examples: name already taken: value: errors: - attr: name code: taken detail: duplicate answer name name too long: value: errors: - attr: name code: too_long detail: name cannot be longer than 500 characters description too long: value: errors: - attr: description code: too_long detail: description cannot be longer than 10000 characters '404': description: Answer does not exist content: application/json: schema: $ref: '#/components/schemas/Errors' example: errors: code: not_exist detail: answer does not exist delete: tags: - Answer Management summary: Delete Answer description: 'Deletes the answer with the provided id. ' operationId: deleteAnswer parameters: - name: answerId in: path description: id of the answer required: true schema: type: string example: 1grfSzATQLa334VDLCWc4A responses: '204': description: Answer deleted '400': description: Bad Request content: application/json: schema: $ref: '#/components/schemas/ErrorsWithMeta' examples: answer associated with rules: value: errors: - attr: answer code: in_use detail: answer is associated with rules answer associated with help center: value: errors: - code: in_use detail: Public response used in Help Center 'help center name' Section 'section name' meta: helpCenterID: helpCenterId sectionID: sectionId snippetID: answerId answer associated with thread: value: errors: - attr: answer code: in_use detail: answer is associated with thread '404': description: Answer does not exist content: application/json: schema: $ref: '#/components/schemas/Errors' example: errors: code: not_exist detail: answer does not exist /api/v1/answers/{answerId}/languages/{language}/type/{type}: get: tags: - Answer Management summary: Get Answer Content description: 'Returns the answer content requested by language and type. ' operationId: getAnswerContentByLanguageAndType parameters: - name: answerId in: path description: id of the answer required: true schema: type: string example: 1grfSzATQLa334VDLCWc4A - name: language in: path description: Language code according to ISO 639 format. The specified language must also be configured for the org. required: true schema: type: string example: en-us - name: type in: path description: Type of answer. Must be one of `public`, `email`, `messaging`, or `reference`. required: true schema: type: string example: public responses: '200': description: answerContent content: application/json: schema: properties: answerId: type: string description: answer id example: 1grfSzATQLa334VDLCWc4A language: type: string description: Language of the answer content example: en-us type: type: string description: Answer content type example: public bodyHtml: type: string description: The body of the answer content example:
Public content
title: type: string description: Title of the answer content. Present for `public` type. example: Reset Password subject: type: string description: Subject line of the answer content. Present for `email` type. example: 'Re: Your inquiry' internal: type: boolean description: Whether the content is internal-only. Present for `reference` type. example: false '400': description: Bad Request content: application/json: schema: $ref: '#/components/schemas/Error' examples: invalid language: value: errors: - attr: language code: invalid detail: invalid language language not configured: value: errors: - attr: language code: invalid detail: language not configured for org invalid type: value: errors: - attr: type code: invalid detail: invalid type '404': description: Answer content does not exist content: application/json: schema: $ref: '#/components/schemas/Errors' examples: answer content does not exist: value: errors: code: not_exist detail: answer content does not exist answer does not exist: value: errors: code: not_exist detail: answer does not exist put: tags: - Answer Management summary: Add or Update Answer Content description: 'Adds or Updates the answer content for the specified answer by language and type. ' operationId: addAnswerContentByLanguageAndType parameters: - name: answerId in: path description: id of the answer required: true schema: type: string example: 1grfSzATQLa334VDLCWc4A - name: language in: path description: Language code according to ISO 639 format. The specified language must also be configured for the org. required: true schema: type: string example: en-us - name: type in: path description: Type of answer. Must be one of `public`, `email`, `messaging`, or `reference`. required: true schema: type: string enum: - public - email - messaging - reference example: public requestBody: description: 'The request body fields depend on the content type: - **public**: `bodyHtml` (required), `title` (required) - **email**: `bodyHtml` (required), `subject` (required) - **messaging**: `bodyHtml` (required) - **reference**: `bodyHtml` (required), `internal` (optional, defaults to false) ' content: application/json: schema: properties: bodyHtml: type: string description: The body of the answer content. Required for all content types. example:
Public content
title: type: string description: Title of the answer content. Required for `public` type. example: Reset Password subject: type: string description: Subject line of the answer content. Required for `email` type. example: 'Re: Your inquiry' internal: type: boolean description: Whether the content is internal-only. Applicable to `reference` type. example: false examples: Public Content: summary: Example of public answer content value: bodyHtml:
Navigate to Settings and click Reset Password.
title: How to reset your password Email Content: summary: Example of email answer content value: bodyHtml:
Thank you for reaching out.
subject: 'Re: Your inquiry' Messaging Content: summary: Example of messaging answer content value: bodyHtml:
Thanks for messaging us!
Reference Content: summary: Example of reference answer content value: bodyHtml:
Internal reference notes for agents.
internal: false responses: '200': description: Added/Updated answer content content: application/json: schema: $ref: '#/paths/~1api~1v1~1answers~1%7BanswerId%7D~1languages~1%7Blanguage%7D~1type~1%7Btype%7D/get/responses/200/content/application~1json/schema' '400': description: Bad Request content: application/json: schema: $ref: '#/components/schemas/Errors' examples: invalid language: value: errors: - attr: language code: invalid detail: invalid language language not configured: value: errors: - attr: language code: invalid detail: language not configured for org invalid type: value: errors: - attr: type code: invalid detail: invalid type '404': description: Answer does not exist content: application/json: schema: $ref: '#/components/schemas/Errors' example: errors: code: not_exist detail: answer does not exist delete: tags: - Answer Management summary: Delete Answer Content description: 'Deletes the answer content for the specified answer by language and type. ' operationId: deleteAnswerContentByLanguageAndType parameters: - name: answerId in: path description: id of the answer required: true schema: type: string example: 1grfSzATQLa334VDLCWc4A - name: language in: path description: Language code according to ISO 639 format. The specified language must also be configured for the org. required: true schema: type: string example: en-us - name: type in: path description: Type of answer. Must be one of `public`, `email`, `messaging`, or `reference`. required: true schema: type: string example: public responses: '204': description: Answer content deleted '400': description: Bad Request content: application/json: schema: oneOf: - $ref: '#/components/schemas/Error' - $ref: '#/components/schemas/ErrorsWithMeta' examples: invalid language: value: errors: - attr: language code: invalid detail: invalid language language not configured: value: errors: - attr: language code: invalid detail: language not configured for org invalid type: value: errors: - attr: type code: invalid detail: invalid type type not implemented: value: errors: - attr: type code: invalid detail: not implemented answer associated with rules: value: errors: - attr: answer code: in_use detail: answer is associated with rules answer associated with help center: value: errors: - code: in_use detail: Public response used in Help Center 'help center name' Section 'section name' meta: helpCenterID: helpCenterId sectionID: sectionId snippetID: answerId answer associated with thread: value: errors: - attr: answer code: in_use detail: answer is associated with thread '404': description: Does not exist content: application/json: schema: $ref: '#/components/schemas/Errors' examples: answer content does not exist: value: errors: code: not_exist detail: answer content does not exist answer does not exist: value: errors: code: not_exist detail: answer does not exist components: schemas: Errors: type: object properties: errors: type: array items: $ref: '#/components/schemas/Error' example: - attr: content code: blank detail: content cannot be blank 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 ErrorWithMeta: allOf: - $ref: '#/components/schemas/Error' - type: object properties: meta: type: object additionalProperties: true description: Additional information about the error 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 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 ``` ' basicAuth: type: http scheme: basic description: HTTP Basic auth — username is the API user email; password is the API token. Requires the "API User" permission. x-tagGroups: - name: REST API tags: - Agents - Public Answer - Answer Management - Audiences - Business Hours - Communications - Conversations - Customers - 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