# Auto-generated Open API specification, any manual modifications will be lost during regeneration.
openapi: 3.1.0
info:
  title: Gaio API
  description: "Operate a Gaio account from your own program: its contacts, conversations,\nautomations and webhooks, authenticated with an API key. The guide, with the conventions every\nroute follows, is at https://gaio.social/developers, and the index for coding agents at\nhttps://gaio.social/developers/llms.txt."
  version: 1.0.0
servers:
  - url: "https://api.gaio.social"

paths:
  /v1/me:
    get:
      operationId: readMe
      summary: "Read the account and the key"
      description: "The account and the key a request acts as. Needs no scope: it reads nothing beyond the key itself."
      tags:
        - "Account"
      security:
        - publicApiKey: []
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/readMeHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "Forbidden"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '404':
          description: "The key no longer resolves to an account (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/contacts:
    get:
      operationId: listContacts
      summary: "List contacts"
      description: "The account's contacts, least recently active first (`updated_at`, then `id`). The filters combine.\n\nTo keep a copy in sync, page until the first contact whose `updated_at` is later than the moment\nthe pass started, and start the next pass from `updated_since` a few minutes before that moment:\na contact touched during a pass moves past it and is read by the next pass, never lost nor read\ntwice in one pass, and the client upserts by `id`. `updated_since` follows the contact's activity\nonly: a change to its tags or values made by an automation, a bulk action, another key or a\nremoval on another contact of its person does not bring it back, and neither does a deletion, so\na copy of tags and values needs a periodic full read."
      tags:
        - "Contacts"
      security:
        - publicApiKey: []
      parameters:
        - name: cursor
          in: query
          description: "The `next_cursor` of the previous page. Opaque: its content may change at any time."
          required: false
          schema:
            type: string
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
        - name: updated_since
          in: query
          description: "Only contacts whose `updated_at` is at or after this moment."
          required: false
          schema:
            type: string
            format: date-time
        - name: phone
          in: query
          description: "The WhatsApp contact of this phone. A Brazilian mobile matches with or without the ninth\ndigit; a foreign number needs its `+`."
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 32
        - name: instagram_username
          in: query
          description: "Instagram contacts with this username as Instagram sends it, with or without the `@`: it\nmatches in lowercase or exactly as given."
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 64
        - name: instagram_id
          in: query
          description: "The Instagram contact with this id (`instagram.id`)."
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 64
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/listContactsHandler'
        '400':
          description: "The cursor was not issued by this list (`invalid_cursor`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `contacts:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '422':
          description: "The phone is not one a contact can have (`invalid_phone`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
    post:
      operationId: createContact
      summary: "Create a WhatsApp contact"
      description: "Create a WhatsApp contact, or update the one that already holds the phone: the same as importing\na spreadsheet of one row. Answers 201 when it created the contact and 200 when it existed.\n\n- An existing contact is found under either form of a Brazilian mobile and keeps its id.\n- `name` overwrites the contact's name; its next message with a profile name overwrites it again.\n- The values and tags are added; values and tags not given are left as they are.\n- The contact is not billed until a first message is stored, in either direction, and no\n  messaging window is opened.\n- The contact's history records the consent and the connection (`contact.imported`); the tags\n  and values it sets are not recorded one by one.\n- Webhooks report `contact.created` for a contact it created, carrying its tags and values, and\n  for one that existed, `contact.tagged` and `contact.custom_fields_updated` for what changed.\n- Sending it again is safe: it finds the contact by the phone and records the consent again. After\n  `outcome_unknown`, send it again with a new Idempotency-Key."
      tags:
        - "Contacts"
      security:
        - publicApiKey: []
      parameters:
        - name: idempotency-key
          in: header
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 255
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/createContactHandlerRequest'
      responses:
        '201':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/createContactHandler'
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/createContactHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `contacts:write` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '409':
          description: "A request with this Idempotency-Key is still running (`idempotency_in_progress`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '422':
          description: "Without `consent: true` (`consent_required`), a phone no contact can have\n(`invalid_phone`), a blank name (`invalid_name`), a connection that is not a connected WhatsApp\nnumber of the account (`invalid_connection`), a tag or custom field that does not exist\n(`tag_not_found`, `custom_field_not_found`), a value its field refuses\n(`invalid_custom_field_value`), or an Idempotency-Key reused with another request\n(`idempotency_key_reused`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its write requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/contacts/{contactId}:
    get:
      operationId: readContact
      summary: "Read a contact"
      description: "One contact of the account."
      tags:
        - "Contacts"
      security:
        - publicApiKey: []
      parameters:
        - name: contactId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/readContactHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `contacts:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "No such contact in the account (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/contacts/{contactId}/tags/{tagId}:
    put:
      operationId: addContactTag
      summary: "Tag a contact"
      description: "Put a tag on a contact. A tag the contact already has is left as it is, and the answer is the\nsame. The contact's `updated_at` does not move."
      tags:
        - "Contacts"
      security:
        - publicApiKey: []
      parameters:
        - name: idempotency-key
          in: header
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 255
        - name: contactId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: tagId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/addContactTagHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `contacts:write` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "No such contact or tag in the account (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '409':
          description: "A request with this Idempotency-Key is still running (`idempotency_in_progress`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '422':
          description: "This Idempotency-Key was used with another request (`idempotency_key_reused`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its write requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
    delete:
      operationId: removeContactTag
      summary: "Untag a contact"
      description: "Take a tag off a contact and off the other contacts of the same person, as the console does,\nalso when the contact itself no longer has it, so a retry finishes a removal that failed halfway.\nThe answer is the contact's own tags. The contact's `updated_at` does not move."
      tags:
        - "Contacts"
      security:
        - publicApiKey: []
      parameters:
        - name: idempotency-key
          in: header
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 255
        - name: contactId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: tagId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/removeContactTagHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `contacts:write` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "No such contact or tag in the account (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '409':
          description: "A request with this Idempotency-Key is still running (`idempotency_in_progress`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '422':
          description: "This Idempotency-Key was used with another request (`idempotency_key_reused`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its write requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/contacts/{contactId}/custom-fields:
    patch:
      operationId: setContactCustomFields
      summary: "Set a contact's custom field values"
      description: "Set some of a contact's custom field values. Only the fields given change, and the request is\nchecked whole before anything is written: one refused value writes none. The contact's\n`updated_at` does not move."
      tags:
        - "Contacts"
      security:
        - publicApiKey: []
      parameters:
        - name: idempotency-key
          in: header
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 255
        - name: contactId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/setContactCustomFieldsHandlerRequest'
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/setContactCustomFieldsHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `contacts:write` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "No such contact in the account (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '409':
          description: "A request with this Idempotency-Key is still running (`idempotency_in_progress`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '422':
          description: "A field that does not exist (`custom_field_not_found`), a value its field refuses\n(`invalid_custom_field_value`), or an Idempotency-Key reused with another request\n(`idempotency_key_reused`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its write requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/contacts/{contactId}/custom-fields/{fieldId}:
    delete:
      operationId: clearContactCustomField
      summary: "Clear a contact's custom field value"
      description: "Clear one custom field value of a contact, and of the other contacts of the same person, as the\nconsole does, also when the contact itself no longer has one, so a retry finishes a clear that\nfailed halfway. The answer is the contact's own values. The contact's `updated_at` does not move."
      tags:
        - "Contacts"
      security:
        - publicApiKey: []
      parameters:
        - name: idempotency-key
          in: header
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 255
        - name: contactId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: fieldId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/clearContactCustomFieldHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `contacts:write` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "No such contact or custom field in the account (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '409':
          description: "A request with this Idempotency-Key is still running (`idempotency_in_progress`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '422':
          description: "This Idempotency-Key was used with another request (`idempotency_key_reused`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its write requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/tags:
    get:
      operationId: listTags
      summary: "List tags"
      description: "The account's tags, oldest first: a tag created while paging lands at the end."
      tags:
        - "Tags"
      security:
        - publicApiKey: []
      parameters:
        - name: cursor
          in: query
          description: "The `next_cursor` of the previous page. Opaque: its content may change at any time."
          required: false
          schema:
            type: string
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/listTagsHandler'
        '400':
          description: "The cursor was not issued by this list (`invalid_cursor`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `contacts:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
    post:
      operationId: createTag
      summary: "Create a tag"
      tags:
        - "Tags"
      security:
        - publicApiKey: []
      parameters:
        - name: idempotency-key
          in: header
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 255
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/createTagHandlerRequest'
      responses:
        '201':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/createTagHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `contacts:write` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '409':
          description: "An active tag already has this name, in any case (`tag_already_exists`, with its\n`tag_id`), or a request with this Idempotency-Key is still running (`idempotency_in_progress`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '422':
          description: "A blank name (`invalid_name`), or an Idempotency-Key reused with another request\n(`idempotency_key_reused`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its write requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/tags/{tagId}:
    get:
      operationId: readTag
      summary: "Read a tag"
      description: "One tag of the account."
      tags:
        - "Tags"
      security:
        - publicApiKey: []
      parameters:
        - name: tagId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/readTagHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `contacts:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "No such tag in the account (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
    patch:
      operationId: updateTag
      summary: "Rename a tag"
      description: "Rename a tag. The contacts that have it keep it, under the new name. A tag that workflows of the\naccount name is not renamed, not even in another case: their tag conditions compare it exactly."
      tags:
        - "Tags"
      security:
        - publicApiKey: []
      parameters:
        - name: idempotency-key
          in: header
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 255
        - name: tagId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/updateTagHandlerRequest'
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/updateTagHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `contacts:write` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "No such tag in the account (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '409':
          description: "Workflows of the account name the tag and the name changes (`tag_in_use`, with\n`workflow_ids` and `workflow_count`), another active tag already has this name, in any case\n(`tag_already_exists`, with its `tag_id`), or a request with this Idempotency-Key is still running\n(`idempotency_in_progress`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '422':
          description: "A blank name (`invalid_name`), or an Idempotency-Key reused with another request\n(`idempotency_key_reused`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its write requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
    delete:
      operationId: deleteTag
      summary: "Delete a tag"
      description: "Delete a tag and take it off every contact that has it, as the console does: the contacts'\nhistory does not record it. A tag that workflows of the account name is not deleted."
      tags:
        - "Tags"
      security:
        - publicApiKey: []
      parameters:
        - name: idempotency-key
          in: header
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 255
        - name: tagId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `contacts:write` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "No such tag in the account (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '409':
          description: "Workflows of the account name the tag (`tag_in_use`, with `workflow_ids` and\n`workflow_count`), or a request with this Idempotency-Key is still running\n(`idempotency_in_progress`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '422':
          description: "An Idempotency-Key reused with another request (`idempotency_key_reused`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its write requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/tags/{tagId}/contacts:
    get:
      operationId: listTagContacts
      summary: "List the contacts with a tag"
      description: "The contacts holding a tag, in the order they got it (`tagged_at`, then the contact's `id`): with\n`tagged_since`, who got the tag since a given moment. A contact that loses the tag and gets it\nagain moves to the end."
      tags:
        - "Tags"
      security:
        - publicApiKey: []
      parameters:
        - name: tagId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: cursor
          in: query
          description: "The `next_cursor` of the previous page. Opaque: its content may change at any time."
          required: false
          schema:
            type: string
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
        - name: tagged_since
          in: query
          description: "Only contacts that got the tag at or after this moment."
          required: false
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/listTagContactsHandler'
        '400':
          description: "The cursor was not issued by this list (`invalid_cursor`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `contacts:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "No such tag in the account (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/custom-fields:
    get:
      operationId: listCustomFields
      summary: "List custom fields"
      description: "The account's custom fields, by `name`."
      tags:
        - "Custom fields"
      security:
        - publicApiKey: []
      parameters:
        - name: cursor
          in: query
          description: "The `next_cursor` of the previous page. Opaque: its content may change at any time."
          required: false
          schema:
            type: string
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/listCustomFieldsHandler'
        '400':
          description: "The cursor was not issued by this list (`invalid_cursor`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `contacts:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/connections:
    get:
      operationId: listConnections
      summary: "List connections"
      description: "The account's connections (its Instagram accounts and WhatsApp numbers), oldest first: what a\ncontact's `channel.connection_id` points at, and where `POST /v1/contacts` takes its\n`connection_id` from."
      tags:
        - "Connections"
      security:
        - publicApiKey: []
      parameters:
        - name: cursor
          in: query
          description: "The `next_cursor` of the previous page. Opaque: its content may change at any time."
          required: false
          schema:
            type: string
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/listConnectionsHandler'
        '400':
          description: "The cursor was not issued by this list (`invalid_cursor`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `contacts:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/conversations:
    get:
      operationId: listConversations
      summary: "List conversations"
      description: "The account's conversations, one per contact, as its Live Chat lists them: a contact who only\ncommented has none yet."
      tags:
        - "Conversations"
      security:
        - publicApiKey: []
      parameters:
        - name: cursor
          in: query
          description: "The `next_cursor` of the previous page. Opaque: its content may change at any time."
          required: false
          schema:
            type: string
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
        - name: order
          in: query
          description: "By the last message: `desc` (the default) the most recent first, `asc` the oldest first. To\nsync, page `asc` from `last_message_after`: a conversation that moves while you page goes to\nthe end of the series instead of being skipped."
          required: false
          schema:
            enum:
              - "desc"
              - "asc"
        - name: channel
          in: query
          required: false
          schema:
            enum:
              - "instagram"
              - "whatsapp"
        - name: unread
          in: query
          description: "`true`: only conversations with unread messages or marked as unread. `false`: only the rest."
          required: false
          schema:
            type: boolean
        - name: last_message_after
          in: query
          description: "Only conversations whose last message is later than this. Reading a message, its status\nchanging, an edit or a reaction do not move a conversation's last message."
          required: false
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/listConversationsHandler'
        '400':
          description: "The cursor belongs to another order, other filters or no list (`invalid_cursor`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The API key lacks the `conversations:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/conversations/{conversationId}:
    get:
      operationId: readConversation
      summary: "Read a conversation"
      description: "One conversation of the account, including one the list leaves out (a contact who only commented)\nand one with no message yet."
      tags:
        - "Conversations"
      security:
        - publicApiKey: []
      parameters:
        - name: conversationId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/readConversationHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The API key lacks the `conversations:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "The account has no such conversation (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/conversations/{conversationId}/messages:
    get:
      operationId: listConversationMessages
      summary: "List a conversation's messages"
      description: "A conversation's messages of every type the Live Chat shows (direct messages, comments and replies\nto them, story mentions and replies, live comments), each with its `type`."
      tags:
        - "Conversations"
      security:
        - publicApiKey: []
      parameters:
        - name: conversationId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: cursor
          in: query
          description: "The `next_cursor` of the previous page. Opaque: its content may change at any time."
          required: false
          schema:
            type: string
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
        - name: order
          in: query
          description: "`desc` (the default) the newest first, `asc` the oldest first, to import a conversation."
          required: false
          schema:
            enum:
              - "desc"
              - "asc"
        - name: created_after
          in: query
          description: "Only messages created later than this."
          required: false
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/listConversationMessagesHandler'
        '400':
          description: "The cursor belongs to another conversation, another order, another `created_after` or\nno list (`invalid_cursor`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The API key lacks the `conversations:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "The account has no such conversation (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
    post:
      operationId: sendMessage
      summary: "Send a message"
      description: "Send a message in a conversation, on the conversation's own connection: a text, a text with link\nbuttons, a media from `POST /v1/media` (with a caption on WhatsApp), cards, or a WhatsApp template.\nEverything but a template goes out only inside the channel's 24-hour messaging window; a template\nis what reaches a WhatsApp contact past it. Like a reply typed in the console, it marks what the\ncontact sent so far as read and moves the contact's pending inbox cards to in progress. It answers\nthe message as `GET /v1/messages/{id}` reads it.\n\nNeeds an `Idempotency-Key`: a retry with the same key answers the first answer without sending\nagain. When the outcome is unknown the key keeps that answer, so check the conversation before\nsending again with a new key."
      tags:
        - "Conversations"
      security:
        - publicApiKey: []
      parameters:
        - name: idempotency-key
          in: header
          required: true
          schema:
            type: string
            minLength: 1
            maxLength: 255
        - name: conversationId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/sendMessageHandlerRequest'
      responses:
        '201':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/sendMessageHandler'
        '400':
          description: "No `Idempotency-Key` header (the route's schema requires it)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The API key lacks the `messages:send` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "The account has no such conversation (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '409':
          description: "A request with this key is still running (`idempotency_in_progress`), or stopped\nwithout answering (`outcome_unknown`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '422':
          description: "The message holds together on no channel (`invalid_message`), or the conversation's\nchannel cannot carry it (`content_not_supported`), a text is too long where it goes\n(`text_too_long`), a media is not the account's, not uploaded or not taken by the channel\n(`media_not_found`, `media_not_uploaded`, `media_not_supported`), a template is not the account's,\nnot approved, needs other parameters or other variables (`template_not_found`,\n`template_not_approved`, `template_not_supported`, `template_variables_mismatch`), the\nconversation's connection is disconnected (`channel_disconnected`), the contact last wrote more\nthan 24 hours ago (`messaging_window_closed`; on WhatsApp `template_required`), the account blocked\nthe contact from its automations (`contact_blocked`), another app controls the Instagram\nconversation (`conversation_not_owned`), the contact cannot receive messages\n(`recipient_unavailable`), the channel refused the message (`provider_rejected`), or the key was\nused with another request (`idempotency_key_reused`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its sends for the minute (`rate_limited`), or the channel is holding\nthe account's sends (`provider_throttled`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '502':
          description: "The channel did not confirm the send, which may have gone out, or Instagram refused it\nwithout saying why (`outcome_unknown`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '503':
          description: "Instagram failed the send without sending it (`provider_unavailable`), or the\nidempotency store or the media storage is unavailable (`service_unavailable`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/messages/{messageId}:
    get:
      operationId: readMessage
      summary: "Read a message"
      description: "One message of the account. What a sent message's `status` became: a WhatsApp send the channel\naccepted can still fail afterwards, and only then turns `failed`."
      tags:
        - "Conversations"
      security:
        - publicApiKey: []
      parameters:
        - name: messageId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/readMessageHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The API key lacks the `conversations:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "The account has no such message (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/messages/{messageId}/media/{mediaId}:
    get:
      operationId: downloadMessageMedia
      summary: "Download a message's media"
      description: "A media of a message, as a redirect to a download valid for a few minutes. The URL in the message is\nstable; the download it redirects to is not. Only media the message carries is served, so the key\ncannot reach any other file of the account by its id.\n\nReceived media is kept for up to 90 days: download it when you sync."
      tags:
        - "Conversations"
      security:
        - publicApiKey: []
      parameters:
        - name: messageId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: mediaId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '302':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
            location:
              required: true
              schema:
                type: string
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The API key lacks the `conversations:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "The message does not exist, does not carry this media, or the media is still being\nstored right after the message arrived (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '410':
          description: "The media is no longer stored (`media_expired`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '503':
          description: "The media service did not answer; retry (`service_unavailable`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/media:
    post:
      operationId: createMedia
      summary: "Create a media to send"
      description: "Create a media to send: answers where to upload its file, which a send then names by `id` in\n`attachments[].media_id` or a card's `media_id`. The file goes to storage that keeps it while the\naccount exists, so a media can be sent any number of times.\n\n`PUT` the bytes to `upload_url` within 5 minutes, with `Content-Type` set to `content_type`. The\nsize is not checked here: a send refuses a media larger than its channel takes."
      tags:
        - "Conversations"
      security:
        - publicApiKey: []
      parameters:
        - name: idempotency-key
          in: header
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 255
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/createMediaHandlerRequest'
      responses:
        '201':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/createMediaHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The API key lacks the `messages:send` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '409':
          description: "A request with this key is still running (`idempotency_in_progress`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '422':
          description: "The key was used with another request (`idempotency_key_reused`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its write requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '503':
          description: "The media storage did not answer; retry (`service_unavailable`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/workflows:
    get:
      operationId: listWorkflows
      summary: "List workflows"
      description: "The account's workflows, newest first, without their graphs (read one to get it). Templates are\nleft out."
      tags:
        - "Workflows"
      security:
        - publicApiKey: []
      parameters:
        - name: cursor
          in: query
          description: "The `next_cursor` of the previous page. Opaque: its content may change at any time."
          required: false
          schema:
            type: string
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
        - name: status
          in: query
          required: false
          schema:
            enum:
              - "draft"
              - "published"
        - name: channel
          in: query
          required: false
          schema:
            enum:
              - "instagram"
              - "whatsapp"
        - name: connection_id
          in: query
          required: false
          schema:
            type: string
            format: uuid
        - name: trigger_event
          in: query
          required: false
          schema:
            enum:
              - "comment"
              - "live_comment"
              - "story_message"
              - "story_mention"
              - "message"
              - "message_sent"
        - name: folder_id
          in: query
          description: "Only the workflows filed directly in this folder, not in the folders under it."
          required: false
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/listWorkflowsHandler'
        '400':
          description: "The cursor is not one this list issued (`invalid_cursor`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The API key does not have the `workflows:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
    post:
      operationId: createWorkflow
      summary: "Create a workflow"
      description: "Create a workflow as a draft. Nothing runs until it is published."
      tags:
        - "Workflows"
      security:
        - publicApiKey: []
      parameters:
        - name: idempotency-key
          in: header
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 255
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/createWorkflowHandlerRequest'
      responses:
        '201':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
            etag:
              required: true
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/createWorkflowHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The API key does not have the `workflows:write` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '409':
          description: "A request with this `Idempotency-Key` is still running (`idempotency_in_progress`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '422':
          description: "The graph breaks the contract (`invalid_graph`, with every issue in `errors`).\n\nThe channel cannot be bound (`invalid_channel`).\n\nThe trigger does not hold together (`invalid_trigger`).\n\n`folder_id` is not a folder of the account's workflows (`folder_not_found`).\n\nThis `Idempotency-Key` was used with another request (`idempotency_key_reused`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its write requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/workflows/validate:
    post:
      operationId: validateWorkflowDefinition
      summary: "Validate an unsaved workflow"
      description: "Check a workflow that is not saved, without saving it: every error that saving or publishing it\nwould refuse, with the node and the path of each, and the warnings about what would publish but\nmisbehave (a trigger another published workflow already answers, for one). A read: checking in a\nloop does not spend the write allowance."
      tags:
        - "Workflows"
      security:
        - publicApiKey: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/validateWorkflowDefinitionHandlerRequest'
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/validateWorkflowDefinitionHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The API key does not have the `workflows:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/workflows/{workflowId}:
    get:
      operationId: readWorkflow
      summary: "Read a workflow"
      description: "A workflow with its graph (the draft). The `ETag` is its revision, which a change sends back in\n`If-Match`."
      tags:
        - "Workflows"
      security:
        - publicApiKey: []
      parameters:
        - name: workflowId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
            etag:
              required: true
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/readWorkflowHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The API key does not have the `workflows:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "The account has no such workflow (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
    patch:
      operationId: updateWorkflow
      summary: "Update a workflow's draft"
      description: "Change a workflow's draft. What runs does not change until the workflow is published again.\nOnly the fields sent change; a body with none changes nothing."
      tags:
        - "Workflows"
      security:
        - publicApiKey: []
      parameters:
        - name: idempotency-key
          in: header
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 255
        - name: if-match
          in: header
          description: "The revision the change is based on: the `ETag` of the read."
          required: true
          schema:
            type: string
        - name: workflowId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/updateWorkflowHandlerRequest'
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
            etag:
              required: true
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/updateWorkflowHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The API key does not have the `workflows:write` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "The account has no such workflow (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '409':
          description: "Moving a published workflow to another channel (`workflow_published`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '412':
          description: "The workflow changed since the revision in `If-Match` (`version_conflict`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '422':
          description: "The graph breaks the contract (`invalid_graph`, with every issue in `errors`).\n\nThe channel cannot be bound (`invalid_channel`).\n\nThe trigger does not hold together (`invalid_trigger`).\n\n`folder_id` is not a folder of the account's workflows (`folder_not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '428':
          description: "`If-Match` is missing (`precondition_required`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its write requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
    delete:
      operationId: deleteWorkflow
      summary: "Delete a workflow"
      description: "Delete a workflow, and stop every run of it under way. A published workflow is taken down with\nit, so deleting one needs `workflows:publish` as well."
      tags:
        - "Workflows"
      security:
        - publicApiKey: []
      parameters:
        - name: idempotency-key
          in: header
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 255
        - name: if-match
          in: header
          description: "Delete only if the workflow is still at this revision."
          required: false
          schema:
            type: string
        - name: workflowId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The API key does not have the `workflows:write` scope, or the workflow is published\nand it does not have `workflows:publish` (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "The account has no such workflow (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '412':
          description: "The workflow changed since the revision in `If-Match` (`version_conflict`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its write requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/workflows/{workflowId}/validate:
    post:
      operationId: validateWorkflow
      summary: "Validate a workflow's draft"
      description: "Check a workflow's saved draft the way publishing it would: `valid` is true exactly when the\npublish would go through."
      tags:
        - "Workflows"
      security:
        - publicApiKey: []
      parameters:
        - name: workflowId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
            etag:
              required: true
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/validateWorkflowHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The API key does not have the `workflows:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "The account has no such workflow (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/workflows/{workflowId}/publish:
    post:
      operationId: publishWorkflow
      summary: "Publish a workflow"
      description: "Put the draft live: it is kept as a new version and replaces what runs. Runs already under way\ncarry on with the copy they hold. Publishing again without changes is allowed and makes another\nversion."
      tags:
        - "Workflows"
      security:
        - publicApiKey: []
      parameters:
        - name: idempotency-key
          in: header
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 255
        - name: if-match
          in: header
          description: "Publish only if the draft is still at this revision, such as the one `validate` checked."
          required: false
          schema:
            type: string
        - name: workflowId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
            etag:
              required: true
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/publishWorkflowHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The API key does not have the `workflows:publish` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "The account has no such workflow (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '409':
          description: "Sent without `If-Match`, the draft kept changing while it was published\n(`workflow_changed`): read it and try again."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '412':
          description: "The workflow changed since the revision in `If-Match` (`version_conflict`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '422':
          description: "The publish checks refused it (`workflow_invalid`, with the same `errors` `validate`\nanswers).\n\nThe engine refused the compiled workflow (`workflow_not_publishable`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its write requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/workflows/{workflowId}/unpublish:
    post:
      operationId: unpublishWorkflow
      summary: "Unpublish a workflow"
      description: "Take the workflow off: nothing starts it anymore. Runs already under way carry on to their end\nwith the copy they hold. The draft stays as it is. A draft answers the same, unpublished."
      tags:
        - "Workflows"
      security:
        - publicApiKey: []
      parameters:
        - name: idempotency-key
          in: header
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 255
        - name: if-match
          in: header
          description: "Unpublish only if the workflow is still at this revision."
          required: false
          schema:
            type: string
        - name: workflowId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
            etag:
              required: true
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/unpublishWorkflowHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The API key does not have the `workflows:publish` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "The account has no such workflow (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '412':
          description: "The workflow changed since the revision in `If-Match` (`version_conflict`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its write requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/workflows/{workflowId}/versions:
    get:
      operationId: listWorkflowVersions
      summary: "List a workflow's versions"
      description: "The versions of a workflow, newest first: the graph each publish put live (the trigger is not\npart of a version)."
      tags:
        - "Workflows"
      security:
        - publicApiKey: []
      parameters:
        - name: workflowId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: cursor
          in: query
          description: "The `next_cursor` of the previous page. Opaque: its content may change at any time."
          required: false
          schema:
            type: string
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/listWorkflowVersionsHandler'
        '400':
          description: "The cursor is not one this list issued (`invalid_cursor`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The API key does not have the `workflows:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "The account has no such workflow (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/workflows/{workflowId}/versions/{versionId}:
    get:
      operationId: readWorkflowVersion
      summary: "Read a workflow version"
      description: "One version of a workflow, with the graph that publish put live."
      tags:
        - "Workflows"
      security:
        - publicApiKey: []
      parameters:
        - name: workflowId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: versionId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/readWorkflowVersionHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The API key does not have the `workflows:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "The account has no such workflow, or the workflow no such version (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/workflows/{workflowId}/runs:
    get:
      operationId: listWorkflowRuns
      summary: "List a workflow's runs"
      description: "A workflow's runs, newest first by when they started. The run history keeps 90 days, and a run\nshows up once its first stretch is recorded: seconds after it starts on most accounts, longer\nwhen the account's queue is busy."
      tags:
        - "Workflow runs"
      security:
        - publicApiKey: []
      parameters:
        - name: workflowId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: cursor
          in: query
          description: "The `next_cursor` of the previous page. Opaque: its content may change at any time."
          required: false
          schema:
            type: string
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
        - name: contact_id
          in: query
          description: "Only the runs of this contact on the workflow's channel."
          required: false
          schema:
            type: string
            format: uuid
        - name: started_after
          in: query
          description: "Only runs that started at or after this instant."
          required: false
          schema:
            type: string
            format: date-time
        - name: started_before
          in: query
          description: "Only runs that started before this instant."
          required: false
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/listWorkflowRunsHandler'
        '400':
          description: "The cursor is not one this list issued (`invalid_cursor`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The API key does not have the `workflows:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "The account has no such workflow (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
    post:
      operationId: startWorkflowRun
      summary: "Start a workflow for a contact"
      description: "Start a published workflow for a contact, on the workflow's channel, as if it had been triggered\nwith nothing to answer: no comment for a private reply, no message text. The first message goes\nout as a plain message, so a workflow that sends one needs the contact's 24-hour window on that\nchannel open. Needs an `Idempotency-Key`."
      tags:
        - "Workflow runs"
      security:
        - publicApiKey: []
      parameters:
        - name: idempotency-key
          in: header
          required: true
          schema:
            type: string
            minLength: 1
            maxLength: 255
        - name: workflowId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/startWorkflowRunHandlerRequest'
      responses:
        '202':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/startWorkflowRunHandler'
        '400':
          description: "No `Idempotency-Key` header (the route's schema requires it)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The API key does not have the `messages:send` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "The account has no such workflow or contact (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '409':
          description: "Automations are paused for the contact (`contact_automations_paused`).\n\nThe workflow is not published (`workflow_not_published`).\n\nThe contact is in the middle of a run of the workflow (`run_in_progress`).\n\nA request with this `Idempotency-Key` is still running (`idempotency_in_progress`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '422':
          description: "The workflow's channel is not connected (`channel_disconnected`).\n\nThe contact never reached the workflow's channel (`contact_not_on_channel`).\n\nThe contact's 24-hour window on the channel is closed (`messaging_window_closed`).\n\nThe workflow uses an integration that is not connected (`integration_disconnected`).\n\nThis `Idempotency-Key` was used with another request (`idempotency_key_reused`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its send requests for the minute (`rate_limited`).\n\nThe contact reached the hourly runs of this workflow (`run_limit_reached`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '502':
          description: "The engine did not confirm the start (`outcome_unknown`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/workflows/{workflowId}/runs/{runId}:
    get:
      operationId: readWorkflowRun
      summary: "Read a workflow run"
      description: "One run of a workflow, with the steps it went through in order."
      tags:
        - "Workflow runs"
      security:
        - publicApiKey: []
      parameters:
        - name: workflowId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: runId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/readWorkflowRunHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The API key does not have the `workflows:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "The account has no such workflow, or the workflow no such run yet or anymore\n(`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/workflow-graph-schema:
    get:
      operationId: readWorkflowGraphSchema
      summary: "Read the workflow graph catalog"
      description: "The workflow graph catalog as JSON Schema, to check a graph or generate one (a tool's input\nschema, for an agent) before sending it. It is the catalog in force; `validate` also checks what\na schema cannot, such as `next` pointing at nodes that exist and the account's own resources."
      tags:
        - "Workflows"
      security:
        - publicApiKey: []
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/readWorkflowGraphSchemaHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The API key does not have the `workflows:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/folders:
    get:
      operationId: listFolders
      summary: "List folders"
      description: "The account's folders of one type, at every level, oldest first: a folder created while paging\nlands at the end. `parent_id` tells where each one is."
      tags:
        - "Folders"
      security:
        - publicApiKey: []
      parameters:
        - name: cursor
          in: query
          description: "The `next_cursor` of the previous page. Opaque: its content may change at any time."
          required: false
          schema:
            type: string
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
        - name: type
          in: query
          description: "What the folders hold. Left out: workflows."
          required: false
          schema:
            type: string
            enum: ["workflow"]
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/listFoldersHandler'
        '400':
          description: "The cursor was not issued by this list (`invalid_cursor`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `workflows:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
    post:
      operationId: createFolder
      summary: "Create a folder"
      description: "Create a folder. A workflow goes in it through its `folder_id`."
      tags:
        - "Folders"
      security:
        - publicApiKey: []
      parameters:
        - name: idempotency-key
          in: header
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 255
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/createFolderHandlerRequest'
      responses:
        '201':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/createFolderHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `workflows:write` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '409':
          description: "A request with this Idempotency-Key is still running (`idempotency_in_progress`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '422':
          description: "A blank name (`invalid_name`), a `parent_id` that is not a folder of the account of\nthis type (`folder_not_found`, with `field`), or an Idempotency-Key reused with another request\n(`idempotency_key_reused`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its write requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/folders/{folderId}:
    get:
      operationId: readFolder
      summary: "Read a folder"
      description: "One folder of the account."
      tags:
        - "Folders"
      security:
        - publicApiKey: []
      parameters:
        - name: folderId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/readFolderHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `workflows:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "No such folder in the account (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
    patch:
      operationId: updateFolder
      summary: "Rename or move a folder"
      description: "Rename a folder, move it, or both. Only the fields sent change; a body with none changes nothing.\nWhat the folder holds stays in it."
      tags:
        - "Folders"
      security:
        - publicApiKey: []
      parameters:
        - name: idempotency-key
          in: header
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 255
        - name: folderId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/updateFolderHandlerRequest'
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/updateFolderHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `workflows:write` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "No such folder in the account (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '409':
          description: "A request with this Idempotency-Key is still running (`idempotency_in_progress`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '422':
          description: "A blank name (`invalid_name`), a `parent_id` that is not a folder of the account of\nthis type (`folder_not_found`, with `field`), the folder itself or one under it as the parent\n(`invalid_parent`), or an Idempotency-Key reused with another request (`idempotency_key_reused`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its write requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
    delete:
      operationId: deleteFolder
      summary: "Delete a folder"
      description: "Delete a folder and every folder under it, as the console does. What they hold is not deleted:\neach workflow in them moves to the top level (`folder_id` null), which moves its revision and\nleaves what runs as it was."
      tags:
        - "Folders"
      security:
        - publicApiKey: []
      parameters:
        - name: idempotency-key
          in: header
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 255
        - name: folderId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `workflows:write` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "No such folder in the account (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '409':
          description: "A request with this Idempotency-Key is still running (`idempotency_in_progress`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '422':
          description: "An Idempotency-Key reused with another request (`idempotency_key_reused`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its write requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/replies-lists:
    get:
      operationId: listRepliesLists
      summary: "List replies lists"
      description: "The account's replies lists, oldest first, without their replies (read one to get them): a list\ncreated while paging lands at the end."
      tags:
        - "Replies lists"
      security:
        - publicApiKey: []
      parameters:
        - name: cursor
          in: query
          description: "The `next_cursor` of the previous page. Opaque: its content may change at any time."
          required: false
          schema:
            type: string
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/listRepliesListsHandler'
        '400':
          description: "The cursor was not issued by this list (`invalid_cursor`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `workflows:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
    post:
      operationId: createRepliesList
      summary: "Create a replies list"
      description: "Create a replies list: the public replies an Instagram workflow posts under the comments that\nstart it, one picked at random for each, once its trigger names the list\n(`trigger.replies_list_id`)."
      tags:
        - "Replies lists"
      security:
        - publicApiKey: []
      parameters:
        - name: idempotency-key
          in: header
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 255
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/createRepliesListHandlerRequest'
      responses:
        '201':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/createRepliesListHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `workflows:write` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '409':
          description: "A live list of the account already has this name, in any case\n(`replies_list_already_exists`, with its `replies_list_id`), or a request with this\nIdempotency-Key is still running (`idempotency_in_progress`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '422':
          description: "A blank name (`invalid_name`), a blank reply (`invalid_reply`, with its `index`), or\nan Idempotency-Key reused with another request (`idempotency_key_reused`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its write requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '503':
          description: "The automations engine did not take the replies, and nothing was saved: retry\n(`service_unavailable`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/replies-lists/{repliesListId}:
    get:
      operationId: readRepliesList
      summary: "Read a replies list"
      description: "One replies list of the account, with its replies."
      tags:
        - "Replies lists"
      security:
        - publicApiKey: []
      parameters:
        - name: repliesListId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/readRepliesListHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `workflows:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "No such list in the account (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
    patch:
      operationId: updateRepliesList
      summary: "Update a replies list"
      description: "Rename a replies list, replace its replies, or both. Only the fields sent change; a body with none\nchanges nothing. New replies take effect at once: the published workflows that answer with the\nlist post them from the next comment, with no publish."
      tags:
        - "Replies lists"
      security:
        - publicApiKey: []
      parameters:
        - name: idempotency-key
          in: header
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 255
        - name: repliesListId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/updateRepliesListHandlerRequest'
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/updateRepliesListHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `workflows:write` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "No such list in the account (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '409':
          description: "Another live list of the account already has this name, in any case\n(`replies_list_already_exists`, with its `replies_list_id`), or a request with this\nIdempotency-Key is still running (`idempotency_in_progress`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '422':
          description: "A blank name (`invalid_name`), a blank reply (`invalid_reply`, with its `index`), or\nan Idempotency-Key reused with another request (`idempotency_key_reused`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its write requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '503':
          description: "The automations engine did not take the replies, and nothing was saved: retry\n(`service_unavailable`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
    delete:
      operationId: deleteRepliesList
      summary: "Delete a replies list"
      description: "Delete a replies list. A list that workflows of the account answer comments with, as a draft or\npublished, is not deleted: take it out of their triggers first."
      tags:
        - "Replies lists"
      security:
        - publicApiKey: []
      parameters:
        - name: idempotency-key
          in: header
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 255
        - name: repliesListId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `workflows:write` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "No such list in the account (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '409':
          description: "Workflows of the account answer with the list (`replies_list_in_use`, with\n`workflow_ids` and `workflow_count`), or a request with this Idempotency-Key is still running\n(`idempotency_in_progress`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '422':
          description: "An Idempotency-Key reused with another request (`idempotency_key_reused`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its write requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '503':
          description: "The automations engine did not answer, and nothing was deleted: retry\n(`service_unavailable`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/webhooks:
    get:
      operationId: listWebhooks
      summary: "List webhook endpoints"
      description: "The account's webhook endpoints, newest first. An account holds at most 10, so the list is always\none page."
      tags:
        - "Webhooks"
      security:
        - publicApiKey: []
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/listWebhooksHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `webhooks:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
    post:
      operationId: createWebhook
      summary: "Register a webhook endpoint"
      description: "Register a webhook endpoint, enabled, and answer it with its signing secret. Every event of the\ngiven types that happens in the account from now on is posted to it.\n\nThe registration is recorded in the account's audit log with the key and its holder: it is the\naccount's instruction to send its data to that URL."
      tags:
        - "Webhooks"
      security:
        - publicApiKey: []
      parameters:
        - name: idempotency-key
          in: header
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 255
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/createWebhookHandlerRequest'
      responses:
        '201':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/createWebhookHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `webhooks:write` scope, or the read scope of one of the types\n(`insufficient_scope`, with `required_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '409':
          description: "The account holds the most endpoints allowed (`webhook_limit_reached`, with `limit`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '422':
          description: "The URL is not one Gaio posts to (`invalid_webhook_url`, with `reason`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its write requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/webhooks/{webhookId}:
    get:
      operationId: readWebhook
      summary: "Read a webhook endpoint"
      description: "One webhook endpoint of the account, without its secret."
      tags:
        - "Webhooks"
      security:
        - publicApiKey: []
      parameters:
        - name: webhookId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/readWebhookHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `webhooks:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "The account has no such endpoint (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
    patch:
      operationId: updateWebhook
      summary: "Update a webhook endpoint"
      description: "Change a webhook endpoint: where it points, what it receives, or whether it receives at all."
      tags:
        - "Webhooks"
      security:
        - publicApiKey: []
      parameters:
        - name: idempotency-key
          in: header
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 255
        - name: webhookId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/updateWebhookHandlerRequest'
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/updateWebhookHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `webhooks:write` scope, or the read scope of one of the types\n(`insufficient_scope`, with `required_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "The account has no such endpoint (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '422':
          description: "The URL is not one Gaio posts to (`invalid_webhook_url`, with `reason`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its write requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
    delete:
      operationId: deleteWebhook
      summary: "Delete a webhook endpoint"
      description: "Delete a webhook endpoint. It stops receiving at once, and what it still had to receive is given\nup on."
      tags:
        - "Webhooks"
      security:
        - publicApiKey: []
      parameters:
        - name: idempotency-key
          in: header
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 255
        - name: webhookId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `webhooks:write` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "The account has no such endpoint (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its write requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/webhooks/{webhookId}/rotate-secret:
    post:
      operationId: rotateWebhookSecret
      summary: "Rotate a webhook endpoint's secret"
      description: "Replace a webhook endpoint's signing secret and answer the new one. For a day the previous secret\nsigns beside it (`previous_secret_expires_at`), so the receiver can switch without refusing a\ndelivery. Rotating again in that day stops the oldest at once."
      tags:
        - "Webhooks"
      security:
        - publicApiKey: []
      parameters:
        - name: idempotency-key
          in: header
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 255
        - name: webhookId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/rotateWebhookSecretHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `webhooks:write` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "The account has no such endpoint (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its write requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/webhooks/{webhookId}/test:
    post:
      operationId: testWebhook
      summary: "Send a test event to a webhook endpoint"
      description: "Post a signed `webhook.test` event to an endpoint, enabled or not, and answer how it took it. A\nfailure is an answer too (`delivered: false`, with `error`): nothing is stored or retried.\n\nIt reaches outside the account, so it counts against the sends of the minute."
      tags:
        - "Webhooks"
      security:
        - publicApiKey: []
      parameters:
        - name: webhookId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/testWebhookHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `webhooks:write` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "The account has no such endpoint (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its sends for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/webhooks/{webhookId}/deliveries:
    get:
      operationId: listWebhookDeliveries
      summary: "List a webhook endpoint's deliveries"
      description: "A webhook endpoint's deliveries, newest first. Deliveries are kept 7 days after their event."
      tags:
        - "Webhooks"
      security:
        - publicApiKey: []
      parameters:
        - name: webhookId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: cursor
          in: query
          description: "The `next_cursor` of the previous page. Opaque: its content may change at any time."
          required: false
          schema:
            type: string
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
        - name: status
          in: query
          description: "`pending` also takes the deliveries in an attempt right now."
          required: false
          schema:
            enum:
              - "pending"
              - "succeeded"
              - "failed"
      responses:
        '200':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/listWebhookDeliveriesHandler'
        '400':
          description: "The cursor was not issued by this list (`invalid_cursor`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `webhooks:read` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "The account has no such endpoint (`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its read requests for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
  /v1/webhooks/{webhookId}/deliveries/{deliveryId}/retry:
    post:
      operationId: retryWebhookDelivery
      summary: "Retry a webhook delivery"
      description: "Put a delivery that ended back in line now: one that failed, or one that succeeded and the\nendpoint needs again. It posts the same event, with the same `id`. When that attempt fails, the\nretries go on from where the delivery left them. A delivery still pending is answered as it is.\n\nRetrying the same delivery twice is safe: the second finds it already in line."
      tags:
        - "Webhooks"
      security:
        - publicApiKey: []
      parameters:
        - name: webhookId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: deliveryId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '202':
          description: "Successful response."
          headers:
            ratelimit-limit:
              required: true
              schema:
                type: string
            ratelimit-remaining:
              required: true
              schema:
                type: string
            ratelimit-reset:
              required: true
              schema:
                type: string
            cache-control:
              required: true
              schema:
                type: string
                enum: ["no-store"]
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/retryWebhookDeliveryHandler'
        '400':
          description: "Bad Request"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '401':
          description: "Unauthorized"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
        '403':
          description: "The key lacks the `webhooks:write` scope (`insufficient_scope`)."
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/HttpError'
                  - $ref: '#/components/schemas/GatewayError'
        '404':
          description: "The endpoint has no such delivery, or its event is past the 7 days kept\n(`not_found`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '409':
          description: "The endpoint is disabled (`webhook_disabled`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'
        '429':
          description: "The account used its sends for the minute (`rate_limited`)."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HttpError'

components:
  securitySchemes:
    publicApiKey:
      type: http
      scheme: bearer

  schemas:
    readMeHandler:
      type: object
      additionalProperties: false
      properties:
        account:
          type: object
          additionalProperties: false
          properties:
            id:
              type: string
            name:
              type: [string, 'null']
            alias:
              type: [string, 'null']
          required:
            - id
            - name
            - alias
        api_key:
          type: object
          additionalProperties: false
          properties:
            id:
              type: string
            name:
              type: string
            scopes:
              type: array
              items:
                enum:
                  - "contacts:read"
                  - "contacts:write"
                  - "conversations:read"
                  - "messages:send"
                  - "workflows:read"
                  - "workflows:write"
                  - "workflows:publish"
                  - "webhooks:read"
                  - "webhooks:write"
            expires_at:
              type: string
          required:
            - id
            - name
            - scopes
            - expires_at
      required:
        - account
        - api_key
    listContactsHandler:
      type: object
      additionalProperties: false
      properties:
        data:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
              channel:
                type: object
                additionalProperties: false
                properties:
                  type:
                    enum:
                      - "instagram"
                      - "whatsapp"
                  connection_id:
                    type: [string, 'null']
                required:
                  - type
                  - connection_id
              instagram:
                type: [object, 'null']
                description: "Present on an Instagram contact. `id` is scoped to the connection the contact came in through."
                additionalProperties: false
                properties:
                  id:
                    type: string
                  username:
                    type: [string, 'null']
                required:
                  - id
                  - username
              whatsapp:
                type: [object, 'null']
                description: "Present on a WhatsApp contact. `phone` is in E.164 (`+5511987654321`)."
                additionalProperties: false
                properties:
                  phone:
                    type: [string, 'null']
                required:
                  - phone
              name:
                type: [string, 'null']
                description: "The name the channel reports, refreshed by its next message."
              person_id:
                type: [string, 'null']
                description: "Contacts of the same person share it."
              tags:
                type: array
                description: "The contact's own tags."
                items:
                  type: object
                  additionalProperties: false
                  properties:
                    id:
                      type: string
                    name:
                      type: string
                  required:
                    - id
                    - name
              custom_fields:
                type: array
                description: "The contact's own custom field values; a field without a value is absent."
                items:
                  type: object
                  additionalProperties: false
                  properties:
                    field_id:
                      type: string
                    name:
                      type: string
                      description: "The field's stable key, the one imports and message variables use."
                    type:
                      enum:
                        - "text"
                        - "number"
                        - "dropdown"
                    value:
                      anyOf:
                      - type: string
                      - type: number
                  required:
                    - field_id
                    - name
                    - type
                    - value
              last_interaction_at:
                type: [string, 'null']
                description: "The contact's last inbound interaction, on any connection."
              created_at:
                type: string
              updated_at:
                type: string
                description: "The contact's last activity: a message, or an edit in the console. A change made through this\nAPI does not move it."
            required:
              - id
              - channel
              - instagram
              - whatsapp
              - name
              - person_id
              - tags
              - custom_fields
              - last_interaction_at
              - created_at
              - updated_at
        next_cursor:
          type: [string, 'null']
      required:
        - data
        - next_cursor
    readContactHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        channel:
          type: object
          additionalProperties: false
          properties:
            type:
              enum:
                - "instagram"
                - "whatsapp"
            connection_id:
              type: [string, 'null']
          required:
            - type
            - connection_id
        instagram:
          type: [object, 'null']
          description: "Present on an Instagram contact. `id` is scoped to the connection the contact came in through."
          additionalProperties: false
          properties:
            id:
              type: string
            username:
              type: [string, 'null']
          required:
            - id
            - username
        whatsapp:
          type: [object, 'null']
          description: "Present on a WhatsApp contact. `phone` is in E.164 (`+5511987654321`)."
          additionalProperties: false
          properties:
            phone:
              type: [string, 'null']
          required:
            - phone
        name:
          type: [string, 'null']
          description: "The name the channel reports, refreshed by its next message."
        person_id:
          type: [string, 'null']
          description: "Contacts of the same person share it."
        tags:
          type: array
          description: "The contact's own tags."
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
              name:
                type: string
            required:
              - id
              - name
        custom_fields:
          type: array
          description: "The contact's own custom field values; a field without a value is absent."
          items:
            type: object
            additionalProperties: false
            properties:
              field_id:
                type: string
              name:
                type: string
                description: "The field's stable key, the one imports and message variables use."
              type:
                enum:
                  - "text"
                  - "number"
                  - "dropdown"
              value:
                anyOf:
                - type: string
                - type: number
            required:
              - field_id
              - name
              - type
              - value
        last_interaction_at:
          type: [string, 'null']
          description: "The contact's last inbound interaction, on any connection."
        created_at:
          type: string
        updated_at:
          type: string
          description: "The contact's last activity: a message, or an edit in the console. A change made through this\nAPI does not move it."
      required:
        - id
        - channel
        - instagram
        - whatsapp
        - name
        - person_id
        - tags
        - custom_fields
        - last_interaction_at
        - created_at
        - updated_at
    createContactHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        channel:
          type: object
          additionalProperties: false
          properties:
            type:
              enum:
                - "instagram"
                - "whatsapp"
            connection_id:
              type: [string, 'null']
          required:
            - type
            - connection_id
        instagram:
          type: [object, 'null']
          description: "Present on an Instagram contact. `id` is scoped to the connection the contact came in through."
          additionalProperties: false
          properties:
            id:
              type: string
            username:
              type: [string, 'null']
          required:
            - id
            - username
        whatsapp:
          type: [object, 'null']
          description: "Present on a WhatsApp contact. `phone` is in E.164 (`+5511987654321`)."
          additionalProperties: false
          properties:
            phone:
              type: [string, 'null']
          required:
            - phone
        name:
          type: [string, 'null']
          description: "The name the channel reports, refreshed by its next message."
        person_id:
          type: [string, 'null']
          description: "Contacts of the same person share it."
        tags:
          type: array
          description: "The contact's own tags."
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
              name:
                type: string
            required:
              - id
              - name
        custom_fields:
          type: array
          description: "The contact's own custom field values; a field without a value is absent."
          items:
            type: object
            additionalProperties: false
            properties:
              field_id:
                type: string
              name:
                type: string
                description: "The field's stable key, the one imports and message variables use."
              type:
                enum:
                  - "text"
                  - "number"
                  - "dropdown"
              value:
                anyOf:
                - type: string
                - type: number
            required:
              - field_id
              - name
              - type
              - value
        last_interaction_at:
          type: [string, 'null']
          description: "The contact's last inbound interaction, on any connection."
        created_at:
          type: string
        updated_at:
          type: string
          description: "The contact's last activity: a message, or an edit in the console. A change made through this\nAPI does not move it."
      required:
        - id
        - channel
        - instagram
        - whatsapp
        - name
        - person_id
        - tags
        - custom_fields
        - last_interaction_at
        - created_at
        - updated_at
    addContactTagHandler:
      type: object
      additionalProperties: false
      properties:
        contact_id:
          type: string
        tags:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
              name:
                type: string
            required:
              - id
              - name
      required:
        - contact_id
        - tags
    removeContactTagHandler:
      type: object
      additionalProperties: false
      properties:
        contact_id:
          type: string
        tags:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
              name:
                type: string
            required:
              - id
              - name
      required:
        - contact_id
        - tags
    setContactCustomFieldsHandler:
      type: object
      additionalProperties: false
      properties:
        contact_id:
          type: string
        custom_fields:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              field_id:
                type: string
              name:
                type: string
                description: "The field's stable key, the one imports and message variables use."
              type:
                enum:
                  - "text"
                  - "number"
                  - "dropdown"
              value:
                anyOf:
                - type: string
                - type: number
            required:
              - field_id
              - name
              - type
              - value
      required:
        - contact_id
        - custom_fields
    clearContactCustomFieldHandler:
      type: object
      additionalProperties: false
      properties:
        contact_id:
          type: string
        custom_fields:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              field_id:
                type: string
              name:
                type: string
                description: "The field's stable key, the one imports and message variables use."
              type:
                enum:
                  - "text"
                  - "number"
                  - "dropdown"
              value:
                anyOf:
                - type: string
                - type: number
            required:
              - field_id
              - name
              - type
              - value
      required:
        - contact_id
        - custom_fields
    listTagsHandler:
      type: object
      additionalProperties: false
      properties:
        data:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
              name:
                type: string
              description:
                type: [string, 'null']
              created_at:
                type: string
              updated_at:
                type: string
            required:
              - id
              - name
              - description
              - created_at
              - updated_at
        next_cursor:
          type: [string, 'null']
      required:
        - data
        - next_cursor
    readTagHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        name:
          type: string
        description:
          type: [string, 'null']
        created_at:
          type: string
        updated_at:
          type: string
      required:
        - id
        - name
        - description
        - created_at
        - updated_at
    createTagHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        name:
          type: string
        description:
          type: [string, 'null']
        created_at:
          type: string
        updated_at:
          type: string
      required:
        - id
        - name
        - description
        - created_at
        - updated_at
    updateTagHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        name:
          type: string
        description:
          type: [string, 'null']
        created_at:
          type: string
        updated_at:
          type: string
      required:
        - id
        - name
        - description
        - created_at
        - updated_at
    listTagContactsHandler:
      type: object
      additionalProperties: false
      properties:
        data:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              tagged_at:
                type: string
                description: "When the contact got the tag. Adding a tag it already has keeps the first moment."
              contact:
                type: object
                additionalProperties: false
                properties:
                  id:
                    type: string
                  channel:
                    type: object
                    additionalProperties: false
                    properties:
                      type:
                        enum:
                          - "instagram"
                          - "whatsapp"
                      connection_id:
                        type: [string, 'null']
                    required:
                      - type
                      - connection_id
                  instagram:
                    type: [object, 'null']
                    description: "Present on an Instagram contact. `id` is scoped to the connection the contact came in through."
                    additionalProperties: false
                    properties:
                      id:
                        type: string
                      username:
                        type: [string, 'null']
                    required:
                      - id
                      - username
                  whatsapp:
                    type: [object, 'null']
                    description: "Present on a WhatsApp contact. `phone` is in E.164 (`+5511987654321`)."
                    additionalProperties: false
                    properties:
                      phone:
                        type: [string, 'null']
                    required:
                      - phone
                  name:
                    type: [string, 'null']
                    description: "The name the channel reports, refreshed by its next message."
                  person_id:
                    type: [string, 'null']
                    description: "Contacts of the same person share it."
                  tags:
                    type: array
                    description: "The contact's own tags."
                    items:
                      type: object
                      additionalProperties: false
                      properties:
                        id:
                          type: string
                        name:
                          type: string
                      required:
                        - id
                        - name
                  custom_fields:
                    type: array
                    description: "The contact's own custom field values; a field without a value is absent."
                    items:
                      type: object
                      additionalProperties: false
                      properties:
                        field_id:
                          type: string
                        name:
                          type: string
                          description: "The field's stable key, the one imports and message variables use."
                        type:
                          enum:
                            - "text"
                            - "number"
                            - "dropdown"
                        value:
                          anyOf:
                          - type: string
                          - type: number
                      required:
                        - field_id
                        - name
                        - type
                        - value
                  last_interaction_at:
                    type: [string, 'null']
                    description: "The contact's last inbound interaction, on any connection."
                  created_at:
                    type: string
                  updated_at:
                    type: string
                    description: "The contact's last activity: a message, or an edit in the console. A change made through this\nAPI does not move it."
                required:
                  - id
                  - channel
                  - instagram
                  - whatsapp
                  - name
                  - person_id
                  - tags
                  - custom_fields
                  - last_interaction_at
                  - created_at
                  - updated_at
            required:
              - tagged_at
              - contact
        next_cursor:
          type: [string, 'null']
      required:
        - data
        - next_cursor
    listCustomFieldsHandler:
      type: object
      additionalProperties: false
      properties:
        data:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
              name:
                type: string
                description: "The field's stable key, the one imports and message variables use. It never changes."
              label:
                type: string
              description:
                type: [string, 'null']
              type:
                enum:
                  - "text"
                  - "number"
                  - "dropdown"
              options:
                type: [array, 'null']
                description: "A dropdown's options; `null` for the other types."
                items:
                  type: object
                  additionalProperties: false
                  properties:
                    label:
                      type: string
                    value:
                      type: string
                  required:
                    - label
                    - value
              created_at:
                type: string
              updated_at:
                type: string
            required:
              - id
              - name
              - label
              - description
              - type
              - options
              - created_at
              - updated_at
        next_cursor:
          type: [string, 'null']
      required:
        - data
        - next_cursor
    listConnectionsHandler:
      type: object
      additionalProperties: false
      properties:
        data:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
              type:
                enum:
                  - "instagram"
                  - "whatsapp"
              handle:
                type: [string, 'null']
                description: "The Instagram username, or the WhatsApp number as Meta displays it."
              status:
                enum:
                  - "connected"
                  - "disconnected"
              disconnect_reason:
                type: [string, 'null']
                enum:
                  - "authorization_lost"
                  - "disconnected_by_user"
                  - "account_suspended"
                  - "activation_expired"
                  - "setup_incomplete"
                  - null
            required:
              - id
              - type
              - handle
              - status
              - disconnect_reason
        next_cursor:
          type: [string, 'null']
      required:
        - data
        - next_cursor
    listConversationsHandler:
      type: object
      additionalProperties: false
      properties:
        data:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
              channel:
                type: object
                additionalProperties: false
                properties:
                  type:
                    enum:
                      - "instagram"
                      - "whatsapp"
                  connection_id:
                    type: [string, 'null']
                    description: "The account's connection the conversation runs on: an Instagram account or a WhatsApp number.\nNull only for a conversation stored before connections were tracked."
                required:
                  - type
                  - connection_id
              contact:
                type: object
                additionalProperties: false
                properties:
                  id:
                    type: string
                  name:
                    type: [string, 'null']
                  instagram:
                    type: [object, 'null']
                    description: "Present on an Instagram contact. `id` is scoped to the connection the contact came in through;\n`username` is the handle, without the `@`."
                    additionalProperties: false
                    properties:
                      id:
                        type: string
                      username:
                        type: [string, 'null']
                    required:
                      - id
                      - username
                  whatsapp:
                    type: [object, 'null']
                    description: "Present on a WhatsApp contact. `phone` is in E.164 (`+5511987654321`)."
                    additionalProperties: false
                    properties:
                      phone:
                        type: [string, 'null']
                    required:
                      - phone
                required:
                  - id
                  - name
                  - instagram
                  - whatsapp
              person_id:
                type: [string, 'null']
              last_message:
                type: [object, 'null']
                additionalProperties: false
                properties:
                  id:
                    type: string
                  type:
                    enum:
                      - "message"
                      - "comment"
                      - "comment_reply"
                      - "comment_dm_reply"
                      - "story_mention"
                      - "story_message"
                      - "live_comment"
                  direction:
                    enum:
                      - "inbound"
                      - "outbound"
                  sender:
                    type: object
                    additionalProperties: false
                    properties:
                      type:
                        enum:
                          - "contact"
                          - "user"
                          - "workflow"
                          - "api"
                          - "unattributed"
                      user_id:
                        type: [string, 'null']
                        description: "The team member, when `type` is `user`."
                      name:
                        type: [string, 'null']
                        description: "The team member's name, when `type` is `user`."
                    required:
                      - type
                      - user_id
                      - name
                  text:
                    type: [string, 'null']
                  created_at:
                    type: string
                required:
                  - id
                  - type
                  - direction
                  - sender
                  - text
                  - created_at
              last_message_at:
                type: [string, 'null']
              last_inbound_at:
                type: [string, 'null']
                description: "When the contact last wrote on the conversation's connection: what the window is measured from."
              unread_count:
                type: number
                description: "Inbound messages nobody on the account has read yet."
              is_marked_unread:
                type: boolean
                description: "Someone on the account marked the conversation as unread."
              reply_window:
                type: object
                additionalProperties: false
                properties:
                  state:
                    enum:
                      - "open"
                      - "closed"
                  closes_at:
                    type: [string, 'null']
                    description: "When it closes, while it is open."
                required:
                  - state
                  - closes_at
            required:
              - id
              - channel
              - contact
              - person_id
              - last_message
              - last_message_at
              - last_inbound_at
              - unread_count
              - is_marked_unread
              - reply_window
        next_cursor:
          type: [string, 'null']
      required:
        - data
        - next_cursor
    readConversationHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        channel:
          type: object
          additionalProperties: false
          properties:
            type:
              enum:
                - "instagram"
                - "whatsapp"
            connection_id:
              type: [string, 'null']
              description: "The account's connection the conversation runs on: an Instagram account or a WhatsApp number.\nNull only for a conversation stored before connections were tracked."
          required:
            - type
            - connection_id
        contact:
          type: object
          additionalProperties: false
          properties:
            id:
              type: string
            name:
              type: [string, 'null']
            instagram:
              type: [object, 'null']
              description: "Present on an Instagram contact. `id` is scoped to the connection the contact came in through;\n`username` is the handle, without the `@`."
              additionalProperties: false
              properties:
                id:
                  type: string
                username:
                  type: [string, 'null']
              required:
                - id
                - username
            whatsapp:
              type: [object, 'null']
              description: "Present on a WhatsApp contact. `phone` is in E.164 (`+5511987654321`)."
              additionalProperties: false
              properties:
                phone:
                  type: [string, 'null']
              required:
                - phone
          required:
            - id
            - name
            - instagram
            - whatsapp
        person_id:
          type: [string, 'null']
        last_message:
          type: [object, 'null']
          additionalProperties: false
          properties:
            id:
              type: string
            type:
              enum:
                - "message"
                - "comment"
                - "comment_reply"
                - "comment_dm_reply"
                - "story_mention"
                - "story_message"
                - "live_comment"
            direction:
              enum:
                - "inbound"
                - "outbound"
            sender:
              type: object
              additionalProperties: false
              properties:
                type:
                  enum:
                    - "contact"
                    - "user"
                    - "workflow"
                    - "api"
                    - "unattributed"
                user_id:
                  type: [string, 'null']
                  description: "The team member, when `type` is `user`."
                name:
                  type: [string, 'null']
                  description: "The team member's name, when `type` is `user`."
              required:
                - type
                - user_id
                - name
            text:
              type: [string, 'null']
            created_at:
              type: string
          required:
            - id
            - type
            - direction
            - sender
            - text
            - created_at
        last_message_at:
          type: [string, 'null']
        last_inbound_at:
          type: [string, 'null']
          description: "When the contact last wrote on the conversation's connection: what the window is measured from."
        unread_count:
          type: number
          description: "Inbound messages nobody on the account has read yet."
        is_marked_unread:
          type: boolean
          description: "Someone on the account marked the conversation as unread."
        reply_window:
          type: object
          additionalProperties: false
          properties:
            state:
              enum:
                - "open"
                - "closed"
            closes_at:
              type: [string, 'null']
              description: "When it closes, while it is open."
          required:
            - state
            - closes_at
      required:
        - id
        - channel
        - contact
        - person_id
        - last_message
        - last_message_at
        - last_inbound_at
        - unread_count
        - is_marked_unread
        - reply_window
    listConversationMessagesHandler:
      type: object
      additionalProperties: false
      properties:
        data:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
              conversation_id:
                type: string
              channel:
                type: object
                additionalProperties: false
                properties:
                  type:
                    enum:
                      - "instagram"
                      - "whatsapp"
                  connection_id:
                    type: [string, 'null']
                    description: "The account's connection the conversation runs on: an Instagram account or a WhatsApp number.\nNull only for a conversation stored before connections were tracked."
                required:
                  - type
                  - connection_id
              type:
                enum:
                  - "message"
                  - "comment"
                  - "comment_reply"
                  - "comment_dm_reply"
                  - "story_mention"
                  - "story_message"
                  - "live_comment"
              direction:
                enum:
                  - "inbound"
                  - "outbound"
              sender:
                type: object
                additionalProperties: false
                properties:
                  type:
                    enum:
                      - "contact"
                      - "user"
                      - "workflow"
                      - "api"
                      - "unattributed"
                  user_id:
                    type: [string, 'null']
                    description: "The team member, when `type` is `user`."
                  name:
                    type: [string, 'null']
                    description: "The team member's name, when `type` is `user`."
                required:
                  - type
                  - user_id
                  - name
              text:
                type: [string, 'null']
                description: "Null for a message with no text, and for one the sender removed."
              attachments:
                type: array
                items:
                  type: object
                  additionalProperties: false
                  properties:
                    type:
                      enum:
                        - "image"
                        - "video"
                        - "audio"
                        - "file"
                        - "link"
                        - "cards"
                        - "other"
                    media_id:
                      type: [string, 'null']
                      description: "Image, video, audio or file: the media's id in this message."
                    url:
                      type: [string, 'null']
                      description: "Image, video, audio or file: the API URL that answers with a redirect to a download valid for a\nfew minutes (it takes the same API key). Link: where the link points."
                    caption:
                      type: [string, 'null']
                      description: "Link: its caption."
                    cards:
                      type: [array, 'null']
                      description: "Cards: each card, in order."
                      items:
                        type: object
                        additionalProperties: false
                        properties:
                          title:
                            type: string
                          subtitle:
                            type: [string, 'null']
                          media_id:
                            type: [string, 'null']
                            description: "The card's image, when it has one."
                          media_url:
                            type: [string, 'null']
                            description: "The API URL that answers with the card's image, like an attachment's `url`."
                          buttons:
                            type: array
                            items:
                              type: object
                              additionalProperties: false
                              properties:
                                type:
                                  enum:
                                    - "postback"
                                    - "open_url"
                                title:
                                  type: string
                                url:
                                  type: [string, 'null']
                                  description: "Where an `open_url` button leads."
                                id:
                                  type: [string, 'null']
                                  description: "The id a `reply` button was sent with through the API, which a tap on it answers. Null on every\nother button."
                              required:
                                - type
                                - title
                                - url
                                - id
                        required:
                          - title
                          - subtitle
                          - media_id
                          - media_url
                          - buttons
                  required:
                    - type
                    - media_id
                    - url
                    - caption
                    - cards
              template:
                type: [object, 'null']
                description: "The WhatsApp template the message was sent from."
                additionalProperties: false
                properties:
                  name:
                    type: string
                  language:
                    type: string
                required:
                  - name
                  - language
              reply_to_message_id:
                type: [string, 'null']
                description: "The message this one answers: the comment a reply is under, the message a DM quotes, or the\nmessage a tapped button was on (a `reply` button sent through the API, or any button on\nWhatsApp)."
              button:
                type: [object, 'null']
                description: "The button the contact tapped, when the message is a tap: its label is the `text`."
                additionalProperties: false
                properties:
                  id:
                    type: [string, 'null']
                    description: "The `id` the button was sent with, when its `source` is `api`."
                  title:
                    type: string
                    description: "The button's label, which is also the message's `text`."
                  source:
                    enum:
                      - "api"
                      - "workflow"
                      - "ice_breaker"
                      - "other"
                required:
                  - id
                  - title
                  - source
              post:
                type: [object, 'null']
                description: "The post a comment, comment reply or story message belongs to."
                additionalProperties: false
                properties:
                  id:
                    type: string
                  url:
                    type: [string, 'null']
                required:
                  - id
                  - url
              status:
                enum:
                  - "received"
                  - "pending"
                  - "sent"
                  - "failed"
              is_unsupported:
                type: boolean
                description: "The provider sent something the channel cannot show (an unsupported attachment)."
              is_removed:
                type: boolean
                description: "The sender removed it after it was delivered."
              is_edited:
                type: boolean
                description: "The sender edited it after it was delivered."
              reactions:
                type: array
                description: "The reactions on it now. Instagram only: WhatsApp's do not reach Gaio."
                items:
                  type: object
                  additionalProperties: false
                  properties:
                    emoji:
                      type: string
                    from:
                      enum:
                        - "contact"
                        - "account"
                  required:
                    - emoji
                    - from
              read_at:
                type: [string, 'null']
                description: "Inbound only: when someone on the account read it."
              created_at:
                type: string
            required:
              - id
              - conversation_id
              - channel
              - type
              - direction
              - sender
              - text
              - attachments
              - template
              - reply_to_message_id
              - button
              - post
              - status
              - is_unsupported
              - is_removed
              - is_edited
              - reactions
              - read_at
              - created_at
        next_cursor:
          type: [string, 'null']
      required:
        - data
        - next_cursor
    sendMessageHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        conversation_id:
          type: string
        channel:
          type: object
          additionalProperties: false
          properties:
            type:
              enum:
                - "instagram"
                - "whatsapp"
            connection_id:
              type: [string, 'null']
              description: "The account's connection the conversation runs on: an Instagram account or a WhatsApp number.\nNull only for a conversation stored before connections were tracked."
          required:
            - type
            - connection_id
        type:
          enum:
            - "message"
            - "comment"
            - "comment_reply"
            - "comment_dm_reply"
            - "story_mention"
            - "story_message"
            - "live_comment"
        direction:
          enum:
            - "inbound"
            - "outbound"
        sender:
          type: object
          additionalProperties: false
          properties:
            type:
              enum:
                - "contact"
                - "user"
                - "workflow"
                - "api"
                - "unattributed"
            user_id:
              type: [string, 'null']
              description: "The team member, when `type` is `user`."
            name:
              type: [string, 'null']
              description: "The team member's name, when `type` is `user`."
          required:
            - type
            - user_id
            - name
        text:
          type: [string, 'null']
          description: "Null for a message with no text, and for one the sender removed."
        attachments:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              type:
                enum:
                  - "image"
                  - "video"
                  - "audio"
                  - "file"
                  - "link"
                  - "cards"
                  - "other"
              media_id:
                type: [string, 'null']
                description: "Image, video, audio or file: the media's id in this message."
              url:
                type: [string, 'null']
                description: "Image, video, audio or file: the API URL that answers with a redirect to a download valid for a\nfew minutes (it takes the same API key). Link: where the link points."
              caption:
                type: [string, 'null']
                description: "Link: its caption."
              cards:
                type: [array, 'null']
                description: "Cards: each card, in order."
                items:
                  type: object
                  additionalProperties: false
                  properties:
                    title:
                      type: string
                    subtitle:
                      type: [string, 'null']
                    media_id:
                      type: [string, 'null']
                      description: "The card's image, when it has one."
                    media_url:
                      type: [string, 'null']
                      description: "The API URL that answers with the card's image, like an attachment's `url`."
                    buttons:
                      type: array
                      items:
                        type: object
                        additionalProperties: false
                        properties:
                          type:
                            enum:
                              - "postback"
                              - "open_url"
                          title:
                            type: string
                          url:
                            type: [string, 'null']
                            description: "Where an `open_url` button leads."
                          id:
                            type: [string, 'null']
                            description: "The id a `reply` button was sent with through the API, which a tap on it answers. Null on every\nother button."
                        required:
                          - type
                          - title
                          - url
                          - id
                  required:
                    - title
                    - subtitle
                    - media_id
                    - media_url
                    - buttons
            required:
              - type
              - media_id
              - url
              - caption
              - cards
        template:
          type: [object, 'null']
          description: "The WhatsApp template the message was sent from."
          additionalProperties: false
          properties:
            name:
              type: string
            language:
              type: string
          required:
            - name
            - language
        reply_to_message_id:
          type: [string, 'null']
          description: "The message this one answers: the comment a reply is under, the message a DM quotes, or the\nmessage a tapped button was on (a `reply` button sent through the API, or any button on\nWhatsApp)."
        button:
          type: [object, 'null']
          description: "The button the contact tapped, when the message is a tap: its label is the `text`."
          additionalProperties: false
          properties:
            id:
              type: [string, 'null']
              description: "The `id` the button was sent with, when its `source` is `api`."
            title:
              type: string
              description: "The button's label, which is also the message's `text`."
            source:
              enum:
                - "api"
                - "workflow"
                - "ice_breaker"
                - "other"
          required:
            - id
            - title
            - source
        post:
          type: [object, 'null']
          description: "The post a comment, comment reply or story message belongs to."
          additionalProperties: false
          properties:
            id:
              type: string
            url:
              type: [string, 'null']
          required:
            - id
            - url
        status:
          enum:
            - "received"
            - "pending"
            - "sent"
            - "failed"
        is_unsupported:
          type: boolean
          description: "The provider sent something the channel cannot show (an unsupported attachment)."
        is_removed:
          type: boolean
          description: "The sender removed it after it was delivered."
        is_edited:
          type: boolean
          description: "The sender edited it after it was delivered."
        reactions:
          type: array
          description: "The reactions on it now. Instagram only: WhatsApp's do not reach Gaio."
          items:
            type: object
            additionalProperties: false
            properties:
              emoji:
                type: string
              from:
                enum:
                  - "contact"
                  - "account"
            required:
              - emoji
              - from
        read_at:
          type: [string, 'null']
          description: "Inbound only: when someone on the account read it."
        created_at:
          type: string
      required:
        - id
        - conversation_id
        - channel
        - type
        - direction
        - sender
        - text
        - attachments
        - template
        - reply_to_message_id
        - button
        - post
        - status
        - is_unsupported
        - is_removed
        - is_edited
        - reactions
        - read_at
        - created_at
    readMessageHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        conversation_id:
          type: string
        channel:
          type: object
          additionalProperties: false
          properties:
            type:
              enum:
                - "instagram"
                - "whatsapp"
            connection_id:
              type: [string, 'null']
              description: "The account's connection the conversation runs on: an Instagram account or a WhatsApp number.\nNull only for a conversation stored before connections were tracked."
          required:
            - type
            - connection_id
        type:
          enum:
            - "message"
            - "comment"
            - "comment_reply"
            - "comment_dm_reply"
            - "story_mention"
            - "story_message"
            - "live_comment"
        direction:
          enum:
            - "inbound"
            - "outbound"
        sender:
          type: object
          additionalProperties: false
          properties:
            type:
              enum:
                - "contact"
                - "user"
                - "workflow"
                - "api"
                - "unattributed"
            user_id:
              type: [string, 'null']
              description: "The team member, when `type` is `user`."
            name:
              type: [string, 'null']
              description: "The team member's name, when `type` is `user`."
          required:
            - type
            - user_id
            - name
        text:
          type: [string, 'null']
          description: "Null for a message with no text, and for one the sender removed."
        attachments:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              type:
                enum:
                  - "image"
                  - "video"
                  - "audio"
                  - "file"
                  - "link"
                  - "cards"
                  - "other"
              media_id:
                type: [string, 'null']
                description: "Image, video, audio or file: the media's id in this message."
              url:
                type: [string, 'null']
                description: "Image, video, audio or file: the API URL that answers with a redirect to a download valid for a\nfew minutes (it takes the same API key). Link: where the link points."
              caption:
                type: [string, 'null']
                description: "Link: its caption."
              cards:
                type: [array, 'null']
                description: "Cards: each card, in order."
                items:
                  type: object
                  additionalProperties: false
                  properties:
                    title:
                      type: string
                    subtitle:
                      type: [string, 'null']
                    media_id:
                      type: [string, 'null']
                      description: "The card's image, when it has one."
                    media_url:
                      type: [string, 'null']
                      description: "The API URL that answers with the card's image, like an attachment's `url`."
                    buttons:
                      type: array
                      items:
                        type: object
                        additionalProperties: false
                        properties:
                          type:
                            enum:
                              - "postback"
                              - "open_url"
                          title:
                            type: string
                          url:
                            type: [string, 'null']
                            description: "Where an `open_url` button leads."
                          id:
                            type: [string, 'null']
                            description: "The id a `reply` button was sent with through the API, which a tap on it answers. Null on every\nother button."
                        required:
                          - type
                          - title
                          - url
                          - id
                  required:
                    - title
                    - subtitle
                    - media_id
                    - media_url
                    - buttons
            required:
              - type
              - media_id
              - url
              - caption
              - cards
        template:
          type: [object, 'null']
          description: "The WhatsApp template the message was sent from."
          additionalProperties: false
          properties:
            name:
              type: string
            language:
              type: string
          required:
            - name
            - language
        reply_to_message_id:
          type: [string, 'null']
          description: "The message this one answers: the comment a reply is under, the message a DM quotes, or the\nmessage a tapped button was on (a `reply` button sent through the API, or any button on\nWhatsApp)."
        button:
          type: [object, 'null']
          description: "The button the contact tapped, when the message is a tap: its label is the `text`."
          additionalProperties: false
          properties:
            id:
              type: [string, 'null']
              description: "The `id` the button was sent with, when its `source` is `api`."
            title:
              type: string
              description: "The button's label, which is also the message's `text`."
            source:
              enum:
                - "api"
                - "workflow"
                - "ice_breaker"
                - "other"
          required:
            - id
            - title
            - source
        post:
          type: [object, 'null']
          description: "The post a comment, comment reply or story message belongs to."
          additionalProperties: false
          properties:
            id:
              type: string
            url:
              type: [string, 'null']
          required:
            - id
            - url
        status:
          enum:
            - "received"
            - "pending"
            - "sent"
            - "failed"
        is_unsupported:
          type: boolean
          description: "The provider sent something the channel cannot show (an unsupported attachment)."
        is_removed:
          type: boolean
          description: "The sender removed it after it was delivered."
        is_edited:
          type: boolean
          description: "The sender edited it after it was delivered."
        reactions:
          type: array
          description: "The reactions on it now. Instagram only: WhatsApp's do not reach Gaio."
          items:
            type: object
            additionalProperties: false
            properties:
              emoji:
                type: string
              from:
                enum:
                  - "contact"
                  - "account"
            required:
              - emoji
              - from
        read_at:
          type: [string, 'null']
          description: "Inbound only: when someone on the account read it."
        created_at:
          type: string
      required:
        - id
        - conversation_id
        - channel
        - type
        - direction
        - sender
        - text
        - attachments
        - template
        - reply_to_message_id
        - button
        - post
        - status
        - is_unsupported
        - is_removed
        - is_edited
        - reactions
        - read_at
        - created_at
    createMediaHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          description: "The `media_id` a send names."
        content_type:
          enum:
            - "image/jpeg"
            - "image/png"
            - "image/gif"
            - "image/webp"
            - "video/mp4"
            - "video/ogg"
            - "video/webm"
            - "video/x-msvideo"
            - "video/quicktime"
            - "audio/aac"
            - "audio/mp4"
            - "audio/mpeg"
            - "audio/wav"
            - "audio/x-m4a"
            - "audio/x-wav"
            - "application/pdf"
        upload_url:
          type: string
          description: "Where to `PUT` the file's bytes, with `Content-Type` set to `content_type`."
        upload_expires_at:
          type: string
          description: "When `upload_url` stops taking the upload."
      required:
        - id
        - content_type
        - upload_url
        - upload_expires_at
    listWorkflowsHandler:
      type: object
      additionalProperties: false
      properties:
        data:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
              title:
                type: string
              description:
                type: string
              status:
                enum:
                  - "draft"
                  - "published"
              has_unpublished_changes:
                type: boolean
                description: "Published, and written since: the draft may differ from what runs."
              channel:
                type: object
                additionalProperties: false
                properties:
                  type:
                    enum:
                      - "instagram"
                      - "whatsapp"
                  connection_id:
                    type: [string, 'null']
                    description: "The connection the workflow is bound to. An Instagram workflow stored without one runs on the\naccount's Instagram connection, which is what this answers; null only when there is none."
                required:
                  - type
                  - connection_id
              trigger:
                type: object
                additionalProperties: false
                properties:
                  events:
                    type: array
                    description: "Empty: the workflow only starts through the API, a bulk send or another workflow's start block."
                    items:
                      enum:
                        - "comment"
                        - "live_comment"
                        - "story_message"
                        - "story_mention"
                        - "message"
                        - "message_sent"
                  match:
                    enum:
                      - "any"
                      - "contains"
                      - "equals"
                      - "starts_with"
                  keywords:
                    type: array
                    items:
                      type: string
                  posts:
                    type: [array, 'null']
                    description: "The Instagram posts (`comment`) and stories (`story_message`) the trigger is limited to. Null:\nany of them."
                    items:
                      type: object
                      additionalProperties: false
                      properties:
                        type:
                          enum:
                            - "feed"
                            - "story"
                        id:
                          type: string
                      required:
                        - type
                        - id
                  next_post:
                    type: boolean
                    description: "Comments on the next feed post published after the workflow was created."
                  replies_list_id:
                    type: [string, 'null']
                    description: "The replies list whose replies are posted publicly under the triggering comment, one at random\n(`GET /v1/replies-lists/{repliesListId}`; Instagram only)."
                required:
                  - events
                  - match
                  - keywords
                  - posts
                  - next_post
                  - replies_list_id
              folder_id:
                type: [string, 'null']
                description: "The folder it is filed in (`GET /v1/folders/{folderId}`); null at the top level."
              revision:
                type: number
                description: "Moves on every change to the workflow, except its run count. The `ETag` carries it, and\n`If-Match` takes it back."
              stats:
                type: object
                additionalProperties: false
                properties:
                  total_runs:
                    type: number
                required:
                  - total_runs
              created_at:
                type: string
              published_at:
                type: [string, 'null']
            required:
              - id
              - title
              - description
              - status
              - has_unpublished_changes
              - channel
              - trigger
              - folder_id
              - revision
              - stats
              - created_at
              - published_at
        next_cursor:
          type: [string, 'null']
      required:
        - data
        - next_cursor
    createWorkflowHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        title:
          type: string
        description:
          type: string
        status:
          enum:
            - "draft"
            - "published"
        has_unpublished_changes:
          type: boolean
          description: "Published, and written since: the draft may differ from what runs."
        channel:
          type: object
          additionalProperties: false
          properties:
            type:
              enum:
                - "instagram"
                - "whatsapp"
            connection_id:
              type: [string, 'null']
              description: "The connection the workflow is bound to. An Instagram workflow stored without one runs on the\naccount's Instagram connection, which is what this answers; null only when there is none."
          required:
            - type
            - connection_id
        trigger:
          type: object
          additionalProperties: false
          properties:
            events:
              type: array
              description: "Empty: the workflow only starts through the API, a bulk send or another workflow's start block."
              items:
                enum:
                  - "comment"
                  - "live_comment"
                  - "story_message"
                  - "story_mention"
                  - "message"
                  - "message_sent"
            match:
              enum:
                - "any"
                - "contains"
                - "equals"
                - "starts_with"
            keywords:
              type: array
              items:
                type: string
            posts:
              type: [array, 'null']
              description: "The Instagram posts (`comment`) and stories (`story_message`) the trigger is limited to. Null:\nany of them."
              items:
                type: object
                additionalProperties: false
                properties:
                  type:
                    enum:
                      - "feed"
                      - "story"
                  id:
                    type: string
                required:
                  - type
                  - id
            next_post:
              type: boolean
              description: "Comments on the next feed post published after the workflow was created."
            replies_list_id:
              type: [string, 'null']
              description: "The replies list whose replies are posted publicly under the triggering comment, one at random\n(`GET /v1/replies-lists/{repliesListId}`; Instagram only)."
          required:
            - events
            - match
            - keywords
            - posts
            - next_post
            - replies_list_id
        folder_id:
          type: [string, 'null']
          description: "The folder it is filed in (`GET /v1/folders/{folderId}`); null at the top level."
        revision:
          type: number
          description: "Moves on every change to the workflow, except its run count. The `ETag` carries it, and\n`If-Match` takes it back."
        stats:
          type: object
          additionalProperties: false
          properties:
            total_runs:
              type: number
          required:
            - total_runs
        created_at:
          type: string
        published_at:
          type: [string, 'null']
        graph:
          type: object
          additionalProperties: false
          properties:
            nodes:
              type: object
              description: "The nodes by id, each with its `type`, its `data` and, optionally, its `position` in the editor.\nThe catalog of node types is `GET /v1/workflow-graph-schema`; send back as you got them the node\ntypes and fields you do not know."
              additionalProperties: true
          required:
            - nodes
        published_version_id:
          type: [string, 'null']
          description: "The snapshot of the graph the last publish put live; null for a workflow never published with\none."
      required:
        - id
        - title
        - description
        - status
        - has_unpublished_changes
        - channel
        - trigger
        - folder_id
        - revision
        - stats
        - created_at
        - published_at
        - graph
        - published_version_id
    validateWorkflowDefinitionHandler:
      type: object
      additionalProperties: false
      properties:
        valid:
          type: boolean
          description: "No errors: the workflow can be published as it is."
        errors:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              code:
                type: string
              message:
                type: string
              node_id:
                type: [string, 'null']
                description: "The node it is about, when it is about one."
              path:
                type: [string, 'null']
                description: "Where it is, as a dotted path from the request (`nodes.n1.data.buttons.0.title`, `trigger`,\n`channel`), when it is somewhere."
              workflow_ids:
                type: array
                description: "The workflows it involves: the ones sharing a trigger, or a start block's target."
                items:
                  type: string
              workflows:
                type: array
                description: "The workflows of `workflow_ids` the account has, with their titles."
                items:
                  type: object
                  additionalProperties: false
                  properties:
                    id:
                      type: string
                    title:
                      type: string
                  required:
                    - id
                    - title
              keywords:
                type: array
                description: "The keywords another workflow already answers."
                items:
                  type: string
              connection_id:
                type: string
                description: "The connection a WhatsApp handoff button points at."
            required:
              - code
              - message
              - node_id
              - path
        warnings:
          type: array
          description: "What publishes but probably does not do what was meant."
          items:
            type: object
            additionalProperties: false
            properties:
              code:
                type: string
              message:
                type: string
              node_id:
                type: [string, 'null']
                description: "The node it is about, when it is about one."
              path:
                type: [string, 'null']
                description: "Where it is, as a dotted path from the request (`nodes.n1.data.buttons.0.title`, `trigger`,\n`channel`), when it is somewhere."
              workflow_ids:
                type: array
                description: "The workflows it involves: the ones sharing a trigger, or a start block's target."
                items:
                  type: string
              workflows:
                type: array
                description: "The workflows of `workflow_ids` the account has, with their titles."
                items:
                  type: object
                  additionalProperties: false
                  properties:
                    id:
                      type: string
                    title:
                      type: string
                  required:
                    - id
                    - title
              keywords:
                type: array
                description: "The keywords another workflow already answers."
                items:
                  type: string
              connection_id:
                type: string
                description: "The connection a WhatsApp handoff button points at."
            required:
              - code
              - message
              - node_id
              - path
      required:
        - valid
        - errors
        - warnings
    readWorkflowHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        title:
          type: string
        description:
          type: string
        status:
          enum:
            - "draft"
            - "published"
        has_unpublished_changes:
          type: boolean
          description: "Published, and written since: the draft may differ from what runs."
        channel:
          type: object
          additionalProperties: false
          properties:
            type:
              enum:
                - "instagram"
                - "whatsapp"
            connection_id:
              type: [string, 'null']
              description: "The connection the workflow is bound to. An Instagram workflow stored without one runs on the\naccount's Instagram connection, which is what this answers; null only when there is none."
          required:
            - type
            - connection_id
        trigger:
          type: object
          additionalProperties: false
          properties:
            events:
              type: array
              description: "Empty: the workflow only starts through the API, a bulk send or another workflow's start block."
              items:
                enum:
                  - "comment"
                  - "live_comment"
                  - "story_message"
                  - "story_mention"
                  - "message"
                  - "message_sent"
            match:
              enum:
                - "any"
                - "contains"
                - "equals"
                - "starts_with"
            keywords:
              type: array
              items:
                type: string
            posts:
              type: [array, 'null']
              description: "The Instagram posts (`comment`) and stories (`story_message`) the trigger is limited to. Null:\nany of them."
              items:
                type: object
                additionalProperties: false
                properties:
                  type:
                    enum:
                      - "feed"
                      - "story"
                  id:
                    type: string
                required:
                  - type
                  - id
            next_post:
              type: boolean
              description: "Comments on the next feed post published after the workflow was created."
            replies_list_id:
              type: [string, 'null']
              description: "The replies list whose replies are posted publicly under the triggering comment, one at random\n(`GET /v1/replies-lists/{repliesListId}`; Instagram only)."
          required:
            - events
            - match
            - keywords
            - posts
            - next_post
            - replies_list_id
        folder_id:
          type: [string, 'null']
          description: "The folder it is filed in (`GET /v1/folders/{folderId}`); null at the top level."
        revision:
          type: number
          description: "Moves on every change to the workflow, except its run count. The `ETag` carries it, and\n`If-Match` takes it back."
        stats:
          type: object
          additionalProperties: false
          properties:
            total_runs:
              type: number
          required:
            - total_runs
        created_at:
          type: string
        published_at:
          type: [string, 'null']
        graph:
          type: object
          additionalProperties: false
          properties:
            nodes:
              type: object
              description: "The nodes by id, each with its `type`, its `data` and, optionally, its `position` in the editor.\nThe catalog of node types is `GET /v1/workflow-graph-schema`; send back as you got them the node\ntypes and fields you do not know."
              additionalProperties: true
          required:
            - nodes
        published_version_id:
          type: [string, 'null']
          description: "The snapshot of the graph the last publish put live; null for a workflow never published with\none."
      required:
        - id
        - title
        - description
        - status
        - has_unpublished_changes
        - channel
        - trigger
        - folder_id
        - revision
        - stats
        - created_at
        - published_at
        - graph
        - published_version_id
    updateWorkflowHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        title:
          type: string
        description:
          type: string
        status:
          enum:
            - "draft"
            - "published"
        has_unpublished_changes:
          type: boolean
          description: "Published, and written since: the draft may differ from what runs."
        channel:
          type: object
          additionalProperties: false
          properties:
            type:
              enum:
                - "instagram"
                - "whatsapp"
            connection_id:
              type: [string, 'null']
              description: "The connection the workflow is bound to. An Instagram workflow stored without one runs on the\naccount's Instagram connection, which is what this answers; null only when there is none."
          required:
            - type
            - connection_id
        trigger:
          type: object
          additionalProperties: false
          properties:
            events:
              type: array
              description: "Empty: the workflow only starts through the API, a bulk send or another workflow's start block."
              items:
                enum:
                  - "comment"
                  - "live_comment"
                  - "story_message"
                  - "story_mention"
                  - "message"
                  - "message_sent"
            match:
              enum:
                - "any"
                - "contains"
                - "equals"
                - "starts_with"
            keywords:
              type: array
              items:
                type: string
            posts:
              type: [array, 'null']
              description: "The Instagram posts (`comment`) and stories (`story_message`) the trigger is limited to. Null:\nany of them."
              items:
                type: object
                additionalProperties: false
                properties:
                  type:
                    enum:
                      - "feed"
                      - "story"
                  id:
                    type: string
                required:
                  - type
                  - id
            next_post:
              type: boolean
              description: "Comments on the next feed post published after the workflow was created."
            replies_list_id:
              type: [string, 'null']
              description: "The replies list whose replies are posted publicly under the triggering comment, one at random\n(`GET /v1/replies-lists/{repliesListId}`; Instagram only)."
          required:
            - events
            - match
            - keywords
            - posts
            - next_post
            - replies_list_id
        folder_id:
          type: [string, 'null']
          description: "The folder it is filed in (`GET /v1/folders/{folderId}`); null at the top level."
        revision:
          type: number
          description: "Moves on every change to the workflow, except its run count. The `ETag` carries it, and\n`If-Match` takes it back."
        stats:
          type: object
          additionalProperties: false
          properties:
            total_runs:
              type: number
          required:
            - total_runs
        created_at:
          type: string
        published_at:
          type: [string, 'null']
        graph:
          type: object
          additionalProperties: false
          properties:
            nodes:
              type: object
              description: "The nodes by id, each with its `type`, its `data` and, optionally, its `position` in the editor.\nThe catalog of node types is `GET /v1/workflow-graph-schema`; send back as you got them the node\ntypes and fields you do not know."
              additionalProperties: true
          required:
            - nodes
        published_version_id:
          type: [string, 'null']
          description: "The snapshot of the graph the last publish put live; null for a workflow never published with\none."
      required:
        - id
        - title
        - description
        - status
        - has_unpublished_changes
        - channel
        - trigger
        - folder_id
        - revision
        - stats
        - created_at
        - published_at
        - graph
        - published_version_id
    validateWorkflowHandler:
      type: object
      additionalProperties: false
      properties:
        valid:
          type: boolean
          description: "No errors: the workflow can be published as it is."
        errors:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              code:
                type: string
              message:
                type: string
              node_id:
                type: [string, 'null']
                description: "The node it is about, when it is about one."
              path:
                type: [string, 'null']
                description: "Where it is, as a dotted path from the request (`nodes.n1.data.buttons.0.title`, `trigger`,\n`channel`), when it is somewhere."
              workflow_ids:
                type: array
                description: "The workflows it involves: the ones sharing a trigger, or a start block's target."
                items:
                  type: string
              workflows:
                type: array
                description: "The workflows of `workflow_ids` the account has, with their titles."
                items:
                  type: object
                  additionalProperties: false
                  properties:
                    id:
                      type: string
                    title:
                      type: string
                  required:
                    - id
                    - title
              keywords:
                type: array
                description: "The keywords another workflow already answers."
                items:
                  type: string
              connection_id:
                type: string
                description: "The connection a WhatsApp handoff button points at."
            required:
              - code
              - message
              - node_id
              - path
        warnings:
          type: array
          description: "What publishes but probably does not do what was meant."
          items:
            type: object
            additionalProperties: false
            properties:
              code:
                type: string
              message:
                type: string
              node_id:
                type: [string, 'null']
                description: "The node it is about, when it is about one."
              path:
                type: [string, 'null']
                description: "Where it is, as a dotted path from the request (`nodes.n1.data.buttons.0.title`, `trigger`,\n`channel`), when it is somewhere."
              workflow_ids:
                type: array
                description: "The workflows it involves: the ones sharing a trigger, or a start block's target."
                items:
                  type: string
              workflows:
                type: array
                description: "The workflows of `workflow_ids` the account has, with their titles."
                items:
                  type: object
                  additionalProperties: false
                  properties:
                    id:
                      type: string
                    title:
                      type: string
                  required:
                    - id
                    - title
              keywords:
                type: array
                description: "The keywords another workflow already answers."
                items:
                  type: string
              connection_id:
                type: string
                description: "The connection a WhatsApp handoff button points at."
            required:
              - code
              - message
              - node_id
              - path
        revision:
          type: number
          description: "The revision checked. Publishing with it in `If-Match` publishes exactly what was checked."
      required:
        - valid
        - errors
        - warnings
        - revision
    publishWorkflowHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        title:
          type: string
        description:
          type: string
        status:
          enum:
            - "draft"
            - "published"
        has_unpublished_changes:
          type: boolean
          description: "Published, and written since: the draft may differ from what runs."
        channel:
          type: object
          additionalProperties: false
          properties:
            type:
              enum:
                - "instagram"
                - "whatsapp"
            connection_id:
              type: [string, 'null']
              description: "The connection the workflow is bound to. An Instagram workflow stored without one runs on the\naccount's Instagram connection, which is what this answers; null only when there is none."
          required:
            - type
            - connection_id
        trigger:
          type: object
          additionalProperties: false
          properties:
            events:
              type: array
              description: "Empty: the workflow only starts through the API, a bulk send or another workflow's start block."
              items:
                enum:
                  - "comment"
                  - "live_comment"
                  - "story_message"
                  - "story_mention"
                  - "message"
                  - "message_sent"
            match:
              enum:
                - "any"
                - "contains"
                - "equals"
                - "starts_with"
            keywords:
              type: array
              items:
                type: string
            posts:
              type: [array, 'null']
              description: "The Instagram posts (`comment`) and stories (`story_message`) the trigger is limited to. Null:\nany of them."
              items:
                type: object
                additionalProperties: false
                properties:
                  type:
                    enum:
                      - "feed"
                      - "story"
                  id:
                    type: string
                required:
                  - type
                  - id
            next_post:
              type: boolean
              description: "Comments on the next feed post published after the workflow was created."
            replies_list_id:
              type: [string, 'null']
              description: "The replies list whose replies are posted publicly under the triggering comment, one at random\n(`GET /v1/replies-lists/{repliesListId}`; Instagram only)."
          required:
            - events
            - match
            - keywords
            - posts
            - next_post
            - replies_list_id
        folder_id:
          type: [string, 'null']
          description: "The folder it is filed in (`GET /v1/folders/{folderId}`); null at the top level."
        revision:
          type: number
          description: "Moves on every change to the workflow, except its run count. The `ETag` carries it, and\n`If-Match` takes it back."
        stats:
          type: object
          additionalProperties: false
          properties:
            total_runs:
              type: number
          required:
            - total_runs
        created_at:
          type: string
        published_at:
          type: [string, 'null']
        graph:
          type: object
          additionalProperties: false
          properties:
            nodes:
              type: object
              description: "The nodes by id, each with its `type`, its `data` and, optionally, its `position` in the editor.\nThe catalog of node types is `GET /v1/workflow-graph-schema`; send back as you got them the node\ntypes and fields you do not know."
              additionalProperties: true
          required:
            - nodes
        published_version_id:
          type: [string, 'null']
          description: "The snapshot of the graph the last publish put live; null for a workflow never published with\none."
      required:
        - id
        - title
        - description
        - status
        - has_unpublished_changes
        - channel
        - trigger
        - folder_id
        - revision
        - stats
        - created_at
        - published_at
        - graph
        - published_version_id
    unpublishWorkflowHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        title:
          type: string
        description:
          type: string
        status:
          enum:
            - "draft"
            - "published"
        has_unpublished_changes:
          type: boolean
          description: "Published, and written since: the draft may differ from what runs."
        channel:
          type: object
          additionalProperties: false
          properties:
            type:
              enum:
                - "instagram"
                - "whatsapp"
            connection_id:
              type: [string, 'null']
              description: "The connection the workflow is bound to. An Instagram workflow stored without one runs on the\naccount's Instagram connection, which is what this answers; null only when there is none."
          required:
            - type
            - connection_id
        trigger:
          type: object
          additionalProperties: false
          properties:
            events:
              type: array
              description: "Empty: the workflow only starts through the API, a bulk send or another workflow's start block."
              items:
                enum:
                  - "comment"
                  - "live_comment"
                  - "story_message"
                  - "story_mention"
                  - "message"
                  - "message_sent"
            match:
              enum:
                - "any"
                - "contains"
                - "equals"
                - "starts_with"
            keywords:
              type: array
              items:
                type: string
            posts:
              type: [array, 'null']
              description: "The Instagram posts (`comment`) and stories (`story_message`) the trigger is limited to. Null:\nany of them."
              items:
                type: object
                additionalProperties: false
                properties:
                  type:
                    enum:
                      - "feed"
                      - "story"
                  id:
                    type: string
                required:
                  - type
                  - id
            next_post:
              type: boolean
              description: "Comments on the next feed post published after the workflow was created."
            replies_list_id:
              type: [string, 'null']
              description: "The replies list whose replies are posted publicly under the triggering comment, one at random\n(`GET /v1/replies-lists/{repliesListId}`; Instagram only)."
          required:
            - events
            - match
            - keywords
            - posts
            - next_post
            - replies_list_id
        folder_id:
          type: [string, 'null']
          description: "The folder it is filed in (`GET /v1/folders/{folderId}`); null at the top level."
        revision:
          type: number
          description: "Moves on every change to the workflow, except its run count. The `ETag` carries it, and\n`If-Match` takes it back."
        stats:
          type: object
          additionalProperties: false
          properties:
            total_runs:
              type: number
          required:
            - total_runs
        created_at:
          type: string
        published_at:
          type: [string, 'null']
        graph:
          type: object
          additionalProperties: false
          properties:
            nodes:
              type: object
              description: "The nodes by id, each with its `type`, its `data` and, optionally, its `position` in the editor.\nThe catalog of node types is `GET /v1/workflow-graph-schema`; send back as you got them the node\ntypes and fields you do not know."
              additionalProperties: true
          required:
            - nodes
        published_version_id:
          type: [string, 'null']
          description: "The snapshot of the graph the last publish put live; null for a workflow never published with\none."
      required:
        - id
        - title
        - description
        - status
        - has_unpublished_changes
        - channel
        - trigger
        - folder_id
        - revision
        - stats
        - created_at
        - published_at
        - graph
        - published_version_id
    listWorkflowVersionsHandler:
      type: object
      additionalProperties: false
      properties:
        data:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
              created_at:
                type: string
            required:
              - id
              - created_at
        next_cursor:
          type: [string, 'null']
      required:
        - data
        - next_cursor
    readWorkflowVersionHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        created_at:
          type: string
        workflow_id:
          type: string
        graph:
          type: object
          additionalProperties: false
          properties:
            nodes:
              type: object
              description: "The nodes by id, each with its `type`, its `data` and, optionally, its `position` in the editor.\nThe catalog of node types is `GET /v1/workflow-graph-schema`; send back as you got them the node\ntypes and fields you do not know."
              additionalProperties: true
          required:
            - nodes
      required:
        - id
        - created_at
        - workflow_id
        - graph
    listWorkflowRunsHandler:
      type: object
      additionalProperties: false
      properties:
        data:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
              workflow_id:
                type: string
              contact_id:
                type: [string, 'null']
                description: "The contact the run spoke to, while it exists."
              status:
                enum:
                  - "waiting"
                  - "completed"
                  - "stopped"
                  - "failed"
                  - "blocked"
              trigger:
                type: [object, 'null']
                description: "What started it; null for a run started by the API, a bulk send or another workflow."
                additionalProperties: false
                properties:
                  event:
                    enum:
                      - "comment"
                      - "live_comment"
                      - "story_message"
                      - "story_mention"
                      - "message"
                      - "message_sent"
                  keyword:
                    type: [string, 'null']
                  post_id:
                    type: [string, 'null']
                required:
                  - event
                  - keyword
                  - post_id
              step_count:
                type: number
              started_at:
                type: string
              last_activity_at:
                type: string
            required:
              - id
              - workflow_id
              - contact_id
              - status
              - trigger
              - step_count
              - started_at
              - last_activity_at
        next_cursor:
          type: [string, 'null']
      required:
        - data
        - next_cursor
    startWorkflowRunHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          description: "The run, as `runs/{runId}` reads it once its first stretch is recorded."
        workflow_id:
          type: string
        contact_id:
          type: string
        status:
          type: string
          enum: ["queued"]
        created_at:
          type: string
      required:
        - id
        - workflow_id
        - contact_id
        - status
        - created_at
    readWorkflowRunHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        workflow_id:
          type: string
        contact_id:
          type: [string, 'null']
          description: "The contact the run spoke to, while it exists."
        status:
          enum:
            - "waiting"
            - "completed"
            - "stopped"
            - "failed"
            - "blocked"
        trigger:
          type: [object, 'null']
          description: "What started it; null for a run started by the API, a bulk send or another workflow."
          additionalProperties: false
          properties:
            event:
              enum:
                - "comment"
                - "live_comment"
                - "story_message"
                - "story_mention"
                - "message"
                - "message_sent"
            keyword:
              type: [string, 'null']
            post_id:
              type: [string, 'null']
          required:
            - event
            - keyword
            - post_id
        step_count:
          type: number
        started_at:
          type: string
        last_activity_at:
          type: string
        steps:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              node_id:
                type: [string, 'null']
              action:
                type: string
                description: "What the step did (`message`, `wait`, `sleep`, `tags`, `invoke`…). An open set."
              status:
                enum:
                  - "ok"
                  - "skipped"
                  - "failed"
              at:
                type: string
              duration_ms:
                type: [number, 'null']
              error:
                type: [object, 'null']
                additionalProperties: false
                properties:
                  reason:
                    type: [string, 'null']
                  status:
                    type: [number, 'null']
                required:
                  - reason
                  - status
            required:
              - node_id
              - action
              - status
              - at
              - duration_ms
              - error
        steps_truncated:
          type: boolean
          description: "The oldest steps of a very long run were left out."
      required:
        - id
        - workflow_id
        - contact_id
        - status
        - trigger
        - step_count
        - started_at
        - last_activity_at
        - steps
        - steps_truncated
    readWorkflowGraphSchemaHandler:
      type: object
      additionalProperties: false
      properties:
        schema:
          type: object
          description: "JSON Schema (2020-12) of `graph.nodes`: the node catalog the API checks a graph against."
          additionalProperties: true
        catalog_version:
          type: string
          description: "Changes exactly when the catalog does."
      required:
        - schema
        - catalog_version
    listFoldersHandler:
      type: object
      additionalProperties: false
      properties:
        data:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
              type:
                type: string
                enum: ["workflow"]
              name:
                type: string
              parent_id:
                type: [string, 'null']
                description: "The folder it is in; null at the top level. A folder only goes in a folder of its own type."
              created_at:
                type: string
              updated_at:
                type: string
            required:
              - id
              - type
              - name
              - parent_id
              - created_at
              - updated_at
        next_cursor:
          type: [string, 'null']
      required:
        - data
        - next_cursor
    createFolderHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        type:
          type: string
          enum: ["workflow"]
        name:
          type: string
        parent_id:
          type: [string, 'null']
          description: "The folder it is in; null at the top level. A folder only goes in a folder of its own type."
        created_at:
          type: string
        updated_at:
          type: string
      required:
        - id
        - type
        - name
        - parent_id
        - created_at
        - updated_at
    readFolderHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        type:
          type: string
          enum: ["workflow"]
        name:
          type: string
        parent_id:
          type: [string, 'null']
          description: "The folder it is in; null at the top level. A folder only goes in a folder of its own type."
        created_at:
          type: string
        updated_at:
          type: string
      required:
        - id
        - type
        - name
        - parent_id
        - created_at
        - updated_at
    updateFolderHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        type:
          type: string
          enum: ["workflow"]
        name:
          type: string
        parent_id:
          type: [string, 'null']
          description: "The folder it is in; null at the top level. A folder only goes in a folder of its own type."
        created_at:
          type: string
        updated_at:
          type: string
      required:
        - id
        - type
        - name
        - parent_id
        - created_at
        - updated_at
    listRepliesListsHandler:
      type: object
      additionalProperties: false
      properties:
        data:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
              name:
                type: string
              reply_count:
                type: number
                description: "How many replies the list holds. Read the list to get them."
              created_at:
                type: string
              updated_at:
                type: string
            required:
              - id
              - name
              - reply_count
              - created_at
              - updated_at
        next_cursor:
          type: [string, 'null']
      required:
        - data
        - next_cursor
    createRepliesListHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        name:
          type: string
        created_at:
          type: string
        updated_at:
          type: string
        replies:
          type: array
          description: "What a workflow that answers comments with the list (`trigger.replies_list_id`) posts under\neach comment: one of these, picked at random, with the contact's and the account's variables\nfilled in."
          items:
            type: string
      required:
        - id
        - name
        - created_at
        - updated_at
        - replies
    readRepliesListHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        name:
          type: string
        created_at:
          type: string
        updated_at:
          type: string
        replies:
          type: array
          description: "What a workflow that answers comments with the list (`trigger.replies_list_id`) posts under\neach comment: one of these, picked at random, with the contact's and the account's variables\nfilled in."
          items:
            type: string
      required:
        - id
        - name
        - created_at
        - updated_at
        - replies
    updateRepliesListHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        name:
          type: string
        created_at:
          type: string
        updated_at:
          type: string
        replies:
          type: array
          description: "What a workflow that answers comments with the list (`trigger.replies_list_id`) posts under\neach comment: one of these, picked at random, with the contact's and the account's variables\nfilled in."
          items:
            type: string
      required:
        - id
        - name
        - created_at
        - updated_at
        - replies
    listWebhooksHandler:
      type: object
      additionalProperties: false
      properties:
        data:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
              url:
                type: string
                description: "Where the account's events are posted: HTTPS on port 443."
              description:
                type: [string, 'null']
              event_types:
                type: array
                description: "What the endpoint receives."
                items:
                  enum:
                    - "message.received"
                    - "message.sent"
                    - "message.updated"
                    - "message.deleted"
                    - "message.failed"
                    - "comment.received"
                    - "live_comment.received"
                    - "contact.created"
                    - "contact.tagged"
                    - "contact.untagged"
                    - "contact.custom_fields_updated"
                    - "workflow_run.ended"
                    - "link.clicked"
                    - "connection.connected"
                    - "connection.disconnected"
              status:
                enum:
                  - "enabled"
                  - "disabled"
              disabled_reason:
                type: [string, 'null']
                enum:
                  - "requested"
                  - "failing"
                  - null
              disabled_at:
                type: [string, 'null']
              failing_since:
                type: [string, 'null']
                description: "When every attempt started failing, while they still do."
              previous_secret_expires_at:
                type: [string, 'null']
                description: "Until when the secret before the last rotation still signs beside the current one."
              created_at:
                type: string
              updated_at:
                type: string
            required:
              - id
              - url
              - description
              - event_types
              - status
              - disabled_reason
              - disabled_at
              - failing_since
              - previous_secret_expires_at
              - created_at
              - updated_at
        next_cursor:
          type: [string, 'null']
      required:
        - data
        - next_cursor
    createWebhookHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        url:
          type: string
          description: "Where the account's events are posted: HTTPS on port 443."
        description:
          type: [string, 'null']
        event_types:
          type: array
          description: "What the endpoint receives."
          items:
            enum:
              - "message.received"
              - "message.sent"
              - "message.updated"
              - "message.deleted"
              - "message.failed"
              - "comment.received"
              - "live_comment.received"
              - "contact.created"
              - "contact.tagged"
              - "contact.untagged"
              - "contact.custom_fields_updated"
              - "workflow_run.ended"
              - "link.clicked"
              - "connection.connected"
              - "connection.disconnected"
        status:
          enum:
            - "enabled"
            - "disabled"
        disabled_reason:
          type: [string, 'null']
          enum:
            - "requested"
            - "failing"
            - null
        disabled_at:
          type: [string, 'null']
        failing_since:
          type: [string, 'null']
          description: "When every attempt started failing, while they still do."
        previous_secret_expires_at:
          type: [string, 'null']
          description: "Until when the secret before the last rotation still signs beside the current one."
        created_at:
          type: string
        updated_at:
          type: string
        secret:
          type: string
          description: "Checks the `Gaio-Signature` of every delivery. Kept by the client: no read answers it again."
      required:
        - id
        - url
        - description
        - event_types
        - status
        - disabled_reason
        - disabled_at
        - failing_since
        - previous_secret_expires_at
        - created_at
        - updated_at
        - secret
    readWebhookHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        url:
          type: string
          description: "Where the account's events are posted: HTTPS on port 443."
        description:
          type: [string, 'null']
        event_types:
          type: array
          description: "What the endpoint receives."
          items:
            enum:
              - "message.received"
              - "message.sent"
              - "message.updated"
              - "message.deleted"
              - "message.failed"
              - "comment.received"
              - "live_comment.received"
              - "contact.created"
              - "contact.tagged"
              - "contact.untagged"
              - "contact.custom_fields_updated"
              - "workflow_run.ended"
              - "link.clicked"
              - "connection.connected"
              - "connection.disconnected"
        status:
          enum:
            - "enabled"
            - "disabled"
        disabled_reason:
          type: [string, 'null']
          enum:
            - "requested"
            - "failing"
            - null
        disabled_at:
          type: [string, 'null']
        failing_since:
          type: [string, 'null']
          description: "When every attempt started failing, while they still do."
        previous_secret_expires_at:
          type: [string, 'null']
          description: "Until when the secret before the last rotation still signs beside the current one."
        created_at:
          type: string
        updated_at:
          type: string
      required:
        - id
        - url
        - description
        - event_types
        - status
        - disabled_reason
        - disabled_at
        - failing_since
        - previous_secret_expires_at
        - created_at
        - updated_at
    updateWebhookHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        url:
          type: string
          description: "Where the account's events are posted: HTTPS on port 443."
        description:
          type: [string, 'null']
        event_types:
          type: array
          description: "What the endpoint receives."
          items:
            enum:
              - "message.received"
              - "message.sent"
              - "message.updated"
              - "message.deleted"
              - "message.failed"
              - "comment.received"
              - "live_comment.received"
              - "contact.created"
              - "contact.tagged"
              - "contact.untagged"
              - "contact.custom_fields_updated"
              - "workflow_run.ended"
              - "link.clicked"
              - "connection.connected"
              - "connection.disconnected"
        status:
          enum:
            - "enabled"
            - "disabled"
        disabled_reason:
          type: [string, 'null']
          enum:
            - "requested"
            - "failing"
            - null
        disabled_at:
          type: [string, 'null']
        failing_since:
          type: [string, 'null']
          description: "When every attempt started failing, while they still do."
        previous_secret_expires_at:
          type: [string, 'null']
          description: "Until when the secret before the last rotation still signs beside the current one."
        created_at:
          type: string
        updated_at:
          type: string
      required:
        - id
        - url
        - description
        - event_types
        - status
        - disabled_reason
        - disabled_at
        - failing_since
        - previous_secret_expires_at
        - created_at
        - updated_at
    rotateWebhookSecretHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        url:
          type: string
          description: "Where the account's events are posted: HTTPS on port 443."
        description:
          type: [string, 'null']
        event_types:
          type: array
          description: "What the endpoint receives."
          items:
            enum:
              - "message.received"
              - "message.sent"
              - "message.updated"
              - "message.deleted"
              - "message.failed"
              - "comment.received"
              - "live_comment.received"
              - "contact.created"
              - "contact.tagged"
              - "contact.untagged"
              - "contact.custom_fields_updated"
              - "workflow_run.ended"
              - "link.clicked"
              - "connection.connected"
              - "connection.disconnected"
        status:
          enum:
            - "enabled"
            - "disabled"
        disabled_reason:
          type: [string, 'null']
          enum:
            - "requested"
            - "failing"
            - null
        disabled_at:
          type: [string, 'null']
        failing_since:
          type: [string, 'null']
          description: "When every attempt started failing, while they still do."
        previous_secret_expires_at:
          type: [string, 'null']
          description: "Until when the secret before the last rotation still signs beside the current one."
        created_at:
          type: string
        updated_at:
          type: string
        secret:
          type: string
          description: "Checks the `Gaio-Signature` of every delivery. Kept by the client: no read answers it again."
      required:
        - id
        - url
        - description
        - event_types
        - status
        - disabled_reason
        - disabled_at
        - failing_since
        - previous_secret_expires_at
        - created_at
        - updated_at
        - secret
    testWebhookHandler:
      type: object
      additionalProperties: false
      properties:
        delivered:
          type: boolean
        response_status:
          type: [number, 'null']
        error:
          type: [string, 'null']
          enum:
            - "http_status"
            - "timeout"
            - "dns_failed"
            - "connection_failed"
            - "tls_failed"
            - "unsafe_target"
            - "endpoint_disabled"
            - "account_disabled"
            - null
        duration_ms:
          type: number
      required:
        - delivered
        - response_status
        - error
        - duration_ms
    listWebhookDeliveriesHandler:
      type: object
      additionalProperties: false
      properties:
        data:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
              webhook_id:
                type: string
              event:
                type: object
                additionalProperties: false
                properties:
                  id:
                    type: string
                    description: "What the body's `id` is: the same on every attempt, for the endpoint to deduplicate on."
                  type:
                    type: string
                  created_at:
                    type: string
                required:
                  - id
                  - type
                  - created_at
              status:
                enum:
                  - "pending"
                  - "succeeded"
                  - "failed"
              attempts:
                type: number
              next_attempt_at:
                type: [string, 'null']
              last_attempt_at:
                type: [string, 'null']
              last_response_status:
                type: [number, 'null']
                description: "The status the endpoint answered the last attempt with, when it answered."
              last_error:
                type: [string, 'null']
                enum:
                  - "http_status"
                  - "timeout"
                  - "dns_failed"
                  - "connection_failed"
                  - "tls_failed"
                  - "unsafe_target"
                  - "endpoint_disabled"
                  - "account_disabled"
                  - null
              delivered_at:
                type: [string, 'null']
              created_at:
                type: string
            required:
              - id
              - webhook_id
              - event
              - status
              - attempts
              - next_attempt_at
              - last_attempt_at
              - last_response_status
              - last_error
              - delivered_at
              - created_at
        next_cursor:
          type: [string, 'null']
      required:
        - data
        - next_cursor
    retryWebhookDeliveryHandler:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        webhook_id:
          type: string
        event:
          type: object
          additionalProperties: false
          properties:
            id:
              type: string
              description: "What the body's `id` is: the same on every attempt, for the endpoint to deduplicate on."
            type:
              type: string
            created_at:
              type: string
          required:
            - id
            - type
            - created_at
        status:
          enum:
            - "pending"
            - "succeeded"
            - "failed"
        attempts:
          type: number
        next_attempt_at:
          type: [string, 'null']
        last_attempt_at:
          type: [string, 'null']
        last_response_status:
          type: [number, 'null']
          description: "The status the endpoint answered the last attempt with, when it answered."
        last_error:
          type: [string, 'null']
          enum:
            - "http_status"
            - "timeout"
            - "dns_failed"
            - "connection_failed"
            - "tls_failed"
            - "unsafe_target"
            - "endpoint_disabled"
            - "account_disabled"
            - null
        delivered_at:
          type: [string, 'null']
        created_at:
          type: string
      required:
        - id
        - webhook_id
        - event
        - status
        - attempts
        - next_attempt_at
        - last_attempt_at
        - last_response_status
        - last_error
        - delivered_at
        - created_at
    createContactHandlerRequest:
      type: object
      additionalProperties: false
      properties:
        phone:
          type: string
          description: "The contact's WhatsApp number. Written as in an import: a foreign number needs its `+`, a\nBrazilian one may come without the `55` and with or without the ninth digit."
          minLength: 1
          maxLength: 32
        name:
          type: string
          minLength: 1
          maxLength: 200
        connection_id:
          type: string
          description: "A connected WhatsApp number of the account (`GET /v1/connections`)."
          format: uuid
        consent:
          type: boolean
          description: "That the contact agreed to receive messages from the business, which Meta requires before\nthe business writes first. Must be `true`; it is kept in the contact's history."
        custom_fields:
          type: array
          minItems: 1
          maxItems: 50
          items:
            type: object
            additionalProperties: false
            properties:
              field_id:
                type: string
                format: uuid
              value:
                anyOf:
                - type: string
                  minLength: 1
                  maxLength: 1000
                - type: number
            required:
              - field_id
              - value
        tag_ids:
          type: array
          minItems: 1
          maxItems: 20
          items:
            type: string
            format: uuid
      required:
        - phone
        - name
        - connection_id
        - consent
    setContactCustomFieldsHandlerRequest:
      type: object
      additionalProperties: false
      properties:
        custom_fields:
          type: array
          description: "A `number` field takes a JSON number; `text` and `dropdown` take a string. A dropdown takes\nan option's `value` or `label`, in any case, and stores the `value`."
          minItems: 1
          maxItems: 50
          items:
            type: object
            additionalProperties: false
            properties:
              field_id:
                type: string
                format: uuid
              value:
                anyOf:
                - type: string
                  minLength: 1
                  maxLength: 1000
                - type: number
            required:
              - field_id
              - value
      required:
        - custom_fields
    createTagHandlerRequest:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          description: "Trimmed; unique in the account in any case."
          minLength: 1
          maxLength: 50
        description:
          type: string
          maxLength: 200
      required:
        - name
    updateTagHandlerRequest:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          description: "Trimmed; unique in the account in any case."
          minLength: 1
          maxLength: 50
      required:
        - name
    sendMessageHandlerRequest:
      type: object
      additionalProperties: false
      properties:
        text:
          type: string
          description: "The message's text: alone, above `buttons`, a WhatsApp media's caption, or the text above\nWhatsApp cards. Alone, up to 1000 characters on Instagram and 4096 on WhatsApp (`text_too_long`\nnames the limit of each other use). When the account's plan includes the Gaio signature it is\nappended inside that limit to a text alone and to a text above buttons."
          minLength: 1
          maxLength: 4096
        attachments:
          type: array
          description: "One media, or one set of cards."
          minItems: 1
          maxItems: 1
          items:
            anyOf:
            - type: object
              additionalProperties: false
              properties:
                type:
                  enum:
                    - "image"
                    - "video"
                    - "audio"
                    - "file"
                media_id:
                  type: string
                  format: uuid
              required:
                - type
                - media_id
            - type: object
              additionalProperties: false
              properties:
                type:
                  type: string
                  enum: ["cards"]
                cards:
                  type: array
                  description: "Instagram: 1 to 10. WhatsApp: 2 to 10."
                  minItems: 1
                  maxItems: 10
                  items:
                    type: object
                    additionalProperties: false
                    properties:
                      title:
                        type: string
                        description: "Instagram: up to 80 characters. WhatsApp: the card's body is the title and the subtitle on two\nlines, 160 characters together."
                        minLength: 1
                        maxLength: 160
                      subtitle:
                        type: string
                        description: "Instagram: up to 80 characters. WhatsApp: counted with the title."
                        minLength: 1
                        maxLength: 160
                      media_id:
                        type: string
                        description: "An image from `POST /v1/media`. Required on WhatsApp, whose cards are headed by one."
                        format: uuid
                      buttons:
                        type: array
                        description: "Instagram: 0 to 3 of either kind, and a card needs a subtitle, an image or a button besides its\ntitle. WhatsApp: exactly 1 link button, or 1 to 3 reply buttons, the same kind and number on\nevery card."
                        maxItems: 3
                        items:
                          anyOf:
                          - type: object
                            additionalProperties: false
                            properties:
                              type:
                                type: string
                                enum: ["open_url"]
                              title:
                                type: string
                                description: "Both channels label a button with up to 20 characters."
                                minLength: 1
                                maxLength: 20
                              url:
                                type: string
                                description: "An absolute `https` URL, sent as given: the API does not wrap it in a tracked link, so a tap is\ncounted nowhere."
                                minLength: 1
                                maxLength: 1000
                            required:
                              - type
                              - title
                              - url
                          - type: object
                            additionalProperties: false
                            properties:
                              type:
                                type: string
                                enum: ["reply"]
                              id:
                                type: string
                                description: "Your own name for the button, unique among the reply buttons of the message: 1 to 64 letters,\ndigits, `_` and `-`. A tap answers it back in the message's `button.id`."
                                format: regex
                                pattern: "^[A-Za-z0-9_-]{1,64}$"
                              title:
                                type: string
                                description: "Both channels label a button with up to 20 characters."
                                minLength: 1
                                maxLength: 20
                            required:
                              - type
                              - id
                              - title
                    required:
                      - title
                      - buttons
              required:
                - type
                - cards
        buttons:
          type: array
          description: "Buttons under `text`. Instagram: 1 to 3 of either kind. WhatsApp: 1 to 3 reply buttons with\ndifferent titles, or exactly 1 link button."
          minItems: 1
          maxItems: 3
          items:
            anyOf:
            - type: object
              additionalProperties: false
              properties:
                type:
                  type: string
                  enum: ["open_url"]
                title:
                  type: string
                  description: "Both channels label a button with up to 20 characters."
                  minLength: 1
                  maxLength: 20
                url:
                  type: string
                  description: "An absolute `https` URL, sent as given: the API does not wrap it in a tracked link, so a tap is\ncounted nowhere."
                  minLength: 1
                  maxLength: 1000
              required:
                - type
                - title
                - url
            - type: object
              additionalProperties: false
              properties:
                type:
                  type: string
                  enum: ["reply"]
                id:
                  type: string
                  description: "Your own name for the button, unique among the reply buttons of the message: 1 to 64 letters,\ndigits, `_` and `-`. A tap answers it back in the message's `button.id`."
                  format: regex
                  pattern: "^[A-Za-z0-9_-]{1,64}$"
                title:
                  type: string
                  description: "Both channels label a button with up to 20 characters."
                  minLength: 1
                  maxLength: 20
              required:
                - type
                - id
                - title
        template:
          type: object
          description: "A WhatsApp template: the only message a conversation past its 24-hour window takes."
          additionalProperties: false
          properties:
            name:
              type: string
              description: "The template's name, as WhatsApp approved it."
              minLength: 1
              maxLength: 512
            language:
              type: string
              description: "Its language code (`pt_BR`, `en_US`): a template is one name per language."
              minLength: 1
              maxLength: 15
            body_variables:
              type: array
              description: "One value per `{{n}}` of the template's body, in placeholder order."
              maxItems: 100
              items:
                type: string
                minLength: 1
                maxLength: 1024
          required:
            - name
            - language
    createMediaHandlerRequest:
      type: object
      additionalProperties: false
      properties:
        content_type:
          enum:
            - "image/jpeg"
            - "image/png"
            - "image/gif"
            - "image/webp"
            - "video/mp4"
            - "video/ogg"
            - "video/webm"
            - "video/x-msvideo"
            - "video/quicktime"
            - "audio/aac"
            - "audio/mp4"
            - "audio/mpeg"
            - "audio/wav"
            - "audio/x-m4a"
            - "audio/x-wav"
            - "application/pdf"
      required:
        - content_type
    createWorkflowHandlerRequest:
      type: object
      additionalProperties: false
      properties:
        title:
          type: string
          minLength: 1
          maxLength: 128
        description:
          type: string
          maxLength: 512
        channel:
          type: object
          additionalProperties: false
          properties:
            type:
              enum:
                - "instagram"
                - "whatsapp"
            connection_id:
              type: [string, 'null']
              description: "Required on WhatsApp. On Instagram it may be left out: the workflow runs on the account's\nInstagram connection."
              format: uuid
          required:
            - type
        trigger:
          type: object
          additionalProperties: false
          properties:
            events:
              type: array
              maxItems: 6
              items:
                enum:
                  - "comment"
                  - "live_comment"
                  - "story_message"
                  - "story_mention"
                  - "message"
                  - "message_sent"
            match:
              enum:
                - "any"
                - "contains"
                - "equals"
                - "starts_with"
            keywords:
              type: array
              maxItems: 200
              items:
                type: string
                minLength: 1
                maxLength: 200
            posts:
              type: [array, 'null']
              minItems: 1
              maxItems: 200
              items:
                type: object
                additionalProperties: false
                properties:
                  type:
                    enum:
                      - "feed"
                      - "story"
                  id:
                    type: string
                    minLength: 1
                    maxLength: 128
                required:
                  - type
                  - id
            next_post:
              type: boolean
            replies_list_id:
              type: [string, 'null']
              format: uuid
          required:
            - events
            - match
        graph:
          type: object
          description: "Left out, the workflow starts as a draft with only its `root` node."
          additionalProperties: false
          properties:
            nodes:
              type: object
              description: "The nodes by id, each with its `type`, its `data` and, optionally, its `position` in the editor.\nThe catalog of node types is `GET /v1/workflow-graph-schema`; send back as you got them the node\ntypes and fields you do not know."
              additionalProperties: true
          required:
            - nodes
        folder_id:
          type: [string, 'null']
          description: "The folder of workflows to file it in. Left out or null: the top level."
          format: uuid
      required:
        - title
        - channel
        - trigger
    validateWorkflowDefinitionHandlerRequest:
      type: object
      additionalProperties: false
      properties:
        channel:
          type: object
          additionalProperties: false
          properties:
            type:
              enum:
                - "instagram"
                - "whatsapp"
            connection_id:
              type: [string, 'null']
              description: "Required on WhatsApp. On Instagram it may be left out: the workflow runs on the account's\nInstagram connection."
              format: uuid
          required:
            - type
        trigger:
          type: object
          additionalProperties: false
          properties:
            events:
              type: array
              maxItems: 6
              items:
                enum:
                  - "comment"
                  - "live_comment"
                  - "story_message"
                  - "story_mention"
                  - "message"
                  - "message_sent"
            match:
              enum:
                - "any"
                - "contains"
                - "equals"
                - "starts_with"
            keywords:
              type: array
              maxItems: 200
              items:
                type: string
                minLength: 1
                maxLength: 200
            posts:
              type: [array, 'null']
              minItems: 1
              maxItems: 200
              items:
                type: object
                additionalProperties: false
                properties:
                  type:
                    enum:
                      - "feed"
                      - "story"
                  id:
                    type: string
                    minLength: 1
                    maxLength: 128
                required:
                  - type
                  - id
            next_post:
              type: boolean
            replies_list_id:
              type: [string, 'null']
              format: uuid
          required:
            - events
            - match
        graph:
          type: object
          additionalProperties: false
          properties:
            nodes:
              type: object
              description: "The nodes by id, each with its `type`, its `data` and, optionally, its `position` in the editor.\nThe catalog of node types is `GET /v1/workflow-graph-schema`; send back as you got them the node\ntypes and fields you do not know."
              additionalProperties: true
          required:
            - nodes
      required:
        - channel
        - trigger
        - graph
    updateWorkflowHandlerRequest:
      type: object
      additionalProperties: false
      properties:
        title:
          type: string
          minLength: 1
          maxLength: 128
        description:
          type: string
          maxLength: 512
        channel:
          type: object
          description: "Replaces the channel. A published workflow has to be unpublished first."
          additionalProperties: false
          properties:
            type:
              enum:
                - "instagram"
                - "whatsapp"
            connection_id:
              type: [string, 'null']
              description: "Required on WhatsApp. On Instagram it may be left out: the workflow runs on the account's\nInstagram connection."
              format: uuid
          required:
            - type
        trigger:
          type: object
          description: "Replaces the whole trigger."
          additionalProperties: false
          properties:
            events:
              type: array
              maxItems: 6
              items:
                enum:
                  - "comment"
                  - "live_comment"
                  - "story_message"
                  - "story_mention"
                  - "message"
                  - "message_sent"
            match:
              enum:
                - "any"
                - "contains"
                - "equals"
                - "starts_with"
            keywords:
              type: array
              maxItems: 200
              items:
                type: string
                minLength: 1
                maxLength: 200
            posts:
              type: [array, 'null']
              minItems: 1
              maxItems: 200
              items:
                type: object
                additionalProperties: false
                properties:
                  type:
                    enum:
                      - "feed"
                      - "story"
                  id:
                    type: string
                    minLength: 1
                    maxLength: 128
                required:
                  - type
                  - id
            next_post:
              type: boolean
            replies_list_id:
              type: [string, 'null']
              format: uuid
          required:
            - events
            - match
        graph:
          type: object
          description: "Replaces the whole graph of the draft."
          additionalProperties: false
          properties:
            nodes:
              type: object
              description: "The nodes by id, each with its `type`, its `data` and, optionally, its `position` in the editor.\nThe catalog of node types is `GET /v1/workflow-graph-schema`; send back as you got them the node\ntypes and fields you do not know."
              additionalProperties: true
          required:
            - nodes
        folder_id:
          type: [string, 'null']
          description: "Files the workflow in this folder of workflows; null, at the top level. The folder is not\npart of what runs: moving a published workflow leaves nothing to publish."
          format: uuid
    startWorkflowRunHandlerRequest:
      type: object
      additionalProperties: false
      properties:
        contact_id:
          type: string
          format: uuid
      required:
        - contact_id
    createFolderHandlerRequest:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          description: "Trimmed. Folders may share a name, side by side too."
          minLength: 1
          maxLength: 128
        type:
          type: string
          description: "What the folder holds. Left out: workflows."
          enum: ["workflow"]
        parent_id:
          type: [string, 'null']
          description: "The folder to create it in, which holds the same type. Left out or null: the top level."
          format: uuid
      required:
        - name
    updateFolderHandlerRequest:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          description: "Trimmed."
          minLength: 1
          maxLength: 128
        parent_id:
          type: [string, 'null']
          description: "Moves the folder, with every folder under it and what they hold, into this folder of the same\ntype. Null: to the top level."
          format: uuid
    createRepliesListHandlerRequest:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          description: "Trimmed; unique among the account's lists, in any case."
          minLength: 1
          maxLength: 128
        replies:
          type: array
          description: "Kept as written. Each may carry the contact's and the account's variables\n(`{contact.first_name}`, a custom field's key), filled in when it is posted."
          minItems: 1
          maxItems: 250
          items:
            type: string
            minLength: 1
            maxLength: 512
      required:
        - name
        - replies
    updateRepliesListHandlerRequest:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          description: "Trimmed; unique among the account's lists, in any case."
          minLength: 1
          maxLength: 128
        replies:
          type: array
          description: "Replaces every reply of the list."
          minItems: 1
          maxItems: 250
          items:
            type: string
            minLength: 1
            maxLength: 512
    createWebhookHandlerRequest:
      type: object
      additionalProperties: false
      properties:
        url:
          type: string
          description: "HTTPS on port 443, with no credentials in it, on a host that resolves to a public address."
          minLength: 1
          maxLength: 2048
        description:
          type: string
          description: "What the endpoint is for. Blank leaves none."
          maxLength: 200
        event_types:
          type: array
          description: "Each type needs the scope that reads its data: `conversations:read` for messages and\ncomments, `contacts:read` for contacts and connections, `workflows:read` for runs and links."
          minItems: 1
          maxItems: 50
          items:
            enum:
              - "message.received"
              - "message.sent"
              - "message.updated"
              - "message.deleted"
              - "message.failed"
              - "comment.received"
              - "live_comment.received"
              - "contact.created"
              - "contact.tagged"
              - "contact.untagged"
              - "contact.custom_fields_updated"
              - "workflow_run.ended"
              - "link.clicked"
              - "connection.connected"
              - "connection.disconnected"
      required:
        - url
        - event_types
    updateWebhookHandlerRequest:
      type: object
      additionalProperties: false
      properties:
        url:
          type: string
          minLength: 1
          maxLength: 2048
        description:
          type: string
          description: "Blank removes it."
          maxLength: 200
        event_types:
          type: array
          description: "Replaces the types the endpoint receives."
          minItems: 1
          maxItems: 50
          items:
            enum:
              - "message.received"
              - "message.sent"
              - "message.updated"
              - "message.deleted"
              - "message.failed"
              - "comment.received"
              - "live_comment.received"
              - "contact.created"
              - "contact.tagged"
              - "contact.untagged"
              - "contact.custom_fields_updated"
              - "workflow_run.ended"
              - "link.clicked"
              - "connection.connected"
              - "connection.disconnected"
        status:
          enum:
            - "enabled"
            - "disabled"
    HttpError:
      type: object
      description: "Error returned by the service."
      additionalProperties: false
      properties:
        type:
          type: string
          enum: ["error"]
        message:
          type: string
        context:
          type: object
          additionalProperties: true
      required:
        - type
        - message
    GatewayError:
      type: object
      description: "Error returned by the gateway when it denies the request authorization."
      additionalProperties: false
      properties:
        message:
          type: string
      required:
        - message
