# ThriveDesk developer documentation Merchant and product setup documentation: https://help.thrivedesk.com/llms.txt OpenAPI 3.1 specification: https://developer.thrivedesk.com/openapi/bundled.yaml # API reference (/api) The ThriveDesk Public API exposes **90 operations** across conversations, contacts, inboxes, tags, saved replies, reports, the Knowledge Base, attachments, messages, notes, business hours, holidays, and account utilities. Send every request to `https://api.thrivedesk.com/v1` with an `Authorization: Bearer YOUR_API_KEY` header. ## Explore the API [#explore-the-api] Use the navigation to browse operations grouped by resource. Each operation page includes: * path, method, parameters, and request-body fields; * response schemas and examples; * generated examples for cURL, JavaScript, Python, Go, Java, C#, and Rust; * an interactive request playground with bearer-token support. ## Machine-readable downloads [#machine-readable-downloads] * [Bundled OpenAPI 3.1 specification](/openapi/bundled.yaml) * [Postman collection](/api.postman_collection.json) * [LLM index](/llms.txt) # Content Security Policy (/assistant/csp) Use the exact script and network origins shown by the current installation snippet and your browser's CSP reports. The public Assistant contract does not publish a permanent origin allowlist, so a copied list can become stale as delivery infrastructure changes. ## Rollout procedure [#rollout-procedure] 1. Install the Assistant on a staging origin. 2. Enable `Content-Security-Policy-Report-Only`. 3. Load every enabled screen: home, Chat, Contact, Order Status, and Knowledge Base. 4. Add only the blocked ThriveDesk origins to `script-src`, `connect-src`, `img-src`, and `style-src`. 5. Repeat with an authenticated and anonymous browser before enforcing the policy. ```http Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self' https://ASSISTANT_SCRIPT_ORIGIN; connect-src 'self' https://ASSISTANT_API_ORIGIN wss://ASSISTANT_REALTIME_ORIGIN; img-src 'self' data: https://ASSISTANT_ASSET_ORIGIN; style-src 'self' 'unsafe-inline'; report-uri /csp-reports ``` Replace every placeholder from observed requests; do not deploy the example literally. Avoid `*`, and never add `unsafe-eval` just to silence an unrelated console error. ## Related [#related] * [Assistant troubleshooting](/assistant/troubleshooting) * [Assistant installation](/assistant/overview) # Pass custom customer data (/assistant/custom-data) The currently documented `identify` contract accepts `name` and `email`. ```js Assistant('identify', { name: 'Jane Cooper', email: 'jane@example.com' }); ``` Arbitrary attributes are not part of the published Assistant JavaScript contract. Do not assume an extra property will be stored or shown to agents. For richer customer context, expose an authenticated server endpoint and render its response through a [SmartApp](/smartapp/overview), or store supported contact/custom-field data through the [REST API](/api). ## Related [#related] * [Identify users safely](/assistant/identify) * [SmartApp callback contract](/smartapp/callback-contract) # Events and lifecycle (/assistant/events) Two lifecycle hooks are publicly documented: the `ready` command callback and the `tdAssistantConnected` DOM event. ## Ready callback [#ready-callback] Use `ready` for SDK commands that require the Assistant to be initialized. ```js Assistant('ready', () => { Assistant('identify', currentCustomer); Assistant('open'); }); ``` ## DOM connection event [#dom-connection-event] Use `tdAssistantConnected` when code needs the rendered `` element or its Shadow DOM. ```js document.addEventListener('tdAssistantConnected', (event) => { const assistantElement = event.target; console.log('Assistant element connected', assistantElement); }); ``` Register the listener before initialization so a fast load cannot race past it. Public documentation does not currently define `open`, `close`, or `message sent` event contracts. Do not depend on similarly named browser events unless ThriveDesk documents them here. ## Related [#related] * [Initialization](/assistant/initialization) * [Styling and CSS overrides](/assistant/styling) # Identify users safely (/assistant/identify) `Assistant('identify', user)` supplies a visitor name and email so Chat and Contact can skip or prefill those questions. ```js Assistant('ready', () => { Assistant('identify', { name: 'Jane Cooper', email: 'jane@example.com' }); }); ``` ## Security boundary [#security-boundary] No JWT- or HMAC-based Assistant identity contract is publicly documented. Values passed from browser JavaScript can be changed by the visitor. Do not use `identify` to authorize access to account data, invoices, orders, or private conversations. Use your own authenticated backend for sensitive data. When the Assistant or a SmartApp calls that backend, enforce the application session there and return only data the current user may access. Never embed API keys, signing secrets, or unrestricted bearer tokens in the browser. ## Related [#related] * [Custom customer data](/assistant/custom-data) * [SmartApp authentication](/smartapp/authentication) * [Assistant methods](/assistant/methods) # Initialization and ready callback (/assistant/initialization) Initialization connects the global `Assistant` queue to one configured Assistant. Calls that depend on rendered UI should run only after the ready callback fires. ## Standard initialization [#standard-initialization] ```js Assistant('init', 'YOUR_ASSISTANT_ID'); Assistant('ready', () => { Assistant('open'); }); ``` Use standard initialization when the configured launcher should appear. ## Triggerless initialization [#triggerless-initialization] ```js Assistant('trigger-less-init', 'YOUR_ASSISTANT_ID'); Assistant('ready', () => { document.querySelector('#support').addEventListener('click', () => { Assistant('open'); }); }); ``` `trigger-less-init` initializes without the normal launcher. The separate `triggerLess` command can also hide the launcher after standard initialization. ## Errors [#errors] * If `Assistant` is undefined, the installation snippet has not executed or was blocked. * If ready never fires, verify the Assistant ID, browser console, network requests, and CSP. * Do not initialize the same Assistant repeatedly during client-side route changes. ## Related [#related] * [Events and lifecycle](/assistant/events) * [Content Security Policy](/assistant/csp) * [Troubleshooting](/assistant/troubleshooting) # Assistant methods reference (/assistant/methods) Call Assistant methods after installation, and use the `ready` callback for anything that depends on the initialized widget. | Method | Purpose | Prerequisite | | --------------------------------------------- | --------------------------------------- | --------------------- | | `Assistant('init', assistantId)` | Load an Assistant with its launcher. | Valid Assistant ID | | `Assistant('trigger-less-init', assistantId)` | Load without the launcher. | Valid Assistant ID | | `Assistant('triggerLess')` | Hide or disable the launcher. | Initialized Assistant | | `Assistant('open')` | Open the Assistant. | Ready Assistant | | `Assistant('close')` | Close the Assistant. | Ready Assistant | | `Assistant('toggle')` | Toggle its open state. | Ready Assistant | | `Assistant('chat')` | Open Chat. | Chat enabled | | `Assistant('contact', options)` | Open Contact and optionally prefill it. | Contact enabled | | `Assistant('order-status')` | Open Order Status. | Order Status enabled | | `Assistant('identify', user)` | Prefill a visitor's name and email. | Ready Assistant | | `Assistant('article', article)` | Open a Knowledge Base article. | Article ID | | `Assistant.clearSession()` | Clear local chat/session state. | Initialized Assistant | | `Assistant('ready', callback)` | Run code after initialization. | Installation snippet | ## Open contact with defaults [#open-contact-with-defaults] ```js Assistant('ready', () => { Assistant('contact', { subject: 'Invoice INV-1042', body: 'I need help understanding this charge.' }); }); ``` ## Open an article [#open-an-article] ```js Assistant('article', 'ARTICLE_ID'); Assistant('article', { articleId: 'ARTICLE_ID', mode: 'sidebar' }); ``` Find the article ID by opening the article editor in ThriveDesk. ## Clear the session on logout [#clear-the-session-on-logout] ```js async function logout() { Assistant.clearSession(); await endApplicationSession(); } ``` Clearing the Assistant session removes local chat history and conversation context for that browser. ## Related [#related] * [Initialization](/assistant/initialization) * [Identify users](/assistant/identify) * [Original help-center article](https://help.thrivedesk.com/en/javascript-api) # Assistant SDK overview (/assistant/overview) The Assistant SDK is the browser integration surface for the ThriveDesk widget. Use it to initialize an Assistant, open a specific screen, prefill contact details, display Knowledge Base articles, and coordinate widget behavior with your application. ## Prerequisites [#prerequisites] * A configured Assistant in **Settings → Channel → Assistant**. * The Assistant ID and installation snippet from its **Installation** tab. * Permission to add JavaScript to your website or tag manager. ## Install the Assistant [#install-the-assistant] Copy the installation snippet shown by ThriveDesk and place it before your closing `` tag. The snippet is the source of truth for the current script URL and Assistant ID; do not copy those values from another workspace. After the snippet loads, register work that depends on the widget inside the ready callback: ```html ``` No separate Assistant sandbox is publicly documented. Test with a dedicated Assistant and inbox before adding the snippet to your production site. ## Related [#related] * [Initialization and ready callback](/assistant/initialization) * [Methods reference](/assistant/methods) * [Setup and customize the Assistant](https://help.thrivedesk.com/en/assistant-setup) # Styling and CSS overrides (/assistant/styling) The Assistant renders inside Shadow DOM, so styles from the host page do not cross into it. Add overrides only after `tdAssistantConnected` fires. ```js document.addEventListener('tdAssistantConnected', (event) => { const root = event.target.shadowRoot; if (!root) return; const styles = document.createElement('style'); styles.textContent = ` .td-launcher { right: 100px !important; bottom: 50px !important; } .td-assistant { right: 100px !important; bottom: 130px !important; } `; root.appendChild(styles); }); ``` ## Common selectors [#common-selectors] | Selector | Area | | -------------------- | --------------------- | | `.td-assistant` | Main Assistant window | | `.td-header` | Header | | `.td-body` | Main content | | `.td-footer` | Footer navigation | | `.td-card` | Home-screen cards | | `.td-launcher` | Launcher container | | `.td-launcher__icon` | Launcher icon | | `.td-launcher__text` | Launcher text | | `.td-livechat` | Live Chat | | `.td-contact` | Contact form | | `.td-order` | Order Status | | `.td-kb` | Knowledge Base | These class names are implementation hooks, not a versioned theme API. An Assistant release can rename or restructure them. Keep overrides small and test them after widget updates. ## Related [#related] * [Events and lifecycle](/assistant/events) * [Original styling article](https://help.thrivedesk.com/en/style-overriding) # Assistant troubleshooting (/assistant/troubleshooting) ## `Assistant` is not defined [#assistant-is-not-defined] Confirm the installation snippet runs before your integration code. Check for blocked scripts, consent-manager delays, ad blockers, and CSP violations. ## The launcher appears but methods do nothing [#the-launcher-appears-but-methods-do-nothing] Move the call inside `Assistant('ready', callback)`. Confirm the target feature—Chat, Contact, or Order Status—is enabled in the Assistant settings. ## Styles do not apply [#styles-do-not-apply] Listen for `tdAssistantConnected` and inject the style into `event.target.shadowRoot`. Host-page CSS cannot cross the Shadow DOM boundary. ## The wrong customer remains after logout [#the-wrong-customer-remains-after-logout] Call `Assistant.clearSession()` before ending the application session, then initialize or identify the next signed-in customer. ## Escalation checklist [#escalation-checklist] Capture the page URL, Assistant ID, timestamp and timezone, browser version, console errors, failed network request, CSP report, and a minimal reproduction. Send those details to [help@thrivedesk.com](mailto:help@thrivedesk.com). ## Related [#related] * [Initialization](/assistant/initialization) * [Content Security Policy](/assistant/csp) * [Support](/resources/support) # Authentication and scopes (/get-started/authentication) ## Bearer tokens [#bearer-tokens] Every endpoint requires a bearer access token in the `Authorization` header. ```http Authorization: Bearer eyJ0eXAiOiJKV1Qi... ``` ## How to get an API key [#how-to-get-an-api-key] In the ThriveDesk web app, open **Settings → Integrations → API Keys** and create a new key. Give it a name so you can identify it later. The plaintext key is shown once on creation and cannot be retrieved again. Copy it immediately and store it in your secrets manager. Keys are workspace-scoped and grant full access to the API surface documented here. They expire one year after creation; rotate them by revoking the old key from the same screen and issuing a new one. Integrations should never collect a user's ThriveDesk email and password to obtain a key on their behalf. If you are building an integration that needs to act across multiple workspaces, contact [help@thrivedesk.com](mailto:help@thrivedesk.com). ## Scopes [#scopes] Today every API key has full access to the documented surface. The create-key form also exposes a *Restricted Access* option, which is not yet enabled and is reserved for a future release. Per-operation scopes are not configurable yet. Open any operation in the [API reference](/api), enter the bearer token in its authorization field, complete the request parameters, and send the request directly to the production API. # Changelog (/get-started/changelog) The version is the value in the specification's `info.version`, so it moves when the documentation moves rather than when the product ships. A release marked **Docs only** changed no server behavior: existing calls keep working, but the schema you coded against may have been wrong, and the entry explains how. ## 1.3.0 — 2026-07-30 [#130--2026-07-30] **Latest** ### The remaining delete operations [#the-remaining-delete-operations] #### Added — Four deletes that were left out [#added--four-deletes-that-were-left-out] * `DELETE /v1/conversation/{conversation_id}/force-delete` permanently destroys a conversation already in the trash, along with its thread events, messages, attachments, and object-storage files. Calling it on a live conversation returns 404: soft-delete first. * `DELETE /v1/inboxes/{inbox_id}/automations/{automation_id}` removes an automation. Listing and viewing automations were already documented; creating and updating them still are not. * `DELETE /v1/inboxes/{inbox_id}/custom-views/{custom_view_id}` removes a custom view, and only its owner may do so. It answers with `{success, message}` rather than the usual `{message}`. Listing and creating views are not part of this surface, so the identifier must come from a first-party client. * `DELETE /v1/knowledgebases/{knowledgebase_id}/users/{email}` revokes one person's access to a help center. The ThriveDesk account is untouched. #### Changed — Deletes say what they destroy [#changed--deletes-say-what-they-destroy] * Each of the four carries a description covering what it removes and whether there is a way back. Conversation deletion is recoverable through `PATCH /v1/conversation/{conversation_id}/restore` only until the organization's trash lifetime expires, 30 days by default. ## 1.2.0 — 2026-07-30 [#120--2026-07-30] ### Business hours and holidays [#business-hours-and-holidays] #### Added — Business-hours profiles [#added--business-hours-profiles] * `GET /v1/business-hours` lists every profile in the organization, newest first and unpaginated; `GET /v1/business-hours/{business_hour}` shows one. * `POST /v1/business-hours` creates one and returns 201. A profile is either `calendar_24_7` or `business_hours` with a seven-entry weekly schedule, one entry per weekday, using 24-hour `HH:MM` times. An end earlier than the start is an overnight shift. * `PATCH /v1/business-hours/{business_hour}` updates one. Omitted keys keep their stored value, an explicit `null` is ignored, and sending `inbox_channels` replaces the whole set. `DELETE` returns 204 and releases the channels the profile covered. * A profile can cover the `email` and `livechat` channels of any inbox, and a channel belongs to at most one profile. A conflicting bind returns 422 carrying `conflicting_business_hour_id`, `inbox_id`, and `channel` instead of the usual `errors` object, and rolls the write back. #### Added — Holidays [#added--holidays] * `GET /v1/holidays` lists closures ordered active first, upcoming by start date, then past with the most recent first. `GET /v1/holidays/{holiday}` shows one. * `POST /v1/holidays` creates one with 201 from a `name` and inclusive `start_date` to `end_date` range; equal dates make a single-day holiday and ranges may overlap. `PATCH` accepts either date alone and validates against the stored value for the other, always reporting a range violation under `end_date`. `DELETE` returns 204. * Each holiday carries a read-only `status` of `upcoming`, `active`, or `past`, derived from today's date in the organization's timezone. #### Added — Business-hours fields on the inbox [#added--business-hours-fields-on-the-inbox] * `off_hours_auto_reply_subject` and `off_hours_auto_reply_body` are now documented on the inbox, both in `GET /v1/inboxes` and on the inbox embedded in message and report responses. `business_hour_enabled` is documented on the inbox list. All three have been returned since business hours shipped. Writes on both resources are limited to administrators and the account owner; reads are open to any teammate. All ten operations take a personal access token only. ## 1.1.2 — 2026-07-14 [#112--2026-07-14] **Docs only** ### Pagination and schema description fixes [#pagination-and-schema-description-fixes] #### Fixed — Simple pagination on inbox tags [#fixed--simple-pagination-on-inbox-tags] * `GET /v1/inboxes/{inbox_id}/tags` was described as returning no `meta` block, with `next_page_url` and `prev_page_url` in `links`. It does return `meta`. The block omits `last_page` and `total`, because the endpoint does not count the full result set, and adds `current_page_url`. Walk pages with `links.next` until it is null rather than counting them. #### Changed — Schema descriptions [#changed--schema-descriptions] * `Error`, `PaginationMeta`, the bearer-token `bearerFormat`, and the two camelCase path parameters described themselves in terms of the API's internal framework. They now describe the contract. No field, type, or requirement changed, so the Postman collection and SDKs are byte-identical apart from these strings. ## 1.1.1 — 2026-07-14 [#111--2026-07-14] **Docs only** ### Response schemas verified against the live API [#response-schemas-verified-against-the-live-api] No endpoint, request body, scope, or authentication behavior changed. Every documented response body was replayed against the running API and corrected where it had drifted, so the schemas now describe what the API actually returns. #### Fixed — Fields the docs described but the API never returns [#fixed--fields-the-docs-described-but-the-api-never-returns] These were removed or renamed to the field the API really sends: * Conversations: `assignee_id` and `contact_id` are really `assignable_id` / `assignable_type`, and `snooze_until` is really `is_snoozed`. The fields `is_read` and `is_trashed` do not exist. * Thread events were documented as a flat message (`type`, `body`, `html_body`, `cc_emails`, ...). The API returns `event_type`, `event` (the message, null on system events), `actor`, and `extra`. * Inboxes: `channel`, `from_email`, `enabled`, `is_private`, and `created_at` are not returned. * Organization on `GET /v1/me`: `name` and `subdomain` are really `company` and `slug`. * Tags: `created_at` and `organization_id` are not returned. * Reports: an agent has `first_name` / `last_name` / `name`, not `email` / `avatar_url`. Day buckets are `year` / `month` / `day`, not a single `date`. * Listing knowledge-base articles documented a `{message}` stub. It returns a paginated `{data, links, meta}`. #### Added — Newly documented [#added--newly-documented] * Responses now document every field returned, including per-folder counts and agents/teams on an inbox; embedded `contact`, `last_message`, and `custom_field_values` on a conversation; the `author` on a saved reply; and downloadable attachments on a message. * `GET /v1/inboxes/{inbox_id}/tags` uses simple pagination: its `meta` has no `last_page` or `total`, and adds `current_page_url`. * Free-form objects—an inbox's satisfaction-ratings config, an organization's permission matrix, and a conversation's custom-field values—are documented as such instead of invented shapes. ## 1.1.0 — 2026-07-11 [#110--2026-07-11] **Server change** ### Trimmed public surface, teammate endpoints, and tag validation [#trimmed-public-surface-teammate-endpoints-and-tag-validation] #### Removed — Dropped from the documented surface [#removed--dropped-from-the-documented-surface] Twenty-six operations that existed for the ThriveDesk web app rather than integrations are no longer documented. The routes still exist and first-party clients are unaffected, but they are not supported for integrations and may change without notice: * Session authentication: `POST /v1/auth/login` and `POST /v1/auth/logout`. Use a personal access token; integrations should never collect ThriveDesk passwords. * Composer mechanics: cancel reply (undo send) and the saved-reply use counter. * UI organization: custom-views CRUD, custom-field reorder, and saved-reply folder rename/delete. * Redundant bulk twins: `POST /v1/settings/tags/update` and `/delete`; use `PUT`/`DELETE /v1/settings/tags/{tag_id}`. * Irreversible deletion: conversation force-delete and batch force-delete. * Admin plane: automation create/update/delete, where list and view remain, plus Knowledge Base member/access management. * Dashboard-only reports: recent ratings, agent-team conversations, and agent-team productivity. #### Added — New endpoints [#added--new-endpoints] * `GET /v1/settings/users` lists teammates and pending invitations; `GET /v1/settings/users/{user_id}` shows one teammate. Both require `users:read`, which previously had no documented endpoint. * `POST /v1/conversation/{conversation_id}/draft` creates or updates the caller's reply draft and returns the `draft_id` consumed by reply and attachment upload. This closes the documented reply flow, which already referenced drafts without documenting how to create one. #### Changed — Tag validation is now enforced [#changed--tag-validation-is-now-enforced] * Tag create now enforces what the specification already documented: `name` is limited to 64 characters and `color` must be a six-digit hex value (`#RRGGBB`). Tag merge enforces the same plus a minimum of two source tags; bulk color update requires a hex `color`. Previously the server accepted any string. #### Fixed — Schema corrections [#fixed--schema-corrections] * `ReplyBody` no longer documents `new_conversation`; the server never read it. * The `User` schema now mirrors the API's user serializer: `avatar` rather than `avatar_url`, full name/contact fields, `presence`, preferences under `extra`, and real role values (`Account Owner`, `Administrator`, `User`). * Pagination link fields and avatar fields are typed as URIs instead of date-times, and pagination links are nullable at the edges. #### Changed — Tooling [#changed--tooling] * The Postman collection is now generated from the OpenAPI specification, with a folder per tag and schema-placeholder examples, instead of being maintained by hand. ## 1.0.1 — 2026-07-08 [#101--2026-07-08] **Docs only** ### Accuracy pass against the API implementation [#accuracy-pass-against-the-api-implementation] Every operation was re-verified against the API's route table, validators, and response serializers. Several documented shapes did not match the running API and were corrected to what the server actually accepts and returns. #### Fixed — Authentication [#fixed--authentication] * The public API uses a personal access token granted the first-party `public` scope, which can call every documented endpoint. * `POST /v1/auth/login` is documented as unauthenticated. * `POST /v1/search` requires a token; the authentication guide previously said otherwise. #### Fixed — Request bodies [#fixed--request-bodies] * Reply requires `status`. Message content comes from the authenticated user's draft, not the body. * Note uses `message` rather than `note`. Forward uses `body`, an array `to`, and required `message_id`. Snooze uses `snoozed_until` plus required `type`. Split requires `thread_event_id`, `direction`, `subject`, and `status`. * Tag attach/detach take `tag`. Conversation update takes `assign_to` / `tags`. Custom-field values are sent as a flat key-value map. * Batch update/delete take `conversations`; restore/force-delete take `conversation_ids`. The `hard` flag never existed. * Custom-field and custom-view bodies now mirror validators (`key`, `is_required`, structured `options`, a `filters` tree, and `display`). * Creating a conversation requires `to`, `status`, `subject`, and `message`. Contact create persists only `email`. Attachment upload takes an `attachments[]` multipart array. * Saved-reply folder rename/delete and `GET /v1/saved-replies` require `inbox_id`. Tag update requires `name`. #### Fixed — Responses and parameters [#fixed--responses-and-parameters] * Single resources are wrapped in `{"data": ...}`. List endpoints document their real collection shapes, whether paginated or plain arrays. * Status enums are `Active` / `Pending` / `Closed`, priority is `High` / `Medium` / `Low`, and custom field types are `text` / `textarea` / `dropdown` / `toggle` / `number`. * Date-range reports require `start_date` and `end_date`. Previously undocumented query parameters, including contact search, tag search, per-page overrides, `event_id`, `agent_id`, `rating`, and `view`, are now listed. * The global limit of 300 requests per minute per client IP is documented in [Pagination and rate limits](/get-started/pagination). ## 1.0.0 — 2026-07-07 [#100--2026-07-07] **Initial release** ### Initial public release [#initial-public-release] First publication of the ThriveDesk Public API as an OpenAPI 3.1 specification. It covered the 99 endpoints in the previous Postman collection, plus schema definitions, authentication scopes, the error catalog, pagination contract, and rate-limit documentation. #### Added — Documentation [#added--documentation] * Hand-authored OpenAPI 3.1 specification at `openapi/openapi.yaml` * Bundled single-file specification at `openapi/bundled.yaml` * Redoc reference renderer at `reference.html` * Stoplight Elements interactive playground at `playground.html` * Guides for quickstart, authentication and scopes, errors, pagination and rate limits, and changelog #### Fixed — Crosscheck against the Postman collection [#fixed--crosscheck-against-the-postman-collection] The Postman collection remains in this repository at `api.postman_collection.json`. Seven commits in its history record fixes applied during the crosscheck pass: 1. `Fix api.conversation.merge request body` — the example body was invented and would have returned 422\. 2. `Fix api.settings.tags.merge request body` — the same pattern. 3. `Fill empty request-body templates with real schemas` — 12 endpoints had placeholder bodies. 4. `Fix api.automations.store and api.automations.update` — the body used a nonexistent `conditions[]` field and the wrong active flag. 5. `Replace fabricated "string" placeholders in report responses` — all seven `/v1/reports/*` endpoints. 6. `Replace api.search response placeholder` — corrected shape. 7. `Replace api.me response placeholders` — corrected shape. The Postman collection and OpenAPI specification are intended to remain in lockstep. # Errors (/get-started/errors) Every error response is JSON. The shape depends on which framework layer generated it, but every error has at least a `message` field. ## The envelope [#the-envelope] ```json { "message": "The given data was invalid.", "errors": { "email": ["The email field is required."] } } ``` ## Status code catalog [#status-code-catalog] ### 400 Bad Request [#400-bad-request] The body is malformed JSON, or the request includes a field that the endpoint does not recognize. ### 401 Unauthorized [#401-unauthorized] The bearer token is missing, expired, or revoked. Refresh the token and retry. ```json {"message": "Unauthenticated."} ``` ### 403 Forbidden [#403-forbidden] The token is valid but does not include the scope required for this endpoint, or the authenticated user does not have access to the requested resource. ### 404 Not Found [#404-not-found] The resource does not exist, or it exists but belongs to a different organization. The API does not distinguish between the two. ### 405 Method Not Allowed [#405-method-not-allowed] The HTTP verb is not supported by this path. Check the API reference. ### 409 Conflict [#409-conflict] A handful of endpoints, such as batch conversation updates, return 409 when the request makes sense but the underlying state machine rejects it—for example, when a status is not reachable from the current state. ### 412 Precondition Failed [#412-precondition-failed] Returned by `POST /v1/inboxes/{inbox_id}/batch/update` when no update field is provided. ```json {"message": "Nothing to update"} ``` ### 422 Unprocessable Entity [#422-unprocessable-entity] The request body failed validation. The `errors` object is keyed by field name with an array of human-readable messages. ```json { "message": "The given data was invalid.", "errors": { "email": ["The email has already been taken."], "tags": ["The tags field is required."] } } ``` ### 429 Too Many Requests [#429-too-many-requests] The rate limit was exceeded. See [Pagination and rate limits](/get-started/pagination) for the rate-limit tiers and `Retry-After` semantics. ```json {"message": "Too Many Attempts."} ``` ### 500 Server Error [#500-server-error] An unexpected exception occurred. The API does not return a stack trace in production. The incident is logged server-side with a UUID; include the request ID when contacting support. ### 503 Service Unavailable [#503-service-unavailable] Returned by `POST /v1/auth/registration/register` when the signup pipeline is temporarily unavailable. ```json {"message": "Registration Failed."} ``` ## Error codes on auth endpoints [#error-codes-on-auth-endpoints] Several authentication endpoints return a machine-readable `error` code alongside the human-readable `message`: | Code | Where | Meaning | | ------------------------------ | ------------------------------------- | -------------------------------------------- | | `ERROR_EMAIL_INVALID` | `validate-email`, `register` | Address is malformed or in a blocked domain. | | `ERROR_EMAIL_TAKEN` | `validate-email`, `register` | A user already exists with this address. | | `ERROR_EMAIL_PENDING_APPROVAL` | `login`, `validate-email`, `register` | The account is awaiting approval. | | `ERROR_EMAIL_FLAGGED` | `register` | The address is on a block list. | | `ERROR_SLUG_TAKEN` | `validate-subdomain` | The subdomain is already in use. | # Idempotency and safe retries (/get-started/idempotency) ThriveDesk does **not currently honor an `Idempotency-Key` header**. A repeated POST can therefore perform the action twice. This is especially important for replies: an automatic retry can send the same message to a customer more than once. ## Prerequisites [#prerequisites] * A bearer token with access to the write operation. * A durable identifier for the action in your own system, such as a queued-job or outbound-message ID. ## Safe retry contract [#safe-retry-contract] Store one record per intended write before calling ThriveDesk. Treat your identifier as unique, record the request state, and allow only one worker to own it at a time. ```text pending → sending → succeeded ↘ unknown → reconcile before retrying ↘ failed → retry with backoff ``` If the connection fails after sending the request, the outcome is **unknown**. Do not immediately repeat a customer-visible write. First reconcile by reading the conversation and checking whether the expected reply or state change already exists. ```js const key = `reply:${conversationId}:${outboundMessageId}`; if (await dedupeStore.hasSucceeded(key)) return; await dedupeStore.claim(key); try { await sendReply(conversationId, message); await dedupeStore.succeed(key); } catch (error) { await dedupeStore.markUnknown(key, error); throw error; } ``` You may send `Idempotency-Key` for your own logging, but the current API does not enforce it. Your integration must provide deduplication until server-side idempotency is documented. ## Errors [#errors] * `422` means the request was rejected and can be corrected before retrying. * `429` should be retried only after `Retry-After`. * `5xx`, connection resets, and timeouts can leave the outcome unknown. ## Related [#related] * [Pagination and rate limits](/get-started/pagination) * [Errors](/get-started/errors) * [Create tickets from your app](/guides/create-tickets) # Get started (/get-started) ThriveDesk exposes four developer integration surfaces: the REST API, the browser-based Assistant SDK, signed webhooks, and SmartApp data panels. Start with the surface that matches where your code runs and what it needs to accomplish. ## API contract [#api-contract] * **Base URL:** `https://api.thrivedesk.com/v1` * **Authentication:** bearer access token * **Specification:** OpenAPI 3.1 * **Current version:** 1.3.0 * **Content type:** JSON, except binary attachment downloads Deletes are not uniform. Some are recoverable, while others permanently destroy related records and stored files. Each delete operation describes its recovery behavior in the API reference. ## Downloads [#downloads] * [Bundled OpenAPI specification](/openapi/bundled.yaml) * [Postman collection](/api.postman_collection.json) * [Generated SDK guide](/resources/sdks) * [AI and machine-readable documentation](/resources/ai) # Pagination and rate limits (/get-started/pagination) ## Pagination [#pagination] Most list endpoints return a counting paginator: items in `data`, page URLs in `links`, and counts in `meta`. ```json { "data": [], "links": { "first": "https://...", "last": "https://...", "prev": null, "next": "https://..." }, "meta": { "current_page": 1, "from": 1, "last_page": 10, "per_page": 20, "to": 20, "total": 200, "path": "https://..." } } ``` Two endpoints use a different shape: * `GET /v1/inboxes/{inbox_id}/tags` uses a simple paginator that does not count the full result set. Its `meta` omits `last_page` and `total`, and adds `current_page_url`. Follow `links.next` until it is null instead of counting pages. * `POST /v1/search` wraps the paginator in `{ success, data: { conversations: } }`. ### Query parameters [#query-parameters] | Parameter | Default | Notes | | ---------- | ------- | --------------------------------------------------- | | `page` | 1 | 1-indexed page number. | | `per-page` | 20 | Items per page. Maximum 100. | | `sort` | newest | Where supported: `newest`, `oldest`, or `priority`. | ## Rate limits [#rate-limits] Every API request first passes a global limiter, and a few sensitive routes add a stricter limiter. All limiters are keyed by client IP rather than access token, so a high-traffic single host can hit the limit even when using multiple valid tokens. | Limiter | Default | Applies to | | ------------------------ | ----------------------- | ------------------------- | | `api.global` | 300 requests / 1 minute | Every API endpoint | | `api.register` | 10 requests / 1 minute | `/v1/auth/registration/*` | | `api.email_verification` | 5 requests / 1 minute | `/v1/auth/verification/*` | ### How a throttled request looks [#how-a-throttled-request-looks] ```http HTTP/1.1 429 Too Many Requests Retry-After: 47 X-RateLimit-Limit: 5 X-RateLimit-Remaining: 0 Content-Type: application/json { "message": "Too Many Attempts." } ``` Back off using the `Retry-After` header, do not hammer the endpoint, and consider queueing requests client-side when you would otherwise approach the limit. ### Configuring limits [#configuring-limits] Each limiter reads its `max_attempts` and `decay_minutes` from environment variables, defaulting to the values above: ```dotenv API_RATE_LIMIT_GLOBAL=300,1 API_RATE_LIMIT_REGISTER=10,1 API_RATE_LIMIT_EMAIL_VERIFICATION=5,1 ``` ## Related [#related] * [Idempotency and safe retries](/get-started/idempotency) * [Errors](/get-started/errors) # Quickstart (/get-started/quickstart) This guide walks through a complete session with the ThriveDesk Public API: create an access token, fetch the current user, list your open conversations, then draft and send a reply. The examples use curl so they run from any shell. ## 1. Create an API key [#1-create-an-api-key] In the ThriveDesk app, open **Settings → Integrations → API Keys** and create a new key. Give it a name, copy the plaintext key when it is shown, and store it in a secrets manager. It will not be displayed again. ```bash export TOKEN="eyJ0eXAiOiJKV1Qi..." ``` Treat the key as a secret. Keys expire one year after creation; rotate them by revoking the old key from the same screen and issuing a new one. They are the only publicly documented authentication method at this time, so integrations must never collect ThriveDesk passwords on a user's behalf. ## 2. Confirm who you are [#2-confirm-who-you-are] Call `GET /v1/me` with the bearer token. The response includes the organization, current user, accessible inbox IDs, and unread badge count. ```bash curl https://api.thrivedesk.com/v1/me \ -H "Authorization: Bearer $TOKEN" ``` ## 3. List your open conversations [#3-list-your-open-conversations] `GET /v1/conversations/mine` returns up to five of the conversations most recently assigned to the current user, without pagination. For a full, paginated list use `GET /v1/inboxes/{inbox_id}`. See [Pagination and rate limits](/get-started/pagination). ```bash curl https://api.thrivedesk.com/v1/conversations/mine \ -H "Authorization: Bearer $TOKEN" ``` ## 4. Read a conversation's thread [#4-read-a-conversations-thread] `GET /v1/conversation/{conversation_id}` returns the conversation metadata plus its thread events. Events include incoming messages, outgoing replies, notes, drafts, scheduled replies, and system events. ## 5. Draft a reply [#5-draft-a-reply] `POST /v1/conversation/{conversation_id}/draft` creates or updates the authenticated user's reply draft. There is one draft per user per conversation; posting again overwrites it. ```bash curl -X POST "https://api.thrivedesk.com/v1/conversation/$CONV_ID/draft" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"message": "

