Tidio OpenAPI (REST)

REST API for managing contacts, conversations, tickets, and operators. Requires Plus or Premium plan for full access; Lyro AI plan grants access to product-specific endpoints. Authentication uses X-Tidio-Openapi-Client-Id and X-Tidio-Openapi-Client-Secret headers.

OpenAPI Specification

tidio-openapi-openapi.yml Raw ↑
openapi: 3.0.3
info:
  title: Tidio OpenAPI (REST)
  description: >
    REST API for managing contacts, conversations, tickets, operators, and Lyro
    AI data sources. Requires Plus or Premium plan for full access; Lyro AI plan
    grants access to Lyro-specific endpoints. Authentication uses paired
    X-Tidio-Openapi-Client-Id and X-Tidio-Openapi-Client-Secret headers.
    Rate limits range from 10 requests per minute (entry plans) to 120 requests
    per minute (Premium).
  version: "1"
  contact:
    name: Tidio Developer Support
    url: https://developers.tidio.com/support
  termsOfService: https://www.tidio.com/terms/
  license:
    name: Proprietary
    url: https://www.tidio.com/terms/

servers:
  - url: https://api.tidio.co
    description: Tidio REST API

security:
  - clientId: []
    clientSecret: []

tags:
  - name: Contacts
    description: Manage contacts (website visitors identified by name, email, or phone)
  - name: Tickets
    description: Manage email tickets and replies
  - name: Operators
    description: Retrieve operator (chat agent) information
  - name: Departments
    description: Retrieve department information
  - name: Lyro
    description: Lyro AI data sources and ticket answering
  - name: Products
    description: Product catalog for Lyro AI recommendations
  - name: Project
    description: Retrieve project information

