> ## Documentation Index
> Fetch the complete documentation index at: https://developers.useqx.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a collection

> Creates a collection with a pack. With a contact, the API creates the collection with the slots of the pack requirements. Without a contact, the API creates the collection for a recipient and sends the invitation to the email of the recipient. QX creates the slots after the recipient identifies themselves on the portal. The creation counts toward the paid write limit of the key.



## OpenAPI

````yaml /en/openapi.yaml post /collections
openapi: 3.1.0
info:
  title: QX API
  version: 1.0.0
  description: >-
    The QX API creates and reads the contacts, the collections and the documents
    of the organization, and it lists the packs.

    Each call carries the API key of the organization.


    The API sends each error in the RFC 9457 format
    (`application/problem+json`), with a stable `code`.

    In addition to the errors of each endpoint, any path under `/api/v1` can
    return these errors:


    - `404` with `route_not_found`: the API does not have the path, or the path
    does not accept the HTTP method.

    - `405` with `method_not_allowed`: the API does not recognize the HTTP
    method.

    - `406` with `not_acceptable`: the API does not recognize the `Content-Type`
    or the `Accept` of the call.

    - another `4xx` status with `request_refused`: the API could not complete
    the call.

    - a `5xx` status with `internal_error`: QX had an internal error.
servers:
  - url: https://app.useqx.com/api/v1
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Collections
    description: >-
      The collections of the organization. A collection asks the contact for the
      documents of a pack.
  - name: Contacts
    description: >-
      The people and the companies of the organization. A person has a CPF, and
      a company has a CNPJ.
  - name: Documents
    description: >-
      The documents of the organization. A document sent without a collection
      goes to Triage. A document sent with a collection fills the slot of its
      type.
  - name: Packs
    description: The packs of the organization and the requirements of each pack.