Thanks for reaching out - fixed in v2.1.

"}' ``` ## 6. Send it [#6-send-it] `POST /v1/conversation/{conversation_id}/reply` dispatches your current draft. Without a draft, the request fails with 404. The body controls what happens to the conversation after sending; `status` is required. ```bash curl -X POST "https://api.thrivedesk.com/v1/conversation/$CONV_ID/reply" \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"status": "Closed"}' ``` ## What to read next [#what-to-read-next] * [Authentication and scopes](/get-started/authentication) — bearer tokens and how to obtain one * [Errors](/get-started/errors) — what every error response looks like * [Pagination and rate limits](/get-started/pagination) — including the global 300 requests/minute limit * [API reference](/api) — every operation with an interactive request playground # Versioning and deprecation (/get-started/versioning) The REST API uses the stable `/v1` base path. The OpenAPI document also carries a documentation release version—currently `1.3.0`—so integrators can identify changes to the published contract. ## Compatibility policy [#compatibility-policy] Within `/v1`, ThriveDesk aims to make additive changes without breaking existing integrations. Examples include new optional request fields, new response fields, new endpoints, and new enum values where consumers are expected to tolerate unknown values. A change is breaking when an existing valid request stops working or a documented response field is removed or changes type. Breaking REST changes require a new major URL version or an explicitly announced migration path. ## Deprecation process [#deprecation-process] When a supported operation or field is scheduled for removal: 1. The affected reference page and [changelog](/get-started/changelog) identify the replacement. 2. A removal date and migration window are published before enforcement. 3. The old contract remains available during that window unless an urgent security issue prevents it. No operation is currently marked deprecated in the public OpenAPI specification. ## Consumer guidance [#consumer-guidance] * Ignore response fields you do not recognize. * Handle unknown enum values defensively. * Pin generated clients to a known version and review the changelog before regenerating. * Validate against the [bundled OpenAPI specification](/openapi/bundled.yaml) in CI. ## Related [#related] * [Changelog](/get-started/changelog) * [SDKs](/resources/sdks) * [OpenAPI reference](/api) # Bulk import and backfill (/guides/bulk-import) The public API does not provide a general asynchronous import endpoint. Build imports as resumable jobs over the normal contact and conversation operations. ## Import loop [#import-loop] 1. Normalize and validate input before enqueueing it. 2. Assign every source row a stable external ID in your database. 3. Search or look up the corresponding ThriveDesk record. 4. Create or update only when necessary. 5. Persist the ThriveDesk ID and result before acknowledging the job. 6. Back off on `429` using `Retry-After`. Keep concurrency below the global 300-requests-per-minute IP limit and reduce it further when other production traffic shares the same egress IP. ```js for await (const row of importRows()) { if (await mappings.has(row.sourceId)) continue; const contact = await createContact(row); await mappings.put(row.sourceId, contact.id); } ``` ## Errors [#errors] Write validation failures to a dead-letter report with the source row, status code, and field errors. Do not retry `422` unchanged. Reconcile timeouts before repeating POST requests. ## Related [#related] * [Contacts reference](/api/contacts/contacts-index-post) * [Idempotency](/get-started/idempotency) * [Rate limits](/get-started/pagination) # Create tickets from your app (/guides/create-tickets) Create a conversation under the inbox that should own the ticket. Keep the bearer token on your server and deduplicate submissions before calling ThriveDesk. ## Request [#request] ```bash curl -X POST "https://api.thrivedesk.com/v1/inboxes/3f7c1e94-2b6a-4d0e-8c5f-9a1b2c3d4e5f/conversations" \ -H "Authorization: Bearer $THRIVEDESK_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "to": "jane@example.com", "status": "Active", "subject": "Order INV-1042 arrived damaged", "message": "The customer reported a cracked screen.", "contact": { "name": "Jane Cooper", "company": "Acme Inc" } }' ``` Validate the email and message in your application, escape untrusted HTML, and store your own submission ID before sending. ## Errors [#errors] * `401`/`403`: token or workspace access is invalid. * `404`: the inbox does not exist or is unavailable to the token. * `422`: inspect `errors` and correct the submitted fields. * Timeout or `5xx`: reconcile before retrying because the conversation may already exist. ## Related [#related] * [Idempotency and safe retries](/get-started/idempotency) * [Create-conversation reference](/api/inboxes/inbox-conversations-store-post) * [Errors](/get-started/errors) # Build a customer portal (/guides/customer-portal) A customer portal should call your backend, which authenticates the customer and then calls ThriveDesk. Never put a ThriveDesk bearer token in browser or mobile application code. ## Recommended architecture [#recommended-architecture] ```text Customer browser → Your authenticated backend → ThriveDesk API ↓ tenant authorization ``` Map the signed-in application's customer ID to a ThriveDesk contact ID. Before returning any conversation, verify it belongs to that contact. Return only fields the portal needs. ```bash curl "https://api.thrivedesk.com/v1/contacts/CONTACT_ID/conversations?limit=20" \ -H "Authorization: Bearer $THRIVEDESK_TOKEN" ``` Use the contact conversation endpoint for lists and fetch a conversation only after authorization. Proxy attachment downloads through the same authorization boundary. ## Errors [#errors] Translate upstream `401`/`403` into a generic portal error, return `404` rather than revealing another customer's record, and rate-limit both the customer session and your ThriveDesk client. ## Related [#related] * [Authentication](/get-started/authentication) * [Contacts reference](/api/contacts/contacts-conversations-get) * [Create tickets](/guides/create-tickets) # Search and filter conversations (/guides/search-filter) Use the narrowest operation for the question you are answering. | Need | Operation | | ---------------------------------------------------- | ------------------------------------------ | | Conversations in one inbox | `GET /inboxes/{inbox_id}` | | Structured inbox filters | `POST /inboxes/{inbox_id}` | | Conversations for one contact | `GET /contacts/{contact_id}/conversations` | | Five recent conversations assigned to the token user | `GET /conversations/mine` | | Workspace search by several fields | `POST /search` | ## Global search [#global-search] ```bash curl -X POST "https://api.thrivedesk.com/v1/search" \ -H "Authorization: Bearer $THRIVEDESK_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "q": { "subject": "refund", "status": "Active" }, "per-page": 20, "sort": "newest" }' ``` Search wraps its paginator inside `data.conversations`. Do not parse it as the standard top-level collection envelope. ## Related [#related] * [Search reference](/api/misc/search-post) * [Pagination](/get-started/pagination) * [Sync conversations](/guides/sync-conversations) # Sync conversations to your system (/guides/sync-conversations) Use webhooks for low-latency notifications and the REST API for authoritative state. A webhook-only sync can drift when a delivery is discarded; polling alone adds delay and load. ## Prerequisites [#prerequisites] * A server-side bearer token. * A signed webhook receiver. * Durable storage for conversation IDs and sync cursors. ## Initial sync [#initial-sync] List each inbox and walk its paginated conversations, following `links.next` until it is `null`. Store the stable conversation `id`, not only the human-facing `ticket_id`. ```bash curl "https://api.thrivedesk.com/v1/inboxes/INBOX_ID?per-page=100&page=1" \ -H "Authorization: Bearer $THRIVEDESK_TOKEN" ``` ## Incremental sync [#incremental-sync] Subscribe to conversation webhook events. Verify each signature, deduplicate it, enqueue it, then fetch the affected conversation by `data.id` before updating your database. ```bash curl "https://api.thrivedesk.com/v1/conversation/CONVERSATION_ID" \ -H "Authorization: Bearer $THRIVEDESK_TOKEN" ``` Run a periodic reconciliation pass to recover from delayed or discarded webhook deliveries. ## Errors [#errors] Honor `Retry-After` on `429`, quarantine schema failures for inspection, and treat a webhook fetch `404` as a possible deletion rather than immediately recreating the record. ## Related [#related] * [Webhook events](/webhooks/events) * [Webhook retries](/webhooks/retries) * [Pagination](/get-started/pagination) # AI and machine-readable documentation (/resources/ai) Use the smallest artifact that answers the task: | Artifact | Purpose | | -------------------------------------------------------------- | ------------------------------------------------- | | [`/llms.txt`](/llms.txt) | Compact page index with absolute URLs. | | [`/llms-full.txt`](/llms-full.txt) | Concatenated guide and API-reference text. | | [`/openapi/bundled.yaml`](/openapi/bundled.yaml) | Machine-readable REST contract. | | [`/api/search`](/api/search) | Static full-text search index used by the site. | | [Help-center `llms.txt`](https://help.thrivedesk.com/llms.txt) | Merchant and product-configuration documentation. | Use the help center for UI tasks such as installing an Assistant or configuring a webhook, then use this site for the executable contract. Stable headings and per-page Markdown routes allow agents to cite a specific section without ingesting the full corpus. ## Related [#related] * [Developer documentation home](/get-started) * [OpenAPI reference](/api) # Code samples (/resources/code-samples) All REST requests use `https://api.thrivedesk.com/v1` and a server-side bearer token. These examples fetch the current user so you can verify a token without changing data. ## cURL [#curl] ```bash curl "https://api.thrivedesk.com/v1/me" \ -H "Authorization: Bearer $THRIVEDESK_TOKEN" \ -H "Accept: application/json" ``` ## JavaScript [#javascript] ```js const response = await fetch('https://api.thrivedesk.com/v1/me', { headers: { Authorization: `Bearer ${process.env.THRIVEDESK_TOKEN}`, Accept: 'application/json' } }); if (!response.ok) throw new Error(`ThriveDesk returned ${response.status}`); console.log(await response.json()); ``` ## PHP [#php] ```php true, CURLOPT_HTTPHEADER => [ 'Authorization: Bearer ' . getenv('THRIVEDESK_TOKEN'), 'Accept: application/json', ], ]); $body = curl_exec($request); $status = curl_getinfo($request, CURLINFO_RESPONSE_CODE); if ($status < 200 || $status >= 300) throw new RuntimeException("ThriveDesk returned $status"); print_r(json_decode($body, true, flags: JSON_THROW_ON_ERROR)); ``` ## Python [#python] ```python import os import requests response = requests.get( "https://api.thrivedesk.com/v1/me", headers={ "Authorization": f"Bearer {os.environ['THRIVEDESK_TOKEN']}", "Accept": "application/json", }, timeout=30, ) response.raise_for_status() print(response.json()) ``` ## Related [#related] * [Quickstart](/get-started/quickstart) * [Generated SDKs](/resources/sdks) * [API reference](/api) # Postman and Insomnia (/resources/collections) The Postman collection and bundled OpenAPI document are generated from the same 90-operation source used by this reference. ## Postman [#postman] Import `/api.postman_collection.json`, create an environment variable named `TOKEN`, and set its current value to your API key. Keep the token out of exported or shared environments. ## Insomnia [#insomnia] Import `/openapi/bundled.yaml` as an OpenAPI document. Configure bearer authentication in a private environment and select `https://api.thrivedesk.com/v1` as the server. The collection is regenerated rather than hand-edited. If an operation appears wrong, fix the OpenAPI source and rebuild the collection. ## Related [#related] * [Authentication](/get-started/authentication) * [API reference](/api) # Sandbox and testing (/resources/sandbox) The public REST API and Assistant documentation do not currently define a sandbox, test-mode flag, or separate test base URL. Requests made with a normal token affect its real workspace. ## Safe test setup [#safe-test-setup] * Use a dedicated workspace or, when that is not available, a dedicated inbox and test contacts. * Prefix subjects and tags with an unmistakable marker such as `[integration-test]`. * Never use real customer email addresses in fixtures. * Avoid delete operations unless the test explicitly verifies recovery behavior. * Clean up through documented operations and preserve failed fixtures for investigation. * Mock ThriveDesk in unit tests and reserve live requests for a small integration suite. Requests sent from the API reference target `https://api.thrivedesk.com/v1`. Review write and delete operations carefully before pressing Send. ## Related [#related] * [API reference](/api) * [Idempotency](/get-started/idempotency) * [SmartApp testing](/smartapp/testing) # SDKs (/resources/sdks) Four first-party SDKs are generated from this OpenAPI specification and committed under `sdk/` at the root of this repository. Each is a thin HTTP wrapper; applications bring their own retry, caching, and concurrency primitives. ## TypeScript and JavaScript [#typescript-and-javascript] Fetch-based with no runtime dependencies. It works in Node.js 18+ and modern browsers. ```ts import { Configuration, ConversationsApi } from "./sdk/typescript-fetch"; const config = new Configuration({ basePath: "https://api.thrivedesk.com/v1", accessToken: process.env.THRIVEDESK_TOKEN, }); const conversations = new ConversationsApi(config); const mine = await conversations.conversationsMineGet({ perPage: 20 }); console.log(mine.data); ``` ## Python [#python] Uses `urllib3` and requires Python 3.9+. ```python import os import thrivedesk from thrivedesk.rest import ApiException configuration = thrivedesk.Configuration( host="https://api.thrivedesk.com/v1", access_token=os.environ["THRIVEDESK_TOKEN"], ) with thrivedesk.ApiClient(configuration) as api_client: api = thrivedesk.ConversationsApi(api_client) mine = api.conversations_mine_get(per_page=20) print(mine.data) ``` ## PHP [#php] Uses Guzzle 7, requires PHP 8.1+, and ships with a replaceable PSR-18 client. ```php setHost('https://api.thrivedesk.com/v1') ->setAccessToken(getenv('THRIVEDESK_TOKEN')); $api = new OpenAPI\Client\Api\ConversationsApi( new GuzzleHttp\Client(), $config ); $mine = $api->conversationsMineGet(20); print_r($mine->getData()); ``` ## Go [#go] Uses `net/http` directly and requires Go 1.20+. ```go package main import ( "context" "fmt" "os" openapiclient "github.com/thrivedesk/sdk-go" ) func main() { cfg := openapiclient.NewConfiguration() cfg.Host = "api.thrivedesk.com/v1" cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("THRIVEDESK_TOKEN")) client := openapiclient.NewAPIClient(cfg) mine, _, err := client.ConversationsAPI.ConversationsMineGet( context.Background(), ).PerPage(20).Execute() if err != nil { panic(err) } fmt.Println(mine.Data) } ``` ## Regenerating the SDKs [#regenerating-the-sdks] The SDKs are generated by [OpenAPI Generator](https://openapi-generator.tech) from `openapi/bundled.yaml`. Use the exact commands in the repository [README](https://github.com/thrivedesk/developer.thrivedesk.com#re-generate-the-sdks), including the load-bearing package-name and module-path options. Generated code is committed to the repository. SDKs are regenerated whenever the specification changes, and the [Changelog](/get-started/changelog) records each release. # Support and contact (/resources/support) Email [help@thrivedesk.com](mailto:help@thrivedesk.com) when the reference and troubleshooting pages do not resolve an integration problem. Include: * integration surface: REST API, Assistant, webhook, or SmartApp; * UTC timestamp and timezone; * request method and path, without credentials; * HTTP status and response body with personal data redacted; * request or conversation identifier; * browser and console details for Assistant issues; * webhook event type and callback status for webhook issues; * minimal steps that reproduce the problem. Never send API tokens, webhook secrets, customer message bodies, or unredacted personal data by email. Revoke and replace any credential that was accidentally shared. ## Related [#related] * [Errors](/get-started/errors) * [Assistant troubleshooting](/assistant/troubleshooting) * [Webhook debugging](/webhooks/debugging) * [SmartApp troubleshooting](/smartapp/troubleshooting) # SmartApp authentication (/smartapp/authentication) SmartApp configuration can attach static request headers. A common pattern is an authorization header checked by your callback. ```http Authorization: Bearer smartapp_SERVICE_TOKEN ``` Generate a dedicated high-entropy credential for each environment or SmartApp instance. Store only a hash where possible, grant the narrowest access required, rotate it periodically, and revoke it when the SmartApp is removed. ## Authorization [#authorization] Authentication proves the request has the configured credential; it does not decide which customer record may be returned. Validate every dynamic identifier and enforce tenant boundaries before querying data. The public SmartApp documentation does not describe request signing, timestamps, source IPs, or a ThriveDesk-issued identity token. Do not assume an undocumented header is trustworthy. ## Related [#related] * [Callback contract](/smartapp/callback-contract) * [Assistant user identification](/assistant/identify) # SmartApp callback contract (/smartapp/callback-contract) The callback is the endpoint ThriveDesk fetches to obtain agent-facing data. The configuration UI constructs the request from the endpoint, optional headers, and dynamic parameters selected with the `{` picker. ## Response contract [#response-contract] Return a `2xx` response containing JSON with stable property names and types. The builder discovers those properties during **Fetch endpoint and check connection** and maps them into text or repeaters. ```json { "id": "customer_123", "name": "Jane Cooper", "plan": "Pro", "orders": [ { "id": "INV-1042", "total": 49.00, "status": "paid" } ] } ``` Prefer a small purpose-built response over forwarding an internal API unchanged. Keep field types stable, return empty arrays instead of `null` for repeaters, and omit secrets or data the current agent should not see. The public SmartApp documentation does not define an HTTP method, timeout, maximum payload size, cache policy, or error-envelope schema. Validate those behaviors with the connection tester and keep the endpoint fast and side-effect free. ## Errors [#errors] Return conventional `401`/`403` for authorization failures, `404` when the dynamic customer record does not exist, `429` with `Retry-After` when throttled, and `5xx` only for retryable server errors. ## Related [#related] * [Authentication](/smartapp/authentication) * [Testing and simulation](/smartapp/testing) # SmartApp output components (/smartapp/output-components) The SmartApp builder maps a successful JSON test response into two output components. ## Text field [#text-field] A text field has an optional label, a value selector, and text styling. Use it for scalar values such as a customer name, plan, order number, or balance. ## Repeater [#repeater] A repeater selects an array and renders its children once per item. Repeaters can contain text fields and nested repeaters. Given: ```json { "orders": [ { "id": "INV-1042", "items": [ { "name": "Keyboard", "quantity": 1 }, { "name": "Mouse", "quantity": 1 } ] } ] } ``` Create a repeater for `orders`, add a text field for `id`, then create a nested repeater for `items` with text fields for `name` and `quantity`. For an array of strings, select **Print all text value** inside a repeater. Components can be dragged to reorder them, deleted individually, or cleared together; save after changing the builder. ## Related [#related] * [Callback contract](/smartapp/callback-contract) * [Testing and simulation](/smartapp/testing) # SmartApp overview and concepts (/smartapp/overview) A SmartApp calls an HTTP endpoint you control and renders selected fields from its JSON response in the ThriveDesk agent interface. Use it to show customer, order, subscription, or account context without making agents leave the conversation. ## Building blocks [#building-blocks] * **Endpoint:** the URL ThriveDesk fetches. * **Headers:** static headers added to the request, commonly authorization. * **Dynamic parameters:** conversation or customer values inserted into the URL. * **Mock values:** test replacements required while configuring dynamic parameters. * **Refetch interval:** optional refresh frequency. * **Builder:** text and repeater components mapped to response fields. Install the SmartApp for only the inboxes whose agents need the data. Multiple SmartApp instances can be installed when different systems or inboxes require different contracts. ## Related [#related] * [Callback contract](/smartapp/callback-contract) * [Output components](/smartapp/output-components) * [SmartApp setup in the help center](https://help.thrivedesk.com/en/smart-app-user-guide) # SmartApp testing and simulation (/smartapp/testing) The SmartApp connection tester fetches the configured endpoint and exposes the response to the builder. When the URL contains a dynamic parameter, provide a real mock value that returns the same shape production requests will use. ## Test matrix [#test-matrix] 1. A normal customer with all fields populated. 2. A new customer with empty arrays and optional fields. 3. A missing customer (`404`). 4. An expired credential (`401`). 5. A forbidden tenant/customer pair (`403`). 6. A slow or unavailable dependency (`5xx`). 7. The largest response agents realistically need. Use **View Response** to confirm the data shape before mapping fields. Test nested repeaters and the **Print all text value** option separately. Save, open a conversation in each selected inbox, and confirm the installed panel matches the preview. No standalone SmartApp emulator is publicly documented; use a dedicated test endpoint and a test inbox when production data must not be exposed. ## Related [#related] * [Output components](/smartapp/output-components) * [Troubleshooting](/smartapp/troubleshooting) # SmartApp troubleshooting (/smartapp/troubleshooting) ## Connection test fails [#connection-test-fails] Check the URL, mock dynamic values, configured headers, TLS certificate, status code, response time, and whether the endpoint returns JSON. ## A field is missing from the builder [#a-field-is-missing-from-the-builder] Return it in the test response with the same type used in production. The builder cannot select a property it did not discover. ## A repeater is empty or malformed [#a-repeater-is-empty-or-malformed] Confirm the selected property is an array. Use nested repeaters for nested arrays and return `[]` instead of `null` when no items exist. ## Authorization fails after working previously [#authorization-fails-after-working-previously] Check token expiry and rotation. Update the SmartApp header and connection test together; do not temporarily make the endpoint public. ## Data is stale [#data-is-stale] Review the configured refetch interval and any cache in your endpoint. Keep the callback read-only so an automatic refetch cannot repeat a side effect. ## Related [#related] * [Testing and simulation](/smartapp/testing) * [Support](/resources/support) # Webhook debugging (/webhooks/debugging) ## No delivery arrives [#no-delivery-arrives] Confirm the integration is installed for the correct inboxes and event types. Verify the callback is public HTTPS, follows no interactive authentication flow, and is not blocked by a firewall. ## Signature mismatch [#signature-mismatch] Log the event type, content length, encoding, and computed signature—not the secret. Confirm you sign only the JSON-encoded `data` value and that your parser has not reordered or re-escaped it. ## Deliveries fail intermittently [#deliveries-fail-intermittently] Return a `2xx` after durable enqueueing instead of waiting for downstream APIs. Monitor latency, queue depth, status codes, and receiver exceptions. ## Duplicate side effects [#duplicate-side-effects] Assume delivery can repeat. Store a deduplication key before sending email, charging money, or updating another system. ## Escalation checklist [#escalation-checklist] Provide the webhook name, event type, conversation ID, approximate timestamp and timezone, callback status code, response time, and redacted headers to [help@thrivedesk.com](mailto:help@thrivedesk.com). ## Related [#related] * [Verify signatures](/webhooks/signatures) * [Retries and failures](/webhooks/retries) # Webhook events and payloads (/webhooks/events) Every documented webhook uses a v1 envelope with `eventType` and a conversation-shaped `data` object. | Event | Trigger | | ------------------------------ | ---------------------------------------- | | `conversation.created` | A conversation is created. | | `conversation.assigned` | Assignment changes. | | `conversation.note.added` | An internal note is added. | | `conversation.agent.replied` | A teammate replies. | | `conversation.contact.replied` | The customer replies. | | `conversation.status.updated` | Status changes. | | `conversation.tags.updated` | Tags are added or updated. | | `conversation.moved` | The conversation moves to another inbox. | ## Envelope [#envelope] ```json { "eventType": "conversation.tags.updated", "data": { "type": "conversation", "id": "dea1fca0-6529-43fd-91df-044afbf2a1d4", "ticketId": 26, "subject": "Order INV-1042 arrived damaged", "excerpt": "The customer reported a cracked screen.", "status": "Active", "priority": "Normal", "active": true, "createdAt": "2026-07-29T13:04:05.000000Z", "tags": ["Shipping", "Priority"], "inbox": { "id": "f86385ff-9ce5-456a-a207-0bbf4ec59c0e", "name": "Support", "inboxAddress": "support@app.thrivedesk.email", "connectedEmailAddress": "support@example.com" }, "contact": { "id": "925298d4-a7d9-4d6b-8a01-10b2dea439aa", "name": "Jane Cooper", "email": "jane@example.com", "avatar": null }, "threadsCount": 3, "threads": [] } } ``` ## Important fields [#important-fields] | Field | Type | Notes | | ----------------- | -------------- | ------------------------------------------------------------- | | `eventType` | string | One of the event names above. | | `data.id` | string | Stable conversation identifier; use it as the REST API ID. | | `data.ticketId` | integer | Human-facing ticket number. | | `data.status` | string | `Active`, `Pending`, or `Closed`. | | `data.priority` | string | `High`, `Normal`, or `Low`. | | `data.inbox` | object | Inbox identifiers and addresses. | | `data.assignedTo` | object or null | Assigned teammate. | | `data.contact` | object | Customer identity in ThriveDesk. | | `data.threads` | array | Message, note, or draft thread entries included by the event. | Accept unknown fields and event names so additive changes do not break the receiver. When exact state matters, fetch the conversation after accepting the event. ## Related [#related] * [Verify signatures](/webhooks/signatures) * [Sync conversations guide](/guides/sync-conversations) # Webhooks overview and setup (/webhooks/overview) Webhooks send an HTTP request to your server when a selected ThriveDesk event occurs. Use them to start workflows quickly, then use the REST API when you need the latest complete resource state. ## Prerequisites [#prerequisites] * A public HTTPS endpoint that can receive POST requests. * A random signing secret stored in a secrets manager. * An idempotent queue or event handler. ## Configure a webhook [#configure-a-webhook] In the ThriveDesk App Store, install **Webhook**, name the integration, enter its callback URL and secret, choose events, select the inboxes it applies to, and save it. Your endpoint should verify `X-TD-SIGNATURE`, enqueue the event, and return a `2xx` quickly. ```js app.post('/webhooks/thrivedesk', rawJsonMiddleware, async (request, response) => { verifyThriveDeskSignature(request); await queue.publish(request.body); response.sendStatus(204); }); ``` Treat every request as attacker-controlled until its signature matches. Keep the secret on the server and rotate it if it is exposed. ## Related [#related] * [Event reference](/webhooks/events) * [Verify signatures](/webhooks/signatures) * [Webhook setup in the help center](https://help.thrivedesk.com/en/webhooks) # Retries, failures, and replay (/webhooks/retries) ThriveDesk treats any `2xx` response as success and discards the response body. A `410 Gone` response deactivates or deletes the webhook. Other status codes are failures; after several failures, the event is discarded. ## Delivery behavior [#delivery-behavior] The public contract does not specify the retry count, backoff schedule, retention window, delivery identifier, ordering guarantee, or a manual replay API. Do not build correctness around an assumed schedule. ## Recommended receiver [#recommended-receiver] 1. Verify the signature. 2. Compute a deduplication key from `eventType`, `data.id`, and the relevant event timestamp or thread ID. 3. Persist the payload durably. 4. Return `204`. 5. Process it asynchronously and make downstream actions idempotent. ```js import { createHash } from 'node:crypto'; const key = createHash('sha256') .update(JSON.stringify(event)) .digest('hex'); if (await deliveries.seen(key)) return response.sendStatus(204); await deliveries.store(key, event); await jobs.enqueue({ key }); return response.sendStatus(204); ``` The public payload does not expose a delivery ID, so hashing the complete payload is the safest available duplicate-delivery key. Keep reconciliation in place because two legitimate events can still carry identical data. Webhooks are notifications, not the sole event ledger. Periodically reconcile critical records with the REST API so a discarded delivery cannot create permanent drift. ## Related [#related] * [Idempotency and safe retries](/get-started/idempotency) * [Sync conversations guide](/guides/sync-conversations) * [Debugging](/webhooks/debugging) # Verify webhook signatures (/webhooks/signatures) Every webhook includes `X-TD-SIGNATURE`. ThriveDesk computes a base64-encoded HMAC-SHA1 using the webhook secret and the JSON-encoded `data` value from the request body. ## Verification contract [#verification-contract] 1. Read the request body and `X-TD-SIGNATURE` header. 2. JSON-encode the body’s `data` value without changing its key order or character escaping. 3. Compute binary HMAC-SHA1 with the webhook secret. 4. Base64-encode the result. 5. Compare the supplied and expected signatures in constant time. 6. Reject a missing or mismatched signature before processing the event. ## JavaScript [#javascript] ```js import { createHmac, timingSafeEqual } from 'node:crypto'; export function verifyWebhook(body, suppliedSignature, secret) { const expected = createHmac('sha1', secret) .update(JSON.stringify(body.data)) .digest('base64'); const supplied = Buffer.from(suppliedSignature ?? '', 'utf8'); const calculated = Buffer.from(expected, 'utf8'); return supplied.length === calculated.length && timingSafeEqual(supplied, calculated); } ``` ## PHP [#php] ```php bool: data = json.dumps(body["data"], separators=(",", ":"), ensure_ascii=False) digest = hmac.new(secret.encode(), data.encode(), hashlib.sha1).digest() expected = base64.b64encode(digest).decode() return hmac.compare_digest(expected, supplied) ``` JSON whitespace, key order, slash escaping, and non-ASCII escaping can change the signed bytes. Test your runtime against a real delivery before launch and retain the original request for debugging without logging the secret. ## Errors [#errors] Return `401` for a missing signature and `403` for a mismatch. Do not enqueue or log sensitive payload fields until verification succeeds. ## Related [#related] * [Webhook debugging](/webhooks/debugging) * [Webhook overview](/webhooks/overview) # Get current user, organization, and badge counts (/api/misc/me-get) Get current user, organization, and badge counts. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/me", "operation": { "summary": "Get current user, organization, and badge counts", "operationId": "me-get", "tags": [ "Misc" ], "description": "Get current user, organization, and badge counts.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MeResponse" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/me\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Search conversations (/api/misc/search-post) Search conversations. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "POST", "path": "/search", "operation": { "summary": "Search conversations", "operationId": "search-post", "tags": [ "Misc" ], "description": "Search conversations.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SearchResponse" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SearchBody" }, "example": { "q": { "subject": "refund", "status": "Active" }, "per-page": 20, "sort": "newest" } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X POST \"https://api.thrivedesk.com/v1/search\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"q\": {\n \"subject\": \"refund\",\n \"status\": \"Active\"\n },\n \"per-page\": 20,\n \"sort\": \"newest\"\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # View a conversation (/api/conversations/conversation-resource-get) View a conversation. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/conversation/{conversation_id}", "operation": { "summary": "View a conversation", "operationId": "conversation-resource-get", "tags": [ "Conversations" ], "description": "View a conversation.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConversationView" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ConversationId" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/conversation/7b1d4e2a-9c8f-4a3b-b6d5-1e2f3a4b5c6d\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Update a conversation (/api/conversations/conversation-resource-patch) Update a conversation. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "PATCH", "path": "/conversation/{conversation_id}", "operation": { "summary": "Update a conversation", "operationId": "conversation-resource-patch", "tags": [ "Conversations" ], "description": "Update a conversation.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ConversationId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConversationUpdateBody" }, "example": { "status": "Pending", "assign_to": "9c81790c-ae74-4cbd-b2ca-d246ae0df1a9", "tags": [ "9c81790c-ae74-4cbd-b2ca-d246ae0df1a9" ], "subject": "Order INV-1042 arrived damaged" } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X PATCH \"https://api.thrivedesk.com/v1/conversation/7b1d4e2a-9c8f-4a3b-b6d5-1e2f3a4b5c6d\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"status\": \"Pending\",\n \"assign_to\": \"9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\",\n \"tags\": [\n \"9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\"\n ],\n \"subject\": \"Order INV-1042 arrived damaged\"\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Delete a conversation (/api/conversations/conversation-resource-delete) Delete a conversation. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "DELETE", "path": "/conversation/{conversation_id}", "operation": { "summary": "Delete a conversation", "operationId": "conversation-resource-delete", "tags": [ "Conversations" ], "description": "Delete a conversation.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ConversationId" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X DELETE \"https://api.thrivedesk.com/v1/conversation/7b1d4e2a-9c8f-4a3b-b6d5-1e2f3a4b5c6d\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Change the contact on a conversation (/api/conversations/conversation-change-contact-patch) Change the contact on a conversation. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "PATCH", "path": "/conversation/{conversation_id}/change-contact", "operation": { "summary": "Change the contact on a conversation", "operationId": "conversation-change-contact-patch", "tags": [ "Conversations" ], "description": "Change the contact on a conversation.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ConversationId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChangeContactBody" }, "example": { "contact_id": "a2259012-556c-452c-ae91-e8d55e4107c0" } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X PATCH \"https://api.thrivedesk.com/v1/conversation/7b1d4e2a-9c8f-4a3b-b6d5-1e2f3a4b5c6d/change-contact\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"contact_id\": \"a2259012-556c-452c-ae91-e8d55e4107c0\"\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Update custom field values on a conversation (/api/conversations/conversation-custom-fields-patch) Update custom field values on a conversation. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "PATCH", "path": "/conversation/{conversation_id}/custom-fields", "operation": { "summary": "Update custom field values on a conversation", "operationId": "conversation-custom-fields-patch", "tags": [ "Conversations" ], "description": "Update custom field values on a conversation.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ConversationId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CustomFieldsUpdateBody" }, "example": { "order_number": "INV-1042", "issue_category": "shipping_damage" } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X PATCH \"https://api.thrivedesk.com/v1/conversation/7b1d4e2a-9c8f-4a3b-b6d5-1e2f3a4b5c6d/custom-fields\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"order_number\": \"INV-1042\",\n \"issue_category\": \"shipping_damage\"\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Create or update the reply draft (/api/conversations/conversation-draft-post) Create or update the reply draft. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "POST", "path": "/conversation/{conversation_id}/draft", "operation": { "summary": "Create or update the reply draft", "operationId": "conversation-draft-post", "tags": [ "Conversations" ], "description": "Create or update the reply draft.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DraftSaveResponse" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "x-notes": "One draft per user per conversation: posting again updates the existing draft. The returned draft_id is what reply and attachment upload consume.", "parameters": [ { "$ref": "#/components/parameters/ConversationId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DraftBody" }, "example": { "message": "