paths:

  /contacts:
    get:
      operationId: getContacts
      tags: [Contacts]
      summary: Get contacts
      description: >
        Returns a paginated list of contacts. Contacts are website visitors who
        have interacted with the Tidio widget and have been identified by their
        name, email address, or phone number.
      parameters:
        - name: cursor
          in: query
          required: false
          description: Value from the previous page. Use null to fetch the first page.
          schema:
            type: string
            nullable: true
        - name: email
          in: query
          required: false
          description: Filter contacts by email address.
          schema:
            type: string
            format: email
      responses:
        "200":
          description: Paginated list of contacts
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ContactList"
        "400":
          description: Invalid cursor or bad request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

    post:
      operationId: createContact
      tags: [Contacts]
      summary: Create contact
      description: >
        Creates a new contact. At least one of email, first_name, last_name, or
        phone must be provided. Always adds a new contact — no deduplication.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ContactCreate"
      responses:
        "201":
          description: Contact created successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UuidResponse"
        "400":
          description: Bad request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "422":
          description: Validation error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /contacts/batch:
    post:
      operationId: createContactsBatch
      tags: [Contacts]
      summary: Create multiple contacts
      description: >
        Creates up to 100 contacts in a single request using an all-or-nothing
        strategy — if any contact is invalid the entire request fails.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [contacts]
              properties:
                contacts:
                  type: array
                  minItems: 1
                  maxItems: 100
                  items:
                    $ref: "#/components/schemas/ContactCreate"
      responses:
        "201":
          description: Contacts created
        "422":
          description: Validation error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

    patch:
      operationId: updateContactsBatch
      tags: [Contacts]
      summary: Update multiple contacts
      description: >
        Updates up to 100 contacts in a single request using an all-or-nothing
        strategy.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [contacts]
              properties:
                contacts:
                  type: array
                  minItems: 1
                  maxItems: 100
                  items:
                    $ref: "#/components/schemas/ContactPatch"
      responses:
        "200":
          description: Contacts updated
        "422":
          description: Validation error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /contacts/{contactId}:
    get:
      operationId: getContact
      tags: [Contacts]
      summary: Get single contact
      parameters:
        - $ref: "#/components/parameters/contactId"
      responses:
        "200":
          description: Contact details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Contact"
        "404":
          description: Contact not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

    patch:
      operationId: updateContact
      tags: [Contacts]
      summary: Update contact properties
      parameters:
        - $ref: "#/components/parameters/contactId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ContactPatch"
      responses:
        "200":
          description: Contact updated
        "404":
          description: Contact not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "422":
          description: Validation error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

    delete:
      operationId: deleteContact
      tags: [Contacts]
      summary: Delete contact
      description: Permanently deletes a contact. This action cannot be undone.
      parameters:
        - $ref: "#/components/parameters/contactId"
      responses:
        "204":
          description: Contact deleted successfully
        "404":
          description: Contact not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "422":
          description: Validation error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /contacts/{contactId}/messages:
    get:
      operationId: getContactMessages
      tags: [Contacts]
      summary: Get contact messages
      description: Returns all messages in a contact's conversation history.
      parameters:
        - $ref: "#/components/parameters/contactId"
      responses:
        "200":
          description: Contact messages
          content:
            application/json:
              schema:
                type: object
                properties:
                  messages:
                    type: array
                    items:
                      $ref: "#/components/schemas/Message"
        "404":
          description: Contact not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /contacts/{contactId}/viewed-pages:
    get:
      operationId: getContactViewedPages
      tags: [Contacts]
      summary: Get viewed pages history
      description: >
        Returns a list of pages the contact has viewed on your website, covering
        the past 30 days.
      parameters:
        - $ref: "#/components/parameters/contactId"
      responses:
        "200":
          description: Viewed pages
          content:
            application/json:
              schema:
                type: object
                properties:
                  pages:
                    type: array
                    items:
                      type: object
                      properties:
                        url:
                          type: string
                          format: uri
                        visited_at:
                          type: string
                          format: date-time
        "404":
          description: Contact not found

  /contact-properties:
    get:
      operationId: getContactProperties
      tags: [Contacts]
      summary: Get contact properties
      description: >
        Returns the complete list of contact property definitions (default and
        custom) configured in the Tidio panel.
      responses:
        "200":
          description: Contact properties list
          content:
            application/json:
              schema:
                type: object
                properties:
                  properties:
                    type: array
                    items:
                      $ref: "#/components/schemas/ContactPropertyDefinition"

  /tickets:
    get:
      operationId: getTickets
      tags: [Tickets]
      summary: Get tickets
      description: Returns a paginated list of tickets without messages.
      parameters:
        - name: cursor
          in: query
          required: false
          description: Value from the previous page. Use null to fetch the first page.
          schema:
            type: string
            nullable: true
      responses:
        "200":
          description: Paginated list of tickets
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TicketList"
        "400":
          description: Invalid cursor
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /tickets/as-contact:
    post:
      operationId: createTicketAsContact
      tags: [Tickets]
      summary: Create ticket (as Contact)
      description: Creates a ticket on behalf of a contact.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TicketCreateAsContact"
      responses:
        "201":
          description: Ticket created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UuidResponse"
        "422":
          description: Validation error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /tickets/{ticketId}:
    get:
      operationId: getTicket
      tags: [Tickets]
      summary: Get ticket details
      description: Returns full details of a single ticket including all messages.
      parameters:
        - $ref: "#/components/parameters/ticketId"
      responses:
        "200":
          description: Ticket with messages
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TicketWithMessages"
        "400":
          description: Bad request
        "404":
          description: Ticket not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

    patch:
      operationId: updateTicket
      tags: [Tickets]
      summary: Update ticket
      description: Updates status, priority, or assignment of a ticket.
      parameters:
        - $ref: "#/components/parameters/ticketId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TicketUpdate"
      responses:
        "204":
          description: Ticket updated successfully
        "422":
          description: Validation error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

    delete:
      operationId: deleteTicket
      tags: [Tickets]
      summary: Delete ticket
      description: Permanently deletes a ticket. This action cannot be undone.
      parameters:
        - $ref: "#/components/parameters/ticketId"
      responses:
        "204":
          description: Ticket deleted
        "404":
          description: Ticket not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /tickets/{ticketId}/reply:
    post:
      operationId: replyToTicket
      tags: [Tickets]
      summary: Reply to a ticket
      description: Adds a reply message to an existing ticket from an operator or contact.
      parameters:
        - $ref: "#/components/parameters/ticketId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TicketReply"
      responses:
        "201":
          description: Reply created
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    description: ULID identifier of the created message
                    example: "01HAVMVKF90KH3EC0HK2T6QYP6"
        "400":
          description: Bad request
        "404":
          description: Ticket not found
        "422":
          description: Validation error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /operators:
    get:
      operationId: getOperators
      tags: [Operators]
      summary: Get operators
      description: Returns a paginated list of operators (chat agents).
      parameters:
        - name: cursor
          in: query
          required: false
          schema:
            type: string
            nullable: true
      responses:
        "200":
          description: Paginated list of operators
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OperatorList"
        "400":
          description: Bad request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /departments:
    get:
      operationId: getDepartments
      tags: [Departments]
      summary: Get departments
      description: Returns all departments including the default General department.
      responses:
        "200":
          description: List of departments
          content:
            application/json:
              schema:
                type: object
                properties:
                  departments:
                    type: array
                    items:
                      $ref: "#/components/schemas/Department"

  /project:
    get:
      operationId: getProject
      tags: [Project]
      summary: Get project info
      description: Returns information about the authenticated project.
      responses:
        "200":
          description: Project information
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Project"

  /lyro/data-sources:
    get:
      operationId: getLyroDataSources
      tags: [Lyro]
      summary: Get Lyro data sources
      description: >
        Returns a paginated list of data sources used by the Lyro AI Agent.
        Supports filtering by kind (qa/folder) and parent_id.
      parameters:
        - name: cursor
          in: query
          required: false
          schema:
            type: string
            nullable: true
        - name: kind
          in: query
          required: false
          description: Filter by kind (qa or folder).
          schema:
            type: array
            items:
              type: string
              enum: [qa, folder]
        - name: parent_id
          in: query
          required: false
          description: Filter by parent data source UUID.
          schema:
            type: string
            format: uuid
        - name: order
          in: query
          required: false
          description: Sort direction (asc or desc, defaults to desc).
          schema:
            type: string
            enum: [asc, desc]
            default: desc
      responses:
        "200":
          description: Paginated list of Lyro data sources
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/LyroDataSourceList"
        "400":
          description: Bad request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /lyro/data-sources/qa:
    post:
      operationId: createLyroQaDataSource
      tags: [Lyro]
      summary: Create Lyro QA data source
      description: Creates a QA (question-answer) data source for the Lyro AI Agent.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/LyroQaCreate"
      responses:
        "201":
          description: QA data source created
        "422":
          description: Validation error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /lyro/data-sources/website:
    put:
      operationId: upsertLyroWebsiteDataSource
      tags: [Lyro]
      summary: Upsert Lyro data source
      description: >
        Uploads or updates an HTML-based data source for the Lyro AI Agent. If a
        source with the same URL exists, it is updated; otherwise a new one is
        created.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/LyroWebsiteUpsert"
      responses:
        "200":
          description: Data source upserted
        "422":
          description: Validation error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /lyro/data-sources/website/scrape:
    post:
      operationId: scrapeWebsiteLyroDataSource
      tags: [Lyro]
      summary: Add website as Lyro data source (scraping)
      description: >
        Submits a website URL to be scraped and used as a knowledge data source
        for the Lyro AI Agent. Each URL must be unique per project.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [url]
              properties:
                url:
                  type: string
                  format: uri
                  description: Website URL to scrape.
      responses:
        "201":
          description: Website scraping initiated
        "409":
          description: URL already exists as a data source
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "422":
          description: Validation error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /lyro/tickets:
    post:
      operationId: askLyroToAnswerTicket
      tags: [Lyro]
      summary: Ask Lyro to answer ticket
      description: >
        Asks Lyro AI to generate an answer for a ticket. Processing can take up
        to 40 seconds. Currently supports only the first message of a ticket.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/LyroTicketRequest"
      responses:
        "200":
          description: Lyro answer generated (may be null if Lyro cannot answer)
          content:
            application/json:
              schema:
                type: object
                properties:
                  message_content:
                    type: string
                    nullable: true
                    description: Answer generated by Lyro, or null if unable to answer.
        "409":
          description: Quota exceeded or Lyro disabled
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "422":
          description: Validation error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /products/batch:
    put:
      operationId: upsertProducts
      tags: [Products]
      summary: Upsert products
      description: >
        Upload or update up to 100 products for Lyro AI recommendations using
        batch processing. Products are processed all-or-nothing. Processing is
        asynchronous.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [products]
              properties:
                products:
                  type: array
                  minItems: 1
                  maxItems: 100
                  items:
                    $ref: "#/components/schemas/ProductUpsert"
      responses:
        "204":
          description: Products accepted for processing
        "400":
          description: Bad request
        "409":
          description: Products import already initialized from e-commerce platform
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "422":
          description: Validation error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /products/{productId}:
    delete:
      operationId: deleteProduct
      tags: [Products]
      summary: Delete product
      description: >
        Permanently removes a product from Lyro AI recommendations. Deletion is
        irreversible and processed asynchronously.
      parameters:
        - name: productId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "204":
          description: Product deletion accepted
        "404":
          description: Product not found