paths:
  /collections:
    post:
      tags:
        - Collections
      summary: Create a collection
      description: >-
        Creates a collection with a pack. With a contact, the API creates the
        collection with the slots of the pack requirements. Without a contact,
        the API creates the collection for a recipient and sends the invitation
        to the email of the recipient. QX creates the slots after the recipient
        identifies themselves on the portal. The creation counts toward the paid
        write limit of the key.
      operationId: createCollection
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CollectionInput'
            examples:
              contact:
                summary: A collection for a contact, without an invitation
                value:
                  pack_id: pck_12
                  contact_id: com_12
              tax_id_with_invitation:
                summary: A collection for the contact of a CNPJ, with an invitation
                value:
                  pack_id: pck_12
                  tax_id: 12.345.678/0001-95
                  send_invitation: true
              recipient:
                summary: A collection without a contact, for a recipient
                value:
                  pack_id: pck_12
                  recipient:
                    name: Importadora Exemplo Ltda
                    email: fiscal@importadora.com.br
      responses:
        '201':
          description: The new collection, with the documents.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Collection'
              examples:
                contact:
                  summary: >-
                    The collection of the contact, with an empty slot for each
                    requirement of the pack
                  value:
                    id: col_40
                    protocol: DOC-2026-00123
                    state: assembling
                    discarded: false
                    contact:
                      id: com_12
                      type: company
                      name: Importadora Exemplo Ltda
                    recipient: null
                    packs:
                      - id: pck_12
                        name: Importação marítima
                    numbers: []
                    created_at: '2026-09-25T10:31:12.000-03:00'
                    ready_at: null
                    documents:
                      - id: doc_310
                        document_type:
                          id: dtp_31
                          name: Fatura Comercial (Commercial Invoice)
                        status: pending
                        has_content: false
                      - id: doc_311
                        document_type:
                          id: dtp_32
                          name: Bill of Lading (B/L)
                        status: pending
                        has_content: false
                      - id: doc_312
                        document_type:
                          id: dtp_33
                          name: Romaneio de Carga (Packing List)
                        status: pending
                        has_content: false
                recipient:
                  summary: >-
                    The collection of the recipient, without slots until the
                    recipient identifies themselves on the portal
                  value:
                    id: col_41
                    protocol: DOC-2026-00124
                    state: assembling
                    discarded: false
                    contact: null
                    recipient:
                      name: Importadora Exemplo Ltda
                      email: fiscal@importadora.com.br
                    packs:
                      - id: pck_12
                        name: Importação marítima
                    numbers: []
                    created_at: '2026-09-25T10:35:40.000-03:00'
                    ready_at: null
                    documents: []
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          description: >-
            The subscription of the organization is blocked. The API also
            returns `402` when an organization on trial reaches the document
            limit of the trial.
          content:
            application/problem+json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Problem'
                  - type: object
                    properties:
                      code:
                        enum:
                          - subscription_blocked
                          - trial_limit_reached
              examples:
                trial_limit_reached:
                  summary: The organization on trial reached the limit
                  value:
                    type: about:blank
                    title: Payment Required
                    status: 402
                    detail: >-
                      The organization reached the document limit of the trial
                      period. Subscribe to a plan in QX to create new
                      collections.
                    code: trial_limit_reached
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: >-
            The pack or the contact of `contact_id` does not exist in the key's
            organization.
          content:
            application/problem+json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Problem'
                  - type: object
                    properties:
                      code:
                        enum:
                          - not_found
              examples:
                not_found:
                  $ref: '#/components/examples/NotFound'
        '409':
          $ref: '#/components/responses/IdempotencyKeyInUseOrStale'
        '422':
          description: >-
            A field has an error, or the organization cannot create the
            collection with this pack and this contact. The `code` gives the
            reason. The API also returns `422` when the `Idempotency-Key`
            already served a call with different content.
          content:
            application/problem+json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/ValidationProblem'
                  - $ref: '#/components/schemas/CollectionRefusedProblem'
                  - $ref: '#/components/schemas/IdempotencyKeyReusedProblem'
              examples:
                pack_unavailable:
                  summary: The pack is inactive
                  value:
                    type: about:blank
                    title: Unprocessable Content
                    status: 422
                    detail: The pack is archived or inactive. Choose an active pack.
                    code: pack_unavailable
                validation_failed:
                  summary: The call did not include the pack
                  value:
                    type: about:blank
                    title: Unprocessable Content
                    status: 422
                    detail: >-
                      One or more fields have an error. The errors list gives
                      the error of each field.
                    code: validation_failed
                    errors:
                      - field: pack_id
                        code: blank
                        message: Send the id of the pack.
                idempotency_key_reused:
                  $ref: '#/components/examples/IdempotencyKeyReused'
        '429':
          $ref: '#/components/responses/TooManyRequests'
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      description: >-
        A unique value that your system creates for each write, such as a UUID.
        A repeated call with the same value and the same content gets the first
        response, and the API writes nothing new. The API keeps the response for
        24 hours.
      schema:
        type: string
        minLength: 1
        maxLength: 255
      example: 5f0c7e8a-3a1b-4d2e-9c61-2b7f4e0d9a13
  schemas:
    CollectionInput:
      type: object
      additionalProperties: false
      required:
        - pack_id
      properties:
        pack_id:
          type: string
          description: The id of the pack of the collection. The pack must be active.
          examples:
            - pck_12
        contact_id:
          type: string
          description: >-
            The id of the contact of the collection. Send the `contact_id` or
            the `tax_id`, only one of the two.
          examples:
            - com_12
        tax_id:
          type: string
          description: >-
            The CPF or the CNPJ of the collection's contact, with or without
            punctuation. Send the `contact_id` or the `tax_id`, only one of the
            two.
          examples:
            - 12.345.678/0001-95
        recipient:
          $ref: '#/components/schemas/CollectionRecipient'
        send_invitation:
          type: boolean
          default: false
          description: >-
            With `true`, QX creates the invitation and sends the contact an
            email with the portal link. The value applies only to a collection
            with a contact. On a collection without a contact, QX always sends
            the invitation to the recipient.
    Collection:
      description: A collection, with the list of documents.
      allOf:
        - $ref: '#/components/schemas/CollectionFields'
        - type: object
          required:
            - documents
          properties:
            documents:
              type: array
              description: >-
                The documents of the collection, from the oldest to the newest.
                The list does not include a discarded document.
              items:
                $ref: '#/components/schemas/CollectionDocument'
      unevaluatedProperties: false
    Problem:
      type: object
      description: An error in the RFC 9457 format.
      required:
        - type
        - title
        - status
        - detail
        - code
      properties:
        type:
          type: string
          const: about:blank
          description: Always `about:blank`.
        title:
          type: string
          description: The phrase of the HTTP status, in English.
          examples:
            - Unauthorized
        status:
          type: integer
          description: The HTTP status.
          examples:
            - 401
        detail:
          type: string
          description: >-
            The explanation of the error, in the language of the organization.
            An answer that leaves before the key identifies the organization
            stays in Portuguese.
        code:
          type: string
          description: >-
            The error code, in English. The code does not change between
            versions of v1.
    ValidationProblem:
      description: A validation error. The `errors` list gives the error of each field.
      allOf:
        - $ref: '#/components/schemas/Problem'
        - type: object
          required:
            - errors
          properties:
            code:
              enum:
                - validation_failed
            errors:
              type: array
              items:
                $ref: '#/components/schemas/FieldError'
    CollectionRefusedProblem:
      description: >-
        The organization cannot create the collection with this pack and this
        contact.
      allOf:
        - $ref: '#/components/schemas/Problem'
        - type: object
          properties:
            code:
              enum:
                - contact_not_found
                - contact_archived
                - pack_unavailable
                - pack_not_for_contact
                - no_email
                - shareholder_tree_too_large
              description: >-
                `contact_not_found`: the organization has no contact with the
                `tax_id`. `contact_archived`: the contact is archived.
                `pack_unavailable`: the pack is archived or inactive.
                `pack_not_for_contact`: the pack does not serve the type of the
                contact. `no_email`: the invitation needs the email of the
                contact, and the contact has no email.
                `shareholder_tree_too_large`: the shareholder tree of the
                contact has more than 200 people and companies. The tree
                includes the contact. The pack asks for a document from each
                shareholder.
    IdempotencyKeyReusedProblem:
      description: The `Idempotency-Key` already served a call with different content.
      allOf:
        - $ref: '#/components/schemas/Problem'
        - type: object
          properties:
            code:
              enum:
                - idempotency_key_reused
    CollectionRecipient:
      type: object
      additionalProperties: false
      required:
        - name
        - email
      description: >-
        The recipient of a collection without a contact. The recipient gets the
        invitation and identifies themselves on the portal with the CPF or the
        CNPJ. Send the recipient only when the call has no `contact_id` and no
        `tax_id`.
      properties:
        name:
          type: string
          description: The name of the recipient.
          examples:
            - Importadora Exemplo Ltda
        email:
          type: string
          format: email
          description: The email of the recipient.
          examples:
            - fiscal@importadora.com.br
    CollectionFields:
      type: object
      description: The fields of every collection.
      required:
        - id
        - protocol
        - state
        - discarded
        - contact
        - recipient
        - packs
        - numbers
        - created_at
        - ready_at
      properties:
        id:
          type: string
          pattern: ^col_[1-9][0-9]*$
          description: The id of the collection.
          examples:
            - col_40
        protocol:
          type: string
          description: The protocol of the collection.
          examples:
            - DOC-2026-00123
        state:
          $ref: '#/components/schemas/CollectionState'
        discarded:
          type: boolean
          description: With `true`, the collection is archived.
        contact:
          description: >-
            The contact of the collection. The value is `null` on a collection
            without a contact, until the recipient identifies themselves.
          anyOf:
            - $ref: '#/components/schemas/CollectionContact'
            - type: 'null'
        recipient:
          description: >-
            The recipient of a collection created without a contact. On a
            collection created with a contact, the value is `null`.
          anyOf:
            - $ref: '#/components/schemas/CollectionRecipient'
            - type: 'null'
        packs:
          type: array
          description: The packs that the collection asks for.
          items:
            $ref: '#/components/schemas/PackReference'
        numbers:
          type: array
          description: >-
            The operation numbers, as the collection screen shows them. The list
            includes the numbers printed on the documents of the identifier
            requirements of the pack. Without these numbers, the list includes
            the numbers printed on the other documents of the collection. On a
            collection without an operation pack, the list is empty.
          items:
            type: string
          examples:
            - - INV-81244/2026
        created_at:
          type: string
          format: date-time
          description: >-
            The date and the time of the creation, in the time zone of the
            organization.
          examples:
            - '2026-09-25T10:30:00.000-03:00'
        ready_at:
          type:
            - string
            - 'null'
          format: date-time
          description: >-
            The date and the time when the collection last became ready, in the
            time zone of the organization. The value is `null` when the
            collection never became ready.
    CollectionDocument:
      type: object
      additionalProperties: false
      required:
        - id
        - document_type
        - status
        - has_content
      properties:
        id:
          type: string
          pattern: ^doc_[1-9][0-9]*$
          description: The id of the document.
          examples:
            - doc_310
        document_type:
          $ref: '#/components/schemas/DocumentTypeReference'
        status:
          type: string
          enum:
            - pending
            - uploaded
            - approved
            - rejected
          description: >-
            The progress of the document. `pending`: the document waits for the
            upload. `uploaded`: the document arrived and waits for the review.
            `approved`: the operator approved the document. `rejected`: the
            operator rejected the document.
        has_content:
          type: boolean
          description: >-
            With `true`, the document has an attached file or a field with an
            answer. With `false`, the document is an empty slot.
    IdempotencyKeyInUseProblem:
      description: Another call with the same `Idempotency-Key` is still in progress.
      allOf:
        - $ref: '#/components/schemas/Problem'
        - type: object
          properties:
            code:
              enum:
                - idempotency_key_in_use
    StaleProblem:
      description: >-
        The data changed during the call. The call created no document and no
        collection.
      allOf:
        - $ref: '#/components/schemas/Problem'
        - type: object
          properties:
            code:
              enum:
                - stale
    FieldError:
      type: object
      additionalProperties: false
      required:
        - field
        - code
        - message
      properties:
        field:
          type: string
          description: The name of the field with the error.
        code:
          type: string
          description: The error code of the field, in English.
        message:
          type: string
          description: >-
            The explanation of the field error, in the language of the
            organization.
    CollectionState:
      type: string
      enum:
        - assembling
        - reviewing
        - ready_to_dispatch
        - awaiting_partner
        - cancelled
      description: >-
        The state of the collection. `assembling`: the collection is in assembly
        and waits for the documents. `reviewing`: the operator reviews the
        documents. `ready_to_dispatch`: every required document arrived, and no
        validation blocks the collection. `awaiting_partner`: the operator sent
        the collection to the partner. `cancelled`: the operator canceled the
        collection.
    CollectionContact:
      type: object
      additionalProperties: false
      required:
        - id
        - type
        - name
      properties:
        id:
          type: string
          pattern: ^(per|com)_[1-9][0-9]*$
          description: The id of the contact.
          examples:
            - com_12
        type:
          type: string
          enum:
            - person
            - company
          description: '`person` for a person and `company` for a company.'
        name:
          type:
            - string
            - 'null'
          description: The name of the contact.
          examples:
            - Importadora Exemplo Ltda
    PackReference:
      type: object
      additionalProperties: false
      required:
        - id
        - name
      properties:
        id:
          type: string
          pattern: ^pck_[1-9][0-9]*$
          description: The id of the pack.
          examples:
            - pck_12
        name:
          type: string
          description: The name of the pack.
          examples:
            - Importação marítima
    DocumentTypeReference:
      type: object
      additionalProperties: false
      required:
        - id
        - name
      properties:
        id:
          type: string
          pattern: ^dtp_[1-9][0-9]*$
          description: The id of the document type.
          examples:
            - dtp_31
        name:
          type: string
          description: The name of the document type.
          examples:
            - Fatura Comercial (Commercial Invoice)
  responses:
    BadRequest:
      description: >-
        The API refused the call. The `code` gives the reason:


        - `invalid_parameter`: a parameter is missing or has an invalid value.

        - `malformed_request`: the API could not read the call. Examples of
        causes:
          - the path or the query has an invalid encoding;
          - the query repeats a parameter in different forms, such as `limit=1&limit[]=2`;
          - the body is not valid JSON;
          - the address in the `Client-IP` header is not in the `X-Forwarded-For` header.
      content:
        application/problem+json:
          schema:
            allOf:
              - $ref: '#/components/schemas/Problem'
              - type: object
                properties:
                  code:
                    enum:
                      - invalid_parameter
                      - malformed_request
          examples:
            invalid_parameter:
              summary: The limit is above 100
              value:
                type: about:blank
                title: Bad Request
                status: 400
                detail: The limit parameter has an invalid value.
                code: invalid_parameter
            malformed_request:
              $ref: '#/components/examples/MalformedRequest'
    Unauthorized:
      description: The key is missing, does not exist or is revoked.
      headers:
        WWW-Authenticate:
          $ref: '#/components/headers/WwwAuthenticate'
      content:
        application/problem+json:
          schema:
            allOf:
              - $ref: '#/components/schemas/Problem'
              - type: object
                properties:
                  code:
                    enum:
                      - unauthorized
          examples:
            unauthorized:
              summary: The key is missing or not valid
              value:
                type: about:blank
                title: Unauthorized
                status: 401
                detail: >-
                  The call did not include a valid API key. Send the key in the
                  Authorization header, in the format Bearer <key>.
                code: unauthorized
    Forbidden:
      description: >-
        The organization is archived, or the plan of the organization does not
        include the API.
      content:
        application/problem+json:
          schema:
            allOf:
              - $ref: '#/components/schemas/Problem'
              - type: object
                properties:
                  code:
                    enum:
                      - organization_archived
                      - plan_required
          examples:
            plan_required:
              summary: The free plan does not include the API
              value:
                type: about:blank
                title: Forbidden
                status: 403
                detail: >-
                  The free plan does not include the API. Subscribe to a paid
                  plan in QX to use the API.
                code: plan_required
    IdempotencyKeyInUseOrStale:
      description: >-
        The write found a conflict. The `code` tells which conflict.
        `idempotency_key_in_use`: another call with the same `Idempotency-Key`
        is still in progress. Wait for that call to end, and then repeat the
        call with the same value. `stale`: the data changed during the call. The
        call created no document and no collection. Call again. If the call
        included an `Idempotency-Key`, use a new value, because the API keeps
        the `409` response.
      content:
        application/problem+json:
          schema:
            anyOf:
              - $ref: '#/components/schemas/IdempotencyKeyInUseProblem'
              - $ref: '#/components/schemas/StaleProblem'
          examples:
            idempotency_key_in_use:
              $ref: '#/components/examples/IdempotencyKeyInUse'
            stale:
              $ref: '#/components/examples/Stale'
    TooManyRequests:
      description: The key or the IP address went over a limit.
      headers:
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/problem+json:
          schema:
            allOf:
              - $ref: '#/components/schemas/Problem'
              - type: object
                properties:
                  code:
                    enum:
                      - rate_limited
                      - daily_limit_reached
                      - too_many_invalid_keys
          examples:
            rate_limited:
              summary: The key went over the per-minute limit
              value:
                type: about:blank
                title: Too Many Requests
                status: 429
                detail: >-
                  The key went over a per-minute limit. Wait for the seconds in
                  the Retry-After header and call again.
                code: rate_limited
  examples:
    NotFound:
      summary: The id does not exist in the key's organization
      value:
        type: about:blank
        title: Not Found
        status: 404
        detail: The resource does not exist in the key's organization.
        code: not_found
    IdempotencyKeyReused:
      summary: The Idempotency-Key already served another call
      value:
        type: about:blank
        title: Unprocessable Content
        status: 422
        detail: >-
          This Idempotency-Key already served a call with different content. Use
          a new value for the new call.
        code: idempotency_key_reused
    MalformedRequest:
      summary: The API could not read the call
      value:
        type: about:blank
        title: Bad Request
        status: 400
        detail: >-
          The API could not read the call. Check the shape and the encoding of
          the path and the query, the JSON of the body and the headers.
        code: malformed_request
    IdempotencyKeyInUse:
      summary: Another call with the same Idempotency-Key is in progress
      value:
        type: about:blank
        title: Conflict
        status: 409
        detail: >-
          Another call with this Idempotency-Key is still in progress. Wait for
          that call to end and call again.
        code: idempotency_key_in_use
    Stale:
      summary: The data changed during the call
      value:
        type: about:blank
        title: Conflict
        status: 409
        detail: >-
          The data changed during the call. The call created no document and no
          collection. Call again. If the call included an Idempotency-Key, use a
          new value.
        code: stale
  headers:
    WwwAuthenticate:
      description: The authentication scheme that the API expects.
      required: true
      schema:
        type: string
      example: Bearer realm="QX API"
    RetryAfter:
      description: The seconds to wait before the next call.
      required: true
      schema:
        type: integer
        minimum: 1
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        The API key of the organization, in the `Authorization: Bearer <key>`
        header. The key starts with `qx_`.

````