Hi Jane, a replacement is on the way.

", "cc": [ "colleague@example.com" ] } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X POST \"https://api.thrivedesk.com/v1/conversation/7b1d4e2a-9c8f-4a3b-b6d5-1e2f3a4b5c6d/draft\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"message\": \"

Hi Jane, a replacement is on the way.

\",\n \"cc\": [\n \"colleague@example.com\"\n ]\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Permanently delete a conversation (/api/conversations/conversation-force-delete-delete) Irreversible. The conversation must already be in the trash, so soft-delete it with `DELETE /v1/conversation/{conversation_id}` first; calling this on a live conversation returns 404. Everything hanging off the conversation goes with it: thread events, messages, attachments and the files behind them in object storage, tag links, and custom field values. There is no restore afterwards. Trashed conversations are also purged automatically once they pass the organization's trash lifetime (30 days by default). Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "DELETE", "path": "/conversation/{conversation_id}/force-delete", "operation": { "summary": "Permanently delete a conversation", "operationId": "conversation-force-delete-delete", "tags": [ "Conversations" ], "description": "Irreversible. The conversation must already be in the trash, so soft-delete it with `DELETE /v1/conversation/{conversation_id}` first; calling this on a live conversation returns 404.\n\nEverything hanging off the conversation goes with it: thread events, messages, attachments and the files behind them in object storage, tag links, and custom field values. There is no restore afterwards.\n\nTrashed conversations are also purged automatically once they pass the organization's trash lifetime (30 days by default).\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ConversationId" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X DELETE \"https://api.thrivedesk.com/v1/conversation/7b1d4e2a-9c8f-4a3b-b6d5-1e2f3a4b5c6d/force-delete\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Forward a conversation (/api/conversations/conversation-forward-post) Forward a conversation. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "POST", "path": "/conversation/{conversation_id}/forward", "operation": { "summary": "Forward a conversation", "operationId": "conversation-forward-post", "tags": [ "Conversations" ], "description": "Forward a conversation.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ConversationId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ForwardBody" }, "example": { "body": "Forwarding this conversation for a second opinion.", "message_id": "9c81790c-ae74-4cbd-b2ca-d246ae0df1a9", "to": [ "colleague@example.com" ] } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X POST \"https://api.thrivedesk.com/v1/conversation/7b1d4e2a-9c8f-4a3b-b6d5-1e2f3a4b5c6d/forward\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"body\": \"Forwarding this conversation for a second opinion.\",\n \"message_id\": \"9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\",\n \"to\": [\n \"colleague@example.com\"\n ]\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Merge other conversations into this one (/api/conversations/conversation-merge-post) Merge other conversations into this one. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "POST", "path": "/conversation/{conversation_id}/merge", "operation": { "summary": "Merge other conversations into this one", "operationId": "conversation-merge-post", "tags": [ "Conversations" ], "description": "Merge other conversations into this one.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ConversationId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MergeBody" }, "example": { "mergeable_conversation_ids": [ "9c81790c-ae74-4cbd-b2ca-d246ae0df1a9" ], "include_notes": true, "include_merge_summary": true } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X POST \"https://api.thrivedesk.com/v1/conversation/7b1d4e2a-9c8f-4a3b-b6d5-1e2f3a4b5c6d/merge\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"mergeable_conversation_ids\": [\n \"9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\"\n ],\n \"include_notes\": true,\n \"include_merge_summary\": true\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Get thread messages for a conversation (/api/conversations/conversation-messages-get) Get thread messages for a conversation. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/conversation/{conversation_id}/messages", "operation": { "summary": "Get thread messages for a conversation", "operationId": "conversation-messages-get", "tags": [ "Conversations" ], "description": "Get thread messages for a conversation.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MessagesResponse" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ConversationId" }, { "in": "query", "name": "event_id", "schema": { "type": "string" }, "description": "Return only the thread event with this message ID." } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/conversation/7b1d4e2a-9c8f-4a3b-b6d5-1e2f3a4b5c6d/messages\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Move a conversation to another inbox (/api/conversations/conversation-move-post) Move a conversation to another inbox. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "POST", "path": "/conversation/{conversation_id}/move", "operation": { "summary": "Move a conversation to another inbox", "operationId": "conversation-move-post", "tags": [ "Conversations" ], "description": "Move a conversation to another inbox.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ConversationId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MoveBody" }, "example": { "inbox_id": "3f7c1e94-2b6a-4d0e-8c5f-9a1b2c3d4e5f" } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X POST \"https://api.thrivedesk.com/v1/conversation/7b1d4e2a-9c8f-4a3b-b6d5-1e2f3a4b5c6d/move\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"inbox_id\": \"3f7c1e94-2b6a-4d0e-8c5f-9a1b2c3d4e5f\"\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Add an internal note (/api/conversations/conversation-note-post) Add an internal note. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "POST", "path": "/conversation/{conversation_id}/note", "operation": { "summary": "Add an internal note", "operationId": "conversation-note-post", "tags": [ "Conversations" ], "description": "Add an internal note.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ConversationId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NoteBody" }, "example": { "message": "Customer confirmed the invoice number over chat.", "mentioned_ids": [ "9c81790c-ae74-4cbd-b2ca-d246ae0df1a9" ] } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X POST \"https://api.thrivedesk.com/v1/conversation/7b1d4e2a-9c8f-4a3b-b6d5-1e2f3a4b5c6d/note\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"message\": \"Customer confirmed the invoice number over chat.\",\n \"mentioned_ids\": [\n \"9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\"\n ]\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Reply to a conversation (/api/conversations/conversation-reply-post) Reply to a conversation. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "POST", "path": "/conversation/{conversation_id}/reply", "operation": { "summary": "Reply to a conversation", "operationId": "conversation-reply-post", "tags": [ "Conversations" ], "description": "Reply to a conversation.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ConversationId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ReplyBody" }, "example": { "status": "Closed", "assign_to": "9c81790c-ae74-4cbd-b2ca-d246ae0df1a9", "action": "send_and_next_active", "cc": [ "supervisor@example.com" ] } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X POST \"https://api.thrivedesk.com/v1/conversation/7b1d4e2a-9c8f-4a3b-b6d5-1e2f3a4b5c6d/reply\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"status\": \"Closed\",\n \"assign_to\": \"9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\",\n \"action\": \"send_and_next_active\",\n \"cc\": [\n \"supervisor@example.com\"\n ]\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Schedule a reply (/api/conversations/conversation-reply-schedule-post) Schedule a reply. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "POST", "path": "/conversation/{conversation_id}/reply/schedule", "operation": { "summary": "Schedule a reply", "operationId": "conversation-reply-schedule-post", "tags": [ "Conversations" ], "description": "Schedule a reply.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ConversationId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ScheduledReplyWrite" }, "example": { "message": "