components:
  securitySchemes:
    clientId:
      type: apiKey
      in: header
      name: X-Tidio-Openapi-Client-Id
    clientSecret:
      type: apiKey
      in: header
      name: X-Tidio-Openapi-Client-Secret

  parameters:
    contactId:
      name: contactId
      in: path
      required: true
      description: UUID identifying the contact.
      schema:
        type: string
        format: uuid
        example: "a1b4ca4c-1108-4432-b256-1e4cf2bf6f9e"

    ticketId:
      name: ticketId
      in: path
      required: true
      description: Integer identifying the ticket.
      schema:
        type: integer
        example: 10000

  schemas:

    ErrorItem:
      type: object
      properties:
        code:
          type: string
        message:
          type: string

    ErrorResponse:
      type: object
      properties:
        errors:
          type: array
          items:
            $ref: "#/components/schemas/ErrorItem"

    UuidResponse:
      type: object
      properties:
        id:
          type: string
          format: uuid

    PaginationMeta:
      type: object
      properties:
        cursor:
          type: string
          nullable: true
          description: Token for the next page; null when on the last page.
        limit:
          type: integer

    ContactProperty:
      type: object
      properties:
        name:
          type: string
          maxLength: 128
        value:
          type: string
          maxLength: 1000

    Contact:
      type: object
      properties:
        id:
          type: string
          format: uuid
        distinct_id:
          type: string
          nullable: true
        first_name:
          type: string
          nullable: true
        last_name:
          type: string
          nullable: true
        email:
          type: string
          format: email
          nullable: true
        phone:
          type: string
          nullable: true
        language:
          type: string
          nullable: true
          description: ISO 639-1 language code.
        country:
          type: string
          nullable: true
          description: ISO 3166 Alpha-2 country code.
        city:
          type: string
          nullable: true
        created_at:
          type: string
          format: date-time
        email_consent:
          type: string
          enum: [subscribed, unsubscribed]
        properties:
          type: array
          items:
            $ref: "#/components/schemas/ContactProperty"

    ContactList:
      type: object
      properties:
        contacts:
          type: array
          items:
            $ref: "#/components/schemas/Contact"
        meta:
          $ref: "#/components/schemas/PaginationMeta"

    ContactCreate:
      type: object
      description: At least one of email, first_name, last_name, or phone is required.
      properties:
        email:
          type: string
          format: email
        first_name:
          type: string
          maxLength: 127
        last_name:
          type: string
          maxLength: 127
        phone:
          type: string
          maxLength: 155
        email_consent:
          type: string
          enum: [subscribed, unsubscribed]
        distinct_id:
          type: string
          maxLength: 55
        properties:
          type: array
          items:
            $ref: "#/components/schemas/ContactProperty"

    ContactPatch:
      type: object
      properties:
        email:
          type: string
          format: email
          nullable: true
        first_name:
          type: string
          maxLength: 127
          nullable: true
        last_name:
          type: string
          maxLength: 127
          nullable: true
        phone:
          type: string
          maxLength: 155
          nullable: true
        email_consent:
          type: string
          enum: [subscribed, unsubscribed]
        distinct_id:
          type: string
          maxLength: 55
          nullable: true
        properties:
          type: array
          items:
            $ref: "#/components/schemas/ContactProperty"

    ContactPropertyDefinition:
      type: object
      properties:
        name:
          type: string
        type:
          type: string
          enum: [text, email, number, phone, url]

    Ticket:
      type: object
      properties:
        id:
          type: integer
        link:
          type: string
          format: uri
        subject:
          type: string
        contact_id:
          type: string
          format: uuid
        contact_email:
          type: string
          nullable: true
        priority:
          type: string
          enum: [low, normal, urgent]
        status:
          type: string
          enum: [open, pending, solved]
        assigned_operator_id:
          type: string
          format: uuid
          nullable: true
        assigned_department_id:
          type: string
          format: uuid
        custom_channel_id:
          type: string
          nullable: true

    TicketList:
      type: object
      properties:
        tickets:
          type: array
          items:
            $ref: "#/components/schemas/Ticket"
        meta:
          $ref: "#/components/schemas/PaginationMeta"

    TicketMessage:
      type: object
      properties:
        message_id:
          type: string
          description: ULID format identifier.
        created_at:
          type: string
          format: date-time
        author_type:
          type: string
          enum: [operator, contact]
        author_id:
          type: string
          format: uuid
        message_type:
          type: string
          enum: [internal, public]
        attachments:
          type: array
          items:
            type: string
            format: uri

    TicketWithMessages:
      allOf:
        - $ref: "#/components/schemas/Ticket"
        - type: object
          properties:
            messages:
              type: array
              items:
                $ref: "#/components/schemas/TicketMessage"

    TicketUpdate:
      type: object
      properties:
        status:
          type: string
          enum: [open, pending, solved]
        priority:
          type: string
          enum: [low, normal, urgent]
        assigned:
          type: object
          nullable: true
          properties:
            type:
              type: string
              enum: [department, operator]
            id:
              type: string
              format: uuid

    TicketReply:
      type: object
      required: [author_type, content]
      properties:
        author_type:
          type: string
          enum: [contact, operator]
        content:
          type: string
        operator_id:
          type: string
          format: uuid
          description: Required when author_type is operator.
        message_type:
          type: string
          enum: [public, internal]

    TicketCreateAsContact:
      type: object
      properties:
        subject:
          type: string
        contact_id:
          type: string
          format: uuid
        content:
          type: string

    Operator:
      type: object
      properties:
        id:
          type: string
          format: uuid
        active:
          type: boolean
        email:
          type: string
          format: email
        name:
          type: string
          nullable: true
        role:
          type: string
          enum: [owner, admin, chat_agent, moderator, custom]
        picture:
          type: string
          format: uri
          nullable: true
        last_seen:
          type: string
          format: date-time
          nullable: true

    OperatorList:
      type: object
      properties:
        operators:
          type: array
          items:
            $ref: "#/components/schemas/Operator"
        meta:
          $ref: "#/components/schemas/PaginationMeta"

    Department:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string

    Project:
      type: object
      properties:
        id:
          type: string
        name:
          type: string

    Message:
      type: object
      properties:
        message_id:
          type: string
        created_at:
          type: string
          format: date-time
        author_type:
          type: string
          enum: [operator, contact, bot]
        content:
          type: string

    LyroDataSource:
      type: object
      properties:
        id:
          type: string
          format: uuid
        parent_id:
          type: string
          format: uuid
          nullable: true
        title:
          type: string
        type:
          type: string
          enum: [qa, website, zendesk_hc, external_html, pdf_file]
        kind:
          type: string
          enum: [qa, folder]
        origin:
          type: string
          enum: [manual, inbox, industry, website, csv_file, pdf_file, zendesk_hc, external_html]
        status:
          type: string
          enum: [in progress, error, used]
        used_by_lyro:
          type: boolean
        used_by_copilot:
          type: boolean
        sync_status:
          type: string
          enum: [in progress, error, success]
          nullable: true
  

# --- truncated at 32 KB (35 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/tidio/refs/heads/main/openapi/tidio-openapi-openapi.yml