Following up on your damaged order.

", "scheduled_at": "2026-07-10T09:00:00Z", "type": "if_no_reply", "status": "Pending" } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X POST \"https://api.thrivedesk.com/v1/conversation/7b1d4e2a-9c8f-4a3b-b6d5-1e2f3a4b5c6d/reply/schedule\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"message\": \"

Following up on your damaged order.

\",\n \"scheduled_at\": \"2026-07-10T09:00:00Z\",\n \"type\": \"if_no_reply\",\n \"status\": \"Pending\"\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Cancel a scheduled reply (/api/conversations/conversation-reply-unschedule-delete) Cancel a scheduled reply. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "DELETE", "path": "/conversation/{conversation_id}/reply/unschedule/{message_id}", "operation": { "summary": "Cancel a scheduled reply", "operationId": "conversation-reply-unschedule-delete", "tags": [ "Conversations" ], "description": "Cancel a scheduled reply.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ConversationId" }, { "in": "path", "name": "message_id", "required": true, "schema": { "type": "string" } } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X DELETE \"https://api.thrivedesk.com/v1/conversation/7b1d4e2a-9c8f-4a3b-b6d5-1e2f3a4b5c6d/reply/unschedule/9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Restore a trashed conversation (/api/conversations/conversation-restore-patch) Restore a trashed conversation. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "PATCH", "path": "/conversation/{conversation_id}/restore", "operation": { "summary": "Restore a trashed conversation", "operationId": "conversation-restore-patch", "tags": [ "Conversations" ], "description": "Restore a trashed conversation.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ConversationId" } ], "requestBody": { "required": false, "content": { "application/json": { "schema": { "type": "object" }, "example": {} } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X PATCH \"https://api.thrivedesk.com/v1/conversation/7b1d4e2a-9c8f-4a3b-b6d5-1e2f3a4b5c6d/restore\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Update a scheduled reply (/api/conversations/conversation-scheduled-update-patch) Update a scheduled reply. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "PATCH", "path": "/conversation/{conversation_id}/scheduled/{message_id}", "operation": { "summary": "Update a scheduled reply", "operationId": "conversation-scheduled-update-patch", "tags": [ "Conversations" ], "description": "Update a scheduled reply.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ConversationId" }, { "in": "path", "name": "message_id", "required": true, "schema": { "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ScheduledReplyUpdate" }, "example": { "scheduled_at": "2026-07-10T09:00:00Z", "message": "

Updated follow-up message.

", "status": "Pending" } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X PATCH \"https://api.thrivedesk.com/v1/conversation/7b1d4e2a-9c8f-4a3b-b6d5-1e2f3a4b5c6d/scheduled/9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"scheduled_at\": \"2026-07-10T09:00:00Z\",\n \"message\": \"

Updated follow-up message.

\",\n \"status\": \"Pending\"\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Send a scheduled reply now (/api/conversations/conversation-scheduled-send-now-post) Send a scheduled reply now. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "POST", "path": "/conversation/{conversation_id}/scheduled/{message_id}/send-now", "operation": { "summary": "Send a scheduled reply now", "operationId": "conversation-scheduled-send-now-post", "tags": [ "Conversations" ], "description": "Send a scheduled reply now.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ConversationId" }, { "in": "path", "name": "message_id", "required": true, "schema": { "type": "string" } } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X POST \"https://api.thrivedesk.com/v1/conversation/7b1d4e2a-9c8f-4a3b-b6d5-1e2f3a4b5c6d/scheduled/9c81790c-ae74-4cbd-b2ca-d246ae0df1a9/send-now\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Snooze a conversation (/api/conversations/conversation-snooze-put) Snooze a conversation. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "PUT", "path": "/conversation/{conversation_id}/snooze", "operation": { "summary": "Snooze a conversation", "operationId": "conversation-snooze-put", "tags": [ "Conversations" ], "description": "Snooze a conversation.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ConversationId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SnoozeBody" }, "example": { "snoozed_until": "2026-07-10T09:00:00Z", "type": "if_no_reply" } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X PUT \"https://api.thrivedesk.com/v1/conversation/7b1d4e2a-9c8f-4a3b-b6d5-1e2f3a4b5c6d/snooze\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"snoozed_until\": \"2026-07-10T09:00:00Z\",\n \"type\": \"if_no_reply\"\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Mark a conversation as spam (/api/conversations/conversation-spam-post) Mark a conversation as spam. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "POST", "path": "/conversation/{conversation_id}/spam", "operation": { "summary": "Mark a conversation as spam", "operationId": "conversation-spam-post", "tags": [ "Conversations" ], "description": "Mark a conversation as spam.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ConversationId" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X POST \"https://api.thrivedesk.com/v1/conversation/7b1d4e2a-9c8f-4a3b-b6d5-1e2f3a4b5c6d/spam\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Unmark a conversation as spam (/api/conversations/conversation-spam-delete) Unmark a conversation as spam. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "DELETE", "path": "/conversation/{conversation_id}/spam", "operation": { "summary": "Unmark a conversation as spam", "operationId": "conversation-spam-delete", "tags": [ "Conversations" ], "description": "Unmark a conversation as spam.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ConversationId" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X DELETE \"https://api.thrivedesk.com/v1/conversation/7b1d4e2a-9c8f-4a3b-b6d5-1e2f3a4b5c6d/spam\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Split a conversation at a message (/api/conversations/conversation-split-post) Split a conversation at a message. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "POST", "path": "/conversation/{conversation_id}/split", "operation": { "summary": "Split a conversation at a message", "operationId": "conversation-split-post", "tags": [ "Conversations" ], "description": "Split a conversation at a message.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ConversationId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SplitBody" }, "example": { "thread_event_id": "9c81790c-ae74-4cbd-b2ca-d246ae0df1a9", "direction": "after", "subject": "Order INV-1042 arrived damaged", "status": "Active" } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X POST \"https://api.thrivedesk.com/v1/conversation/7b1d4e2a-9c8f-4a3b-b6d5-1e2f3a4b5c6d/split\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"thread_event_id\": \"9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\",\n \"direction\": \"after\",\n \"subject\": \"Order INV-1042 arrived damaged\",\n \"status\": \"Active\"\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Attach a tag (/api/conversations/conversation-tags-post) Attach a tag. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "POST", "path": "/conversation/{conversation_id}/tags", "operation": { "summary": "Attach a tag", "operationId": "conversation-tags-post", "tags": [ "Conversations" ], "description": "Attach a tag.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ConversationId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TagAttachBody" }, "example": { "tag": "9c81790c-ae74-4cbd-b2ca-d246ae0df1a9" } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X POST \"https://api.thrivedesk.com/v1/conversation/7b1d4e2a-9c8f-4a3b-b6d5-1e2f3a4b5c6d/tags\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"tag\": \"9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\"\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Detach a tag (/api/conversations/conversation-tags-delete) Detach a tag. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "DELETE", "path": "/conversation/{conversation_id}/tags", "operation": { "summary": "Detach a tag", "operationId": "conversation-tags-delete", "tags": [ "Conversations" ], "description": "Detach a tag.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ConversationId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TagDetachBody" }, "example": { "tag": "9c81790c-ae74-4cbd-b2ca-d246ae0df1a9" } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X DELETE \"https://api.thrivedesk.com/v1/conversation/7b1d4e2a-9c8f-4a3b-b6d5-1e2f3a4b5c6d/tags\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"tag\": \"9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\"\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Unsnooze a conversation (/api/conversations/conversation-unsnooze-delete) Unsnooze a conversation. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "DELETE", "path": "/conversation/{conversation_id}/unsnooze", "operation": { "summary": "Unsnooze a conversation", "operationId": "conversation-unsnooze-delete", "tags": [ "Conversations" ], "description": "Unsnooze a conversation.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ConversationId" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X DELETE \"https://api.thrivedesk.com/v1/conversation/7b1d4e2a-9c8f-4a3b-b6d5-1e2f3a4b5c6d/unsnooze\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Update a conversation's priority (/api/conversations/conversation-update-priority-put) Update a conversation's priority. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "PUT", "path": "/conversation/{conversation_id}/update/priority", "operation": { "summary": "Update a conversation's priority", "operationId": "conversation-update-priority-put", "tags": [ "Conversations" ], "description": "Update a conversation's priority.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ConversationId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PriorityBody" }, "example": { "priority": "High" } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X PUT \"https://api.thrivedesk.com/v1/conversation/7b1d4e2a-9c8f-4a3b-b6d5-1e2f3a4b5c6d/update/priority\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"priority\": \"High\"\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # List conversations assigned to the current user (/api/conversations/conversations-mine-get) List conversations assigned to the current user. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/conversations/mine", "operation": { "summary": "List conversations assigned to the current user", "operationId": "conversations-mine-get", "tags": [ "Conversations" ], "description": "List conversations assigned to the current user.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConversationList" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "x-notes": "Returns at most the five most recently active conversations. Not paginated.", "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/conversations/mine\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # List contacts (/api/contacts/contacts-index-get) List contacts. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/contacts", "operation": { "summary": "List contacts", "operationId": "contacts-index-get", "tags": [ "Contacts" ], "description": "List contacts.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ContactCollection" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/Page" }, { "in": "query", "name": "per_page", "schema": { "type": "integer", "default": 15 } }, { "in": "query", "name": "q", "schema": { "type": "string" }, "description": "Search by name or email." }, { "in": "query", "name": "inbox", "schema": { "type": "string" }, "description": "Only contacts with conversations in this inbox." }, { "in": "query", "name": "with_orphan", "schema": { "type": "boolean" }, "description": "Include contacts with no conversations." } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/contacts\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Create a contact (/api/contacts/contacts-index-post) Create a contact. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "POST", "path": "/contacts", "operation": { "summary": "Create a contact", "operationId": "contacts-index-post", "tags": [ "Contacts" ], "description": "Create a contact.", "responses": { "201": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ContactCreateResponse" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ContactCreate" }, "example": { "email": "jane@example.com" } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X POST \"https://api.thrivedesk.com/v1/contacts\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"email\": \"jane@example.com\"\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # View a contact (/api/contacts/contacts-resource-get) View a contact. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/contacts/{contact_id}", "operation": { "summary": "View a contact", "operationId": "contacts-resource-get", "tags": [ "Contacts" ], "description": "View a contact.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ContactResponse" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ContactId" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/contacts/a2259012-556c-452c-ae91-e8d55e4107c0\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Update a contact (/api/contacts/contacts-resource-patch) Update a contact. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "PATCH", "path": "/contacts/{contact_id}", "operation": { "summary": "Update a contact", "operationId": "contacts-resource-patch", "tags": [ "Contacts" ], "description": "Update a contact.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ContactId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ContactUpdate" }, "example": { "name": "Jane Cooper", "company": "Acme Inc", "job_title": "CTO", "website": "https://example.com" } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X PATCH \"https://api.thrivedesk.com/v1/contacts/a2259012-556c-452c-ae91-e8d55e4107c0\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"name\": \"Jane Cooper\",\n \"company\": \"Acme Inc\",\n \"job_title\": \"CTO\",\n \"website\": \"https://example.com\"\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # List conversations for a contact (/api/contacts/contacts-conversations-get) List conversations for a contact. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/contacts/{contact_id}/conversations", "operation": { "summary": "List conversations for a contact", "operationId": "contacts-conversations-get", "tags": [ "Contacts" ], "description": "List conversations for a contact.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ContactConversationsResponse" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ContactId" }, { "in": "query", "name": "inbox_id", "schema": { "type": "string" }, "description": "Only conversations in this inbox." }, { "in": "query", "name": "except", "schema": { "type": "string" }, "description": "Conversation ID to exclude." }, { "in": "query", "name": "limit", "schema": { "type": "integer" }, "description": "Maximum number of conversations to return." } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/contacts/a2259012-556c-452c-ae91-e8d55e4107c0/conversations\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # List inboxes (/api/inboxes/inboxes-index-get) List inboxes. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/inboxes", "operation": { "summary": "List inboxes", "operationId": "inboxes-index-get", "tags": [ "Inboxes" ], "description": "List inboxes.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InboxList" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/inboxes\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # List conversations in an inbox (/api/inboxes/inboxes-resource-get) List conversations in an inbox. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/inboxes/{inbox_id}", "operation": { "summary": "List conversations in an inbox", "operationId": "inboxes-resource-get", "tags": [ "Inboxes" ], "description": "List conversations in an inbox.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConversationCollection" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/InboxId" }, { "$ref": "#/components/parameters/Page" }, { "$ref": "#/components/parameters/PerPage" }, { "in": "query", "name": "view", "schema": { "type": "string" }, "description": "Custom view ID whose filters shape the list." } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/inboxes/3f7c1e94-2b6a-4d0e-8c5f-9a1b2c3d4e5f\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Filter conversations in an inbox (/api/inboxes/inboxes-resource-post) Filter conversations in an inbox. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "POST", "path": "/inboxes/{inbox_id}", "operation": { "summary": "Filter conversations in an inbox", "operationId": "inboxes-resource-post", "tags": [ "Inboxes" ], "description": "Filter conversations in an inbox.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConversationCollection" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/InboxId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InboxFilterBody" }, "example": { "filters": { "condition": "and", "groups": [ { "attribute": "status", "comparison": "eq", "values": [ { "value": "Active" } ] } ] }, "display": { "sort": "newest", "per_page": 25, "page": 1 } } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X POST \"https://api.thrivedesk.com/v1/inboxes/3f7c1e94-2b6a-4d0e-8c5f-9a1b2c3d4e5f\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"filters\": {\n \"condition\": \"and\",\n \"groups\": [\n {\n \"attribute\": \"status\",\n \"comparison\": \"eq\",\n \"values\": [\n {\n \"value\": \"Active\"\n }\n ]\n }\n ]\n },\n \"display\": {\n \"sort\": \"newest\",\n \"per_page\": 25,\n \"page\": 1\n }\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # List automations (/api/inboxes/inbox-automations-index-get) List automations. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/inboxes/{inbox_id}/automations", "operation": { "summary": "List automations", "operationId": "inbox-automations-index-get", "tags": [ "Inboxes" ], "description": "List automations.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AutomationList" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/InboxId" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/inboxes/3f7c1e94-2b6a-4d0e-8c5f-9a1b2c3d4e5f/automations\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # View an automation (/api/inboxes/inbox-automations-resource-get) View an automation. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/inboxes/{inbox_id}/automations/{automation_id}", "operation": { "summary": "View an automation", "operationId": "inbox-automations-resource-get", "tags": [ "Inboxes" ], "description": "View an automation.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AutomationResponse" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/InboxId" }, { "$ref": "#/components/parameters/AutomationId" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/inboxes/3f7c1e94-2b6a-4d0e-8c5f-9a1b2c3d4e5f/automations/9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Delete an automation (/api/inboxes/inbox-automations-resource-delete) Requires the `delete_automations` permission. Permanent: the automation is removed outright, and conversations it already acted on keep those changes. Creating and updating automations is not part of this surface. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "DELETE", "path": "/inboxes/{inbox_id}/automations/{automation_id}", "operation": { "summary": "Delete an automation", "operationId": "inbox-automations-resource-delete", "tags": [ "Inboxes" ], "description": "Requires the `delete_automations` permission. Permanent: the automation is removed outright, and conversations it already acted on keep those changes. Creating and updating automations is not part of this surface.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/InboxId" }, { "$ref": "#/components/parameters/AutomationId" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X DELETE \"https://api.thrivedesk.com/v1/inboxes/3f7c1e94-2b6a-4d0e-8c5f-9a1b2c3d4e5f/automations/9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Soft-delete many conversations (/api/inboxes/inbox-batch-delete-post) Soft-delete many conversations. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "POST", "path": "/inboxes/{inbox_id}/batch/delete", "operation": { "summary": "Soft-delete many conversations", "operationId": "inbox-batch-delete-post", "tags": [ "Inboxes" ], "description": "Soft-delete many conversations.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/InboxId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InboxBatchDeleteBody" }, "example": { "conversations": [ "9c81790c-ae74-4cbd-b2ca-d246ae0df1a9" ] } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X POST \"https://api.thrivedesk.com/v1/inboxes/3f7c1e94-2b6a-4d0e-8c5f-9a1b2c3d4e5f/batch/delete\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"conversations\": [\n \"9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\"\n ]\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Restore many trashed conversations (/api/inboxes/inbox-batch-restore-post) Restore many trashed conversations. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "POST", "path": "/inboxes/{inbox_id}/batch/restore", "operation": { "summary": "Restore many trashed conversations", "operationId": "inbox-batch-restore-post", "tags": [ "Inboxes" ], "description": "Restore many trashed conversations.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/InboxId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InboxBatchIdsBody" }, "example": { "conversation_ids": [ "9c81790c-ae74-4cbd-b2ca-d246ae0df1a9" ] } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X POST \"https://api.thrivedesk.com/v1/inboxes/3f7c1e94-2b6a-4d0e-8c5f-9a1b2c3d4e5f/batch/restore\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"conversation_ids\": [\n \"9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\"\n ]\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Bulk update conversations (/api/inboxes/inbox-batch-update-post) Bulk update conversations. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "POST", "path": "/inboxes/{inbox_id}/batch/update", "operation": { "summary": "Bulk update conversations", "operationId": "inbox-batch-update-post", "tags": [ "Inboxes" ], "description": "Bulk update conversations.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "412": { "description": "No update field was provided.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "Nothing to update" } } } } } }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/InboxId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InboxBatchUpdateBody" }, "example": { "conversations": [ "9c81790c-ae74-4cbd-b2ca-d246ae0df1a9" ], "status": "Closed", "assign_to": "9c81790c-ae74-4cbd-b2ca-d246ae0df1a9", "priority": "High" } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X POST \"https://api.thrivedesk.com/v1/inboxes/3f7c1e94-2b6a-4d0e-8c5f-9a1b2c3d4e5f/batch/update\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"conversations\": [\n \"9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\"\n ],\n \"status\": \"Closed\",\n \"assign_to\": \"9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\",\n \"priority\": \"High\"\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Start a new conversation in an inbox (/api/inboxes/inbox-conversations-store-post) Start a new conversation in an inbox. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "POST", "path": "/inboxes/{inbox_id}/conversations", "operation": { "summary": "Start a new conversation in an inbox", "operationId": "inbox-conversations-store-post", "tags": [ "Inboxes" ], "description": "Start a new conversation in an inbox.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/InboxId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InboxConversationCreate" }, "example": { "to": "customer@example.com", "status": "Active", "subject": "Order INV-1042 arrived damaged", "message": "Hi, my order arrived with a cracked screen. Can you help?", "agent": "9c81790c-ae74-4cbd-b2ca-d246ae0df1a9", "tags": [ "9c81790c-ae74-4cbd-b2ca-d246ae0df1a9" ], "contact": { "name": "Jane Cooper", "company": "Acme Inc" } } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X POST \"https://api.thrivedesk.com/v1/inboxes/3f7c1e94-2b6a-4d0e-8c5f-9a1b2c3d4e5f/conversations\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"to\": \"customer@example.com\",\n \"status\": \"Active\",\n \"subject\": \"Order INV-1042 arrived damaged\",\n \"message\": \"Hi, my order arrived with a cracked screen. Can you help?\",\n \"agent\": \"9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\",\n \"tags\": [\n \"9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\"\n ],\n \"contact\": {\n \"name\": \"Jane Cooper\",\n \"company\": \"Acme Inc\"\n }\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Create a custom field (/api/inboxes/inbox-custom-fields-index-post) Create a custom field. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "POST", "path": "/inboxes/{inbox_id}/custom-fields", "operation": { "summary": "Create a custom field", "operationId": "inbox-custom-fields-index-post", "tags": [ "Inboxes" ], "description": "Create a custom field.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "201": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CustomFieldResponse" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/InboxId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CustomFieldCreate" }, "example": { "name": "Order Number", "type": "text", "key": "order_number", "is_required": true, "is_active": true } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X POST \"https://api.thrivedesk.com/v1/inboxes/3f7c1e94-2b6a-4d0e-8c5f-9a1b2c3d4e5f/custom-fields\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"name\": \"Order Number\",\n \"type\": \"text\",\n \"key\": \"order_number\",\n \"is_required\": true,\n \"is_active\": true\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Update a custom field (/api/inboxes/inbox-custom-fields-resource-patch) Update a custom field. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "PATCH", "path": "/inboxes/{inbox_id}/custom-fields/{field_id}", "operation": { "summary": "Update a custom field", "operationId": "inbox-custom-fields-resource-patch", "tags": [ "Inboxes" ], "description": "Update a custom field.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CustomFieldResponse" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/InboxId" }, { "$ref": "#/components/parameters/FieldId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CustomFieldUpdate" }, "example": { "description": "The customer's order reference.", "is_required": true, "is_active": true } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X PATCH \"https://api.thrivedesk.com/v1/inboxes/3f7c1e94-2b6a-4d0e-8c5f-9a1b2c3d4e5f/custom-fields/9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"description\": \"The customer's order reference.\",\n \"is_required\": true,\n \"is_active\": true\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Delete a custom field (/api/inboxes/inbox-custom-fields-resource-delete) Delete a custom field. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "DELETE", "path": "/inboxes/{inbox_id}/custom-fields/{field_id}", "operation": { "summary": "Delete a custom field", "operationId": "inbox-custom-fields-resource-delete", "tags": [ "Inboxes" ], "description": "Delete a custom field.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/InboxId" }, { "$ref": "#/components/parameters/FieldId" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X DELETE \"https://api.thrivedesk.com/v1/inboxes/3f7c1e94-2b6a-4d0e-8c5f-9a1b2c3d4e5f/custom-fields/9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Delete a custom view (/api/inboxes/inbox-custom-views-resource-delete) Only the teammate who owns the view may delete it, the account owner included. Permanent, and it removes the view for everyone it was shared with. Listing and creating custom views is not part of this surface, so the identifier has to come from a first-party client. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "DELETE", "path": "/inboxes/{inbox_id}/custom-views/{custom_view_id}", "operation": { "summary": "Delete a custom view", "operationId": "inbox-custom-views-resource-delete", "tags": [ "Inboxes" ], "description": "Only the teammate who owns the view may delete it, the account owner included. Permanent, and it removes the view for everyone it was shared with. Listing and creating custom views is not part of this surface, so the identifier has to come from a first-party client.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Custom view deleted successfully" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/InboxId" }, { "$ref": "#/components/parameters/CustomViewId" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X DELETE \"https://api.thrivedesk.com/v1/inboxes/3f7c1e94-2b6a-4d0e-8c5f-9a1b2c3d4e5f/custom-views/9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # List saved replies for an inbox (/api/inboxes/inbox-saved-replies-get) List saved replies for an inbox. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/inboxes/{inbox_id}/saved-replies", "operation": { "summary": "List saved replies for an inbox", "operationId": "inbox-saved-replies-get", "tags": [ "Inboxes" ], "description": "List saved replies for an inbox.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SavedReplyList" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/InboxId" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/inboxes/3f7c1e94-2b6a-4d0e-8c5f-9a1b2c3d4e5f/saved-replies\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # List tags assigned in an inbox (/api/inboxes/inbox-tags-get) List tags assigned in an inbox. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/inboxes/{inbox_id}/tags", "operation": { "summary": "List tags assigned in an inbox", "operationId": "inbox-tags-get", "tags": [ "Inboxes" ], "description": "List tags assigned in an inbox.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InboxTagCollection" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "x-notes": "Uses simple pagination: `links.last`, `meta.last_page`, and `meta.total` are absent.", "parameters": [ { "$ref": "#/components/parameters/InboxId" }, { "$ref": "#/components/parameters/Page" }, { "in": "query", "name": "per_page", "schema": { "type": "integer", "default": 15 } } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/inboxes/3f7c1e94-2b6a-4d0e-8c5f-9a1b2c3d4e5f/tags\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # List tags (/api/tags/tags-index-get) List tags. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/settings/tags", "operation": { "summary": "List tags", "operationId": "tags-index-get", "tags": [ "Tags" ], "description": "List tags.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TagCollection" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/Page" }, { "in": "query", "name": "per_page", "schema": { "type": "integer", "default": 15 } }, { "in": "query", "name": "q", "schema": { "type": "string" }, "description": "Search tags by name." } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/settings/tags\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Create a tag (/api/tags/tags-index-post) Create a tag. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "POST", "path": "/settings/tags", "operation": { "summary": "Create a tag", "operationId": "tags-index-post", "tags": [ "Tags" ], "description": "Create a tag.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TagCreateResponse" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TagWrite" }, "example": { "name": "Billing", "color": "#FF0000" } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X POST \"https://api.thrivedesk.com/v1/settings/tags\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"name\": \"Billing\",\n \"color\": \"#FF0000\"\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Delete a tag (/api/tags/tags-resource-delete) Delete a tag. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "DELETE", "path": "/settings/tags/{tag_id}", "operation": { "summary": "Delete a tag", "operationId": "tags-resource-delete", "tags": [ "Tags" ], "description": "Delete a tag.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/TagId" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X DELETE \"https://api.thrivedesk.com/v1/settings/tags/9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Update a tag (/api/tags/tags-resource-put) Update a tag. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "PUT", "path": "/settings/tags/{tag_id}", "operation": { "summary": "Update a tag", "operationId": "tags-resource-put", "tags": [ "Tags" ], "description": "Update a tag.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/TagId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TagUpdate" }, "example": { "name": "Billing", "color": "#FF0000" } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X PUT \"https://api.thrivedesk.com/v1/settings/tags/9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"name\": \"Billing\",\n \"color\": \"#FF0000\"\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Merge tags into one (/api/tags/tags-merge-post) Merge tags into one. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "POST", "path": "/settings/tags/merge", "operation": { "summary": "Merge tags into one", "operationId": "tags-merge-post", "tags": [ "Tags" ], "description": "Merge tags into one.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TagsMergeBody" }, "example": { "name": "Billing", "color": "#FF0000", "tags": [ "9c81790c-ae74-4cbd-b2ca-d246ae0df1a9", "1a2b3c4d-5e6f-4708-9a0b-1c2d3e4f5a6b" ] } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X POST \"https://api.thrivedesk.com/v1/settings/tags/merge\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"name\": \"Billing\",\n \"color\": \"#FF0000\",\n \"tags\": [\n \"9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\",\n \"1a2b3c4d-5e6f-4708-9a0b-1c2d3e4f5a6b\"\n ]\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # List teammates and pending invitations (/api/users/settings-users-index-get) List teammates and pending invitations. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/settings/users", "operation": { "summary": "List teammates and pending invitations", "operationId": "settings-users-index-get", "tags": [ "Users" ], "description": "List teammates and pending invitations.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UsersIndexResponse" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "x-notes": "Organization owners see every member. Other roles see only agents sharing an inbox with them. Not paginated.", "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/settings/users\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # View a teammate (/api/users/settings-users-resource-get) View a teammate. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/settings/users/{user_id}", "operation": { "summary": "View a teammate", "operationId": "settings-users-resource-get", "tags": [ "Users" ], "description": "View a teammate.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserResponse" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/UserId" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/settings/users/9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # List saved replies (/api/saved-replies/saved-replies-index-get) List saved replies. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/saved-replies", "operation": { "summary": "List saved replies", "operationId": "saved-replies-index-get", "tags": [ "Saved Replies" ], "description": "List saved replies.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SavedReplyList" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "in": "query", "name": "inbox_id", "required": true, "schema": { "type": "string" }, "description": "Inbox to list saved replies for. Pass \"all\" for every inbox plus global replies." } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/saved-replies?inbox_id=all\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Create a saved reply (/api/saved-replies/saved-replies-index-post) Create a saved reply. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "POST", "path": "/saved-replies", "operation": { "summary": "Create a saved reply", "operationId": "saved-replies-index-post", "tags": [ "Saved Replies" ], "description": "Create a saved reply.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SavedReplyWrite" }, "example": { "name": "Refund acknowledgement", "message": "

We've started your refund.

", "folder": "Billing", "inbox_id": "3f7c1e94-2b6a-4d0e-8c5f-9a1b2c3d4e5f" } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X POST \"https://api.thrivedesk.com/v1/saved-replies\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"name\": \"Refund acknowledgement\",\n \"message\": \"

We've started your refund.

\",\n \"folder\": \"Billing\",\n \"inbox_id\": \"3f7c1e94-2b6a-4d0e-8c5f-9a1b2c3d4e5f\"\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Delete a saved reply (/api/saved-replies/saved-replies-resource-delete) Delete a saved reply. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "DELETE", "path": "/saved-replies/{saved_reply_id}", "operation": { "summary": "Delete a saved reply", "operationId": "saved-replies-resource-delete", "tags": [ "Saved Replies" ], "description": "Delete a saved reply.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/SavedReplyId" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X DELETE \"https://api.thrivedesk.com/v1/saved-replies/9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Update a saved reply (/api/saved-replies/saved-replies-resource-put) Update a saved reply. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "PUT", "path": "/saved-replies/{saved_reply_id}", "operation": { "summary": "Update a saved reply", "operationId": "saved-replies-resource-put", "tags": [ "Saved Replies" ], "description": "Update a saved reply.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/SavedReplyId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SavedReplyUpdate" }, "example": { "name": "Refund acknowledgement", "message": "

Your refund is being processed.

", "folder": "Billing" } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X PUT \"https://api.thrivedesk.com/v1/saved-replies/9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"name\": \"Refund acknowledgement\",\n \"message\": \"

Your refund is being processed.

\",\n \"folder\": \"Billing\"\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # List business-hours profiles (/api/business-hours/business-hours-index-get) List business-hours profiles. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/business-hours", "operation": { "summary": "List business-hours profiles", "operationId": "business-hours-index-get", "tags": [ "Business Hours" ], "description": "List business-hours profiles.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BusinessHourList" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "x-notes": "Newest first. Not paginated, and takes no query parameters.", "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/business-hours\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Create a business-hours profile (/api/business-hours/business-hours-index-post) Administrators and the account owner only. An inbox channel belongs to at most one profile. Binding one that another profile already covers returns 422 carrying `conflicting_business_hour_id`, `inbox_id`, and `channel` in place of the usual `errors` object, and the whole write is rolled back. Under `calendar_24_7` the server stores `schedule` and `schedule_type` as null whatever the payload carries. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "POST", "path": "/business-hours", "operation": { "summary": "Create a business-hours profile", "operationId": "business-hours-index-post", "tags": [ "Business Hours" ], "description": "Administrators and the account owner only.\n\nAn inbox channel belongs to at most one profile. Binding one that another profile already covers returns 422 carrying `conflicting_business_hour_id`, `inbox_id`, and `channel` in place of the usual `errors` object, and the whole write is rolled back.\n\nUnder `calendar_24_7` the server stores `schedule` and `schedule_type` as null whatever the payload carries.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "201": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BusinessHourResponse" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BusinessHourCreate" }, "example": { "name": "Support hours", "description": "Weekday coverage", "mode": "business_hours", "schedule_type": "standard", "schedule": [ { "day": "mon", "enabled": true, "start": "09:00", "end": "17:00" }, { "day": "tue", "enabled": true, "start": "09:00", "end": "17:00" }, { "day": "wed", "enabled": true, "start": "09:00", "end": "17:00" }, { "day": "thu", "enabled": true, "start": "09:00", "end": "17:00" }, { "day": "fri", "enabled": true, "start": "09:00", "end": "17:00" }, { "day": "sat", "enabled": false, "start": null, "end": null }, { "day": "sun", "enabled": false, "start": null, "end": null } ], "inbox_channels": [ { "inbox_id": "3f7c1e94-2b6a-4d0e-8c5f-9a1b2c3d4e5f", "channel": "email" } ] } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X POST \"https://api.thrivedesk.com/v1/business-hours\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"name\": \"Support hours\",\n \"description\": \"Weekday coverage\",\n \"mode\": \"business_hours\",\n \"schedule_type\": \"standard\",\n \"schedule\": [\n {\n \"day\": \"mon\",\n \"enabled\": true,\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n },\n {\n \"day\": \"tue\",\n \"enabled\": true,\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n },\n {\n \"day\": \"wed\",\n \"enabled\": true,\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n },\n {\n \"day\": \"thu\",\n \"enabled\": true,\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n },\n {\n \"day\": \"fri\",\n \"enabled\": true,\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n },\n {\n \"day\": \"sat\",\n \"enabled\": false,\n \"start\": null,\n \"end\": null\n },\n {\n \"day\": \"sun\",\n \"enabled\": false,\n \"start\": null,\n \"end\": null\n }\n ],\n \"inbox_channels\": [\n {\n \"inbox_id\": \"3f7c1e94-2b6a-4d0e-8c5f-9a1b2c3d4e5f\",\n \"channel\": \"email\"\n }\n ]\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # View a business-hours profile (/api/business-hours/business-hours-resource-get) View a business-hours profile. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/business-hours/{business_hour}", "operation": { "summary": "View a business-hours profile", "operationId": "business-hours-resource-get", "tags": [ "Business Hours" ], "description": "View a business-hours profile.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BusinessHourResponse" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/BusinessHourId" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/business-hours/5d8e2f61-4c3b-4a7d-9e0f-8b7a6c5d4e3f\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Update a business-hours profile (/api/business-hours/business-hours-resource-patch) Administrators and the account owner only. An inbox channel belongs to at most one profile. Binding one that another profile already covers returns 422 carrying `conflicting_business_hour_id`, `inbox_id`, and `channel` in place of the usual `errors` object, and the whole write is rolled back. Under `calendar_24_7` the server stores `schedule` and `schedule_type` as null whatever the payload carries. Omitted keys keep their stored value and an explicit `null` is ignored rather than clearing the field. Sending `inbox_channels` replaces the whole set. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "PATCH", "path": "/business-hours/{business_hour}", "operation": { "summary": "Update a business-hours profile", "operationId": "business-hours-resource-patch", "tags": [ "Business Hours" ], "description": "Administrators and the account owner only.\n\nAn inbox channel belongs to at most one profile. Binding one that another profile already covers returns 422 carrying `conflicting_business_hour_id`, `inbox_id`, and `channel` in place of the usual `errors` object, and the whole write is rolled back.\n\nUnder `calendar_24_7` the server stores `schedule` and `schedule_type` as null whatever the payload carries.\n\nOmitted keys keep their stored value and an explicit `null` is ignored rather than clearing the field. Sending `inbox_channels` replaces the whole set.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BusinessHourResponse" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/BusinessHourId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BusinessHourUpdate" }, "example": { "mode": "business_hours", "schedule_type": "custom", "schedule": [ { "day": "mon", "enabled": true, "start": "09:00", "end": "17:00" }, { "day": "tue", "enabled": true, "start": "09:00", "end": "17:00" }, { "day": "wed", "enabled": true, "start": "09:00", "end": "17:00" }, { "day": "thu", "enabled": true, "start": "09:00", "end": "17:00" }, { "day": "fri", "enabled": true, "start": "09:00", "end": "17:00" }, { "day": "sat", "enabled": false, "start": null, "end": null }, { "day": "sun", "enabled": false, "start": null, "end": null } ] } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X PATCH \"https://api.thrivedesk.com/v1/business-hours/5d8e2f61-4c3b-4a7d-9e0f-8b7a6c5d4e3f\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"mode\": \"business_hours\",\n \"schedule_type\": \"custom\",\n \"schedule\": [\n {\n \"day\": \"mon\",\n \"enabled\": true,\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n },\n {\n \"day\": \"tue\",\n \"enabled\": true,\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n },\n {\n \"day\": \"wed\",\n \"enabled\": true,\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n },\n {\n \"day\": \"thu\",\n \"enabled\": true,\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n },\n {\n \"day\": \"fri\",\n \"enabled\": true,\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n },\n {\n \"day\": \"sat\",\n \"enabled\": false,\n \"start\": null,\n \"end\": null\n },\n {\n \"day\": \"sun\",\n \"enabled\": false,\n \"start\": null,\n \"end\": null\n }\n ]\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Delete a business-hours profile (/api/business-hours/business-hours-resource-delete) Administrators and the account owner only. Permanent, and it releases every inbox channel the profile covered. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "DELETE", "path": "/business-hours/{business_hour}", "operation": { "summary": "Delete a business-hours profile", "operationId": "business-hours-resource-delete", "tags": [ "Business Hours" ], "description": "Administrators and the account owner only. Permanent, and it releases every inbox channel the profile covered.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "204": { "description": "Deleted. Empty body." }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/BusinessHourId" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X DELETE \"https://api.thrivedesk.com/v1/business-hours/5d8e2f61-4c3b-4a7d-9e0f-8b7a6c5d4e3f\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # List holidays (/api/holidays/holidays-index-get) List holidays. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/holidays", "operation": { "summary": "List holidays", "operationId": "holidays-index-get", "tags": [ "Holidays" ], "description": "List holidays.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HolidayList" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "x-notes": "Active first, then upcoming by start date, then past with the most recent first. Not paginated, and takes no query parameters.", "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/holidays\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Create a holiday (/api/holidays/holidays-index-post) Administrators and the account owner only. Ranges may overlap an existing holiday. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "POST", "path": "/holidays", "operation": { "summary": "Create a holiday", "operationId": "holidays-index-post", "tags": [ "Holidays" ], "description": "Administrators and the account owner only. Ranges may overlap an existing holiday.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "201": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HolidayResponse" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HolidayCreate" }, "example": { "name": "Winter break", "start_date": "2026-12-24", "end_date": "2026-12-26" } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X POST \"https://api.thrivedesk.com/v1/holidays\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"name\": \"Winter break\",\n \"start_date\": \"2026-12-24\",\n \"end_date\": \"2026-12-26\"\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # View a holiday (/api/holidays/holidays-resource-get) View a holiday. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/holidays/{holiday}", "operation": { "summary": "View a holiday", "operationId": "holidays-resource-get", "tags": [ "Holidays" ], "description": "View a holiday.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HolidayResponse" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/HolidayId" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/holidays/0f9d1c33-6a1b-4f9f-8f3a-2b7f8f0f0a11\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Update a holiday (/api/holidays/holidays-resource-patch) Administrators and the account owner only. When only one date is sent the range is checked against the stored value for the other. A range violation is always reported under `end_date`, even when `start_date` is the field that moved. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "PATCH", "path": "/holidays/{holiday}", "operation": { "summary": "Update a holiday", "operationId": "holidays-resource-patch", "tags": [ "Holidays" ], "description": "Administrators and the account owner only.\n\nWhen only one date is sent the range is checked against the stored value for the other. A range violation is always reported under `end_date`, even when `start_date` is the field that moved.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HolidayResponse" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/HolidayId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HolidayUpdate" }, "example": { "end_date": "2026-12-27" } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X PATCH \"https://api.thrivedesk.com/v1/holidays/0f9d1c33-6a1b-4f9f-8f3a-2b7f8f0f0a11\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"end_date\": \"2026-12-27\"\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Delete a holiday (/api/holidays/holidays-resource-delete) Administrators and the account owner only. The holiday stops applying immediately and drops out of the list. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "DELETE", "path": "/holidays/{holiday}", "operation": { "summary": "Delete a holiday", "operationId": "holidays-resource-delete", "tags": [ "Holidays" ], "description": "Administrators and the account owner only. The holiday stops applying immediately and drops out of the list.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "204": { "description": "Deleted. Empty body." }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/HolidayId" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X DELETE \"https://api.thrivedesk.com/v1/holidays/0f9d1c33-6a1b-4f9f-8f3a-2b7f8f0f0a11\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Agent leaderboard (/api/reports/reports-agents-get) Agent leaderboard. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/reports/{inbox_id}/agents", "operation": { "summary": "Agent leaderboard", "operationId": "reports-agents-get", "tags": [ "Reports" ], "description": "Agent leaderboard.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ReportsAgents" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/InboxId" }, { "$ref": "#/components/parameters/StartDate" }, { "$ref": "#/components/parameters/EndDate" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/reports/3f7c1e94-2b6a-4d0e-8c5f-9a1b2c3d4e5f/agents\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Conversation volume report (/api/reports/reports-conversations-get) Conversation volume report. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/reports/{inbox_id}/conversations", "operation": { "summary": "Conversation volume report", "operationId": "reports-conversations-get", "tags": [ "Reports" ], "description": "Conversation volume report.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ReportsConversations" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/InboxId" }, { "$ref": "#/components/parameters/StartDate" }, { "$ref": "#/components/parameters/EndDate" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/reports/3f7c1e94-2b6a-4d0e-8c5f-9a1b2c3d4e5f/conversations\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Happiness ratings report (/api/reports/reports-happiness-get) Happiness ratings report. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/reports/{inbox_id}/happiness", "operation": { "summary": "Happiness ratings report", "operationId": "reports-happiness-get", "tags": [ "Reports" ], "description": "Happiness ratings report.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ReportsHappiness" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/InboxId" }, { "$ref": "#/components/parameters/StartDate" }, { "$ref": "#/components/parameters/EndDate" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/reports/3f7c1e94-2b6a-4d0e-8c5f-9a1b2c3d4e5f/happiness\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Productivity report (/api/reports/reports-productivity-get) Productivity report. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/reports/{inbox_id}/productivity", "operation": { "summary": "Productivity report", "operationId": "reports-productivity-get", "tags": [ "Reports" ], "description": "Productivity report.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ReportsProductivity" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/InboxId" }, { "$ref": "#/components/parameters/StartDate" }, { "$ref": "#/components/parameters/EndDate" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/reports/3f7c1e94-2b6a-4d0e-8c5f-9a1b2c3d4e5f/productivity\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # List knowledge bases (/api/knowledge-base/knowledgebase-index-get) List knowledge bases. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/knowledgebases", "operation": { "summary": "List knowledge bases", "operationId": "knowledgebase-index-get", "tags": [ "Knowledge Base" ], "description": "List knowledge bases.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/KnowledgeBaseList" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/knowledgebases\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Create a knowledge base (/api/knowledge-base/knowledgebase-index-post) Create a knowledge base. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "POST", "path": "/knowledgebases", "operation": { "summary": "Create a knowledge base", "operationId": "knowledgebase-index-post", "tags": [ "Knowledge Base" ], "description": "Create a knowledge base.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/KnowledgeBaseCreateResponse" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/KnowledgeBaseCreate" }, "example": { "name": "Help Center", "slug": "help-center", "is_private": false, "members": [ { "email": "colleague@example.com", "role": "editor" } ] } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X POST \"https://api.thrivedesk.com/v1/knowledgebases\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"name\": \"Help Center\",\n \"slug\": \"help-center\",\n \"is_private\": false,\n \"members\": [\n {\n \"email\": \"colleague@example.com\",\n \"role\": \"editor\"\n }\n ]\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # View a knowledge base (/api/knowledge-base/knowledgebase-resource-get) View a knowledge base. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/knowledgebases/{knowledgebase_id}", "operation": { "summary": "View a knowledge base", "operationId": "knowledgebase-resource-get", "tags": [ "Knowledge Base" ], "description": "View a knowledge base.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/KnowledgeBaseResponse" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/KnowledgeBaseId" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/knowledgebases/9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Update a knowledge base (/api/knowledge-base/knowledgebase-resource-post) Update a knowledge base. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "POST", "path": "/knowledgebases/{knowledgebase_id}", "operation": { "summary": "Update a knowledge base", "operationId": "knowledgebase-resource-post", "tags": [ "Knowledge Base" ], "description": "Update a knowledge base.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "x-notes": "Uses POST because the extension's route file uses POST-for-update.", "parameters": [ { "$ref": "#/components/parameters/KnowledgeBaseId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/KnowledgeBaseUpdate" }, "example": { "name": "Help Center", "slug": "help-center" } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X POST \"https://api.thrivedesk.com/v1/knowledgebases/9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"name\": \"Help Center\",\n \"slug\": \"help-center\"\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Delete a knowledge base (/api/knowledge-base/knowledgebase-resource-delete) Delete a knowledge base. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "DELETE", "path": "/knowledgebases/{knowledgebase_id}", "operation": { "summary": "Delete a knowledge base", "operationId": "knowledgebase-resource-delete", "tags": [ "Knowledge Base" ], "description": "Delete a knowledge base.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/KnowledgeBaseId" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X DELETE \"https://api.thrivedesk.com/v1/knowledgebases/9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Remove a knowledge base member (/api/knowledge-base/knowledgebase-users-delete-delete) Revokes one person's access to the help center. The ThriveDesk user account is untouched, and re-inviting them restores access. Proxied to the help-center service, so the status and body are whatever it returns. Listing and inviting members is not part of this surface. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "DELETE", "path": "/knowledgebases/{knowledgebase_id}/users/{email}", "operation": { "summary": "Remove a knowledge base member", "operationId": "knowledgebase-users-delete-delete", "tags": [ "Knowledge Base" ], "description": "Revokes one person's access to the help center. The ThriveDesk user account is untouched, and re-inviting them restores access. Proxied to the help-center service, so the status and body are whatever it returns. Listing and inviting members is not part of this surface.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/KnowledgeBaseId" }, { "$ref": "#/components/parameters/Email" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X DELETE \"https://api.thrivedesk.com/v1/knowledgebases/9c81790c-ae74-4cbd-b2ca-d246ae0df1a9/users/teammate@example.com\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # List articles (/api/knowledge-base/knowledgebase-articles-index-get) List articles. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/knowledgebases/{knowledgebase_slug}/articles", "operation": { "summary": "List articles", "operationId": "knowledgebase-articles-index-get", "tags": [ "Knowledge Base" ], "description": "List articles.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/KnowledgeBaseArticleList" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/KnowledgeBaseSlug" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/knowledgebases/help-center/articles\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # View an article (/api/knowledge-base/knowledgebase-articles-show-get) View an article. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/knowledgebases/{knowledgebase_slug}/articles/{article_id}", "operation": { "summary": "View an article", "operationId": "knowledgebase-articles-show-get", "tags": [ "Knowledge Base" ], "description": "View an article.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/KnowledgeBaseArticle" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/KnowledgeBaseSlug" }, { "$ref": "#/components/parameters/ArticleId" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/knowledgebases/help-center/articles/9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Download an attachment (binary stream) (/api/attachments/attachments-download-get) Download an attachment (binary stream). ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/attachments/{attachmentId}/download", "operation": { "summary": "Download an attachment (binary stream)", "operationId": "attachments-download-get", "tags": [ "Attachments" ], "description": "Download an attachment (binary stream).", "responses": { "200": { "description": "Binary file stream. Content-Disposition header indicates the filename.", "headers": { "Content-Disposition": { "schema": { "type": "string" }, "description": "attachment; filename=" } }, "content": { "application/octet-stream": { "schema": { "type": "string", "format": "binary" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/AttachmentId" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/attachments/9c81790c-ae74-4cbd-b2ca-d246ae0df1a9/download\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Delete an attachment (/api/attachments/attachments-delete-delete) Delete an attachment. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "DELETE", "path": "/attachments/{attachmentId}/delete", "operation": { "summary": "Delete an attachment", "operationId": "attachments-delete-delete", "tags": [ "Attachments" ], "description": "Delete an attachment.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/AttachmentId" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X DELETE \"https://api.thrivedesk.com/v1/attachments/9c81790c-ae74-4cbd-b2ca-d246ae0df1a9/delete\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Upload attachments to a conversation draft (/api/attachments/attachments-store-post) Upload attachments to a conversation draft. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "POST", "path": "/attachments/conversation/{conversationId}/attachment", "operation": { "summary": "Upload attachments to a conversation draft", "operationId": "attachments-store-post", "tags": [ "Attachments" ], "description": "Upload attachments to a conversation draft.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AttachmentUploadResponse" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/ConversationIdCamel" } ], "requestBody": { "required": true, "content": { "multipart/form-data": { "schema": { "type": "object", "properties": { "attachments[]": { "type": "array", "items": { "type": "string", "format": "binary" }, "description": "One or more files." }, "draft_id": { "type": "string", "description": "Draft message to attach to. Pass the literal string \"null\" to create a draft on the fly." }, "is_inline": { "type": "boolean", "description": "Mark the files as inline images." } }, "required": [ "attachments[]" ] } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X POST \"https://api.thrivedesk.com/v1/attachments/conversation/7b1d4e2a-9c8f-4a3b-b6d5-1e2f3a4b5c6d/attachment\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -F \"attachments[]=@/path/to/file.pdf\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # View a single message body (/api/messages-and-notes/messages-resource-get) View a single message body. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "GET", "path": "/messages/{message_id}", "operation": { "summary": "View a single message body", "operationId": "messages-resource-get", "tags": [ "Messages and Notes" ], "description": "View a single message body.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MessageDetailResponse" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/MessageId" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X GET \"https://api.thrivedesk.com/v1/messages/9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Update a message (/api/messages-and-notes/messages-resource-put) Update a message. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "PUT", "path": "/messages/{message_id}", "operation": { "summary": "Update a message", "operationId": "messages-resource-put", "tags": [ "Messages and Notes" ], "description": "Update a message.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/MessageId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ThreadUpdateBody" }, "example": { "html_body": "

Corrected reply text.

", "text_body": "Corrected reply text." } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X PUT \"https://api.thrivedesk.com/v1/messages/9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"html_body\": \"

Corrected reply text.

\",\n \"text_body\": \"Corrected reply text.\"\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Delete a note (/api/messages-and-notes/notes-resource-delete) Delete a note. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "DELETE", "path": "/notes/{message_id}", "operation": { "summary": "Delete a note", "operationId": "notes-resource-delete", "tags": [ "Messages and Notes" ], "description": "Delete a note.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/MessageId" } ], "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X DELETE \"https://api.thrivedesk.com/v1/notes/9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\" \\\n -H \"Authorization: Bearer $TOKEN\"" } ], "security": [ { "bearerToken": [] } ] } } ] } ``` # Update a note (/api/messages-and-notes/notes-resource-put) Update a note. Personal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class. ```json { "servers": [ { "url": "https://api.thrivedesk.com/v1" } ], "security": [ { "bearerToken": [] } ], "operations": [ { "method": "PUT", "path": "/notes/{message_id}", "operation": { "summary": "Update a note", "operationId": "notes-resource-put", "tags": [ "Messages and Notes" ], "description": "Update a note.\n\nPersonal access token only. The API supports a second, partner-issued token class that is not part of the public surface. This endpoint does not accept that class.", "responses": { "200": { "description": "Success.", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "OK" } } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "404": { "$ref": "#/components/responses/NotFound" }, "422": { "$ref": "#/components/responses/UnprocessableEntity" }, "429": { "$ref": "#/components/responses/TooManyRequests" }, "500": { "$ref": "#/components/responses/ServerError" } }, "parameters": [ { "$ref": "#/components/parameters/MessageId" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ThreadUpdateBody" }, "example": { "html_body": "

Updated internal note.

", "text_body": "Updated internal note." } } } }, "x-codeSamples": [ { "lang": "curl", "label": "cURL", "source": "curl -X PUT \"https://api.thrivedesk.com/v1/notes/9c81790c-ae74-4cbd-b2ca-d246ae0df1a9\" \\\n -H \"Authorization: Bearer $TOKEN\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"html_body\": \"

Updated internal note.

\",\n \"text_body\": \"Updated internal note.\"\n}'" } ], "security": [ { "bearerToken": [] } ] } } ] } ```