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

# Download tax documents in batch

> Bundles the XML or PDF files of several tax documents into one zip and returns a temporary download link.

Say which documents to bundle with exactly one of `taxDocumentIds` and `filters`. With `taxDocumentIds` you choose the documents yourself; duplicate ids count once, and an id that is not one of your organization's is reported in `missing` as `NOT_FOUND`. With `filters` every document that matches is bundled, using the same filters as List tax documents (`environment` included); at least one filter is required, so an empty body is never read as "everything", and each range must end on or after its start.

`type` chooses which file of each document goes in the zip: `XML` (the default) or `PDF`. A zip holds at most 1 000 XML files or 200 PDF files. A selection above the limit is rejected as a bad request, and a filter that matches more documents than the limit is rejected with `TAX_DOCUMENT_BATCH_DOWNLOAD_LIMIT_EXCEEDED`: narrow the filters, for example to a shorter date range, or select the documents yourself in smaller groups.

The zip has one file per document, named by its NFSe number (`NFSe-1042.xml`), or by its RPS number (`RPS-1-1042.xml`) before it is authorized, or by its ID. Test-environment documents are prefixed with `HOMOLOGACAO-`, and when two documents would share a name the document's ID is appended. It also holds `manifest.csv`, which lists every requested or matched document with its file name, IDs, NFSe and RPS numbers, status, environment, dates, customer, total value in reais and, for the ones left out, the reason.

A document that has no file of the requested type yet, for example because it is not authorized yet, does not fail the request: it is left out of the zip and listed in `missing` with the reason `FILE_NOT_AVAILABLE`. The request fails only when no document has a file to include. The link in `url` expires after `expiresInSeconds` seconds (1 hour).


## OpenAPI

````yaml /api-reference/accounting.openapi.json post /realms/{realmId}/organizations/{organizationId}/tax-document/download-batch
openapi: 3.0.3
info:
  title: Accounting
  version: 1.0.0
  description: >-
    Portão 3 accounting API. Every endpoint requires a bearer token in the
    Authorization header (Authorization: Bearer <token>) unless its page states
    otherwise; see the Authentication guide. That requirement is not repeated
    per endpoint. Generated by tools/openapi from code (routes + security) and
    the hand-written spec (request/response bodies). NFSe issuance: the
    organization's tax issuer (setup, certificate, logo), its tax documents
    (issue, list, download, cancel, CSV batches) and the city special-tax-regime
    lookup. Every route validates path, query, body and multipart form through a
    zod Input class (`accounting/app/use-case/*/inputs`), which documents it;
    responses are the named interfaces in
    `accounting/app/use-case/*/outputs/*Response.ts`. Confidence tiers:
    generated:typed=24 copied:manual=0 unknown=0.
servers:
  - url: https://api.accounting.v2.portao3.com.br/
    description: production
  - url: https://api.accounting.dev.3pers.com.br/
    description: development
security: []
tags:
  - name: Tax Issuers
  - name: Tax Documents (NFSe)
  - name: Tax Codes
paths:
  /realms/{realmId}/organizations/{organizationId}/tax-document/download-batch:
    post:
      tags:
        - Tax Documents (NFSe)
      summary: Download tax documents in batch
      description: >-
        Bundles the XML or PDF files of several tax documents into one zip and
        returns a temporary download link.
      operationId: postRealmsByRealmIdOrganizationsByOrganizationIdTaxDocumentDownloadBatch
      parameters:
        - name: realmId
          in: path
          required: true
          description: |-
            ID of your realm.

            Format: `UUID`
          schema:
            type: string
            format: uuid
          example: f495ff0c-ab54-4f99-8e92-ca8682e4de9b
        - name: organizationId
          in: path
          required: true
          description: |-
            ID of the organization.

            Format: `UUID`
          schema:
            type: string
            format: uuid
          example: c4bd3f21-dfbd-44e8-8055-68ba15bed410
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                type:
                  description: >-
                    Which file of each tax document to bundle: `XML` or `PDF`.
                    Defaults to `XML`. A zip holds at most 1 000 XML files or
                    200 PDF files.
                  example: XML
                  type: string
                  enum:
                    - PDF
                    - XML
                taxDocumentIds:
                  description: >-
                    Selection mode: the `id` of each tax document to bundle.
                    Duplicates count once. At most 1 000 distinct ids for `XML`
                    and 200 for `PDF`. Send either this or `filters`, never
                    both.


                    ---


                    Example:
                    `["3d6f9a2b-1c4e-4f8a-9b7d-5e2c1a0f8b63","7a1c5e90-2b3d-4c6f-8e1a-9d4b0f2c7a35"]`
                  minItems: 1
                  type: array
                  items:
                    type: string
                    minLength: 1
                    example: 3d6f9a2b-1c4e-4f8a-9b7d-5e2c1a0f8b63
                filters:
                  description: >-
                    Filter mode: bundle every tax document that matches, using
                    the same filters as List tax documents. At least one filter
                    is required, and a filter that matches more than 1 000
                    documents (200 for `PDF`) is rejected. Send either this or
                    `taxDocumentIds`, never both.
                  type: object
                  properties:
                    status:
                      description: |-
                        Only documents in one of these statuses.

                        ---

                        Example: `["AUTHORIZED","DENIED"]`
                      type: array
                      items:
                        type: string
                        enum:
                          - WAITINGFORAUTHORIZATION
                          - REQUESTINGAUTHORIZATION
                          - AUTHORIZATIONREQUESTED
                          - AUTHORIZATIONPROCESS
                          - AWAITINGFILEGENERATION
                          - AUTHORIZED
                          - DENIED
                          - REQUESTINGCANCELLATION
                          - CANCELLATIONREQUESTED
                          - CANCELLATIONPROCESS
                          - AWAITINGFILECANCELATION
                          - CANCELED
                          - CANCELLATIONDENIED
                        example: AUTHORIZED
                    type:
                      description: |-
                        Only documents of one of these types.

                        ---

                        Example: `["NFSE"]`
                      type: array
                      items:
                        type: string
                        enum:
                          - NFSE
                        example: NFSE
                    environment:
                      description: >-
                        `LIVE` for real documents, `TEST` for homologation
                        documents (no fiscal value). Omit to match both.
                      example: LIVE
                      type: string
                      enum:
                        - LIVE
                        - TEST
                    issuedAtStart:
                      description: >-
                        Only documents issued on or after this moment. A date
                        without a time (`2026-10-01`) means 00:00 UTC.
                      example: '2026-10-01T00:00:00.000Z'
                      type: string
                      format: date-time
                    issuedAtEnd:
                      description: >-
                        Only documents issued on or before this moment. Must not
                        be before `issuedAtStart`. To include a whole day, send
                        `T23:59:59.999Z` of that day.
                      example: '2026-10-31T23:59:59.999Z'
                      type: string
                      format: date-time
                    competenceDateStart:
                      description: >-
                        Only documents whose competence date is on or after this
                        moment. A date without a time means 00:00 UTC.
                      example: '2026-10-01T00:00:00.000Z'
                      type: string
                      format: date-time
                    competenceDateEnd:
                      description: >-
                        Only documents whose competence date is on or before
                        this moment. Must not be before `competenceDateStart`.
                        To include a whole day, send `T23:59:59.999Z` of that
                        day.
                      example: '2026-10-31T23:59:59.999Z'
                      type: string
                      format: date-time
                    rpsNumberStart:
                      description: >-
                        Only documents whose RPS number is greater than or equal
                        to this one.
                      example: 1000
                      type: number
                    rpsNumberEnd:
                      description: >-
                        Only documents whose RPS number is less than or equal to
                        this one. Must not be less than `rpsNumberStart`.
                      example: 1100
                      type: number
                    customerDocument:
                      description: >-
                        Only documents of the customer with this CPF or CNPJ,
                        with or without punctuation. An exact match, not a
                        partial one.
                      example: '12345678000195'
                      type: string
                    customerName:
                      description: >-
                        Only documents whose customer name contains this text
                        (case-insensitive).
                      example: acme
                      type: string
                  additionalProperties: false
              additionalProperties: false
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  fileName:
                    type: string
                    description: Suggested name of the zip file.
                    example: nfse-xml-2026-10-20_14-30-05.zip
                  url:
                    type: string
                    description: >-
                      Temporary link to download the zip. Opening it saves the
                      file. It stops working after `expiresInSeconds` seconds.
                    example: >-
                      https://downloads.example.com/nfse-xml-2026-10-20_14-30-05.zip?signature=abc123
                  expiresInSeconds:
                    type: number
                    description: >-
                      For how long `url` works, in seconds, counted from this
                      response.
                    example: 3600
                  total:
                    type: number
                    description: >-
                      Tax documents the request resolved to: the distinct ids
                      you sent (selection mode), or the documents the filters
                      matched (filter mode).
                    example: 3
                  included:
                    type: number
                    description: Files inside the zip, besides `manifest.csv`.
                    example: 2
                  missing:
                    type: array
                    items:
                      type: object
                      properties:
                        taxDocumentId:
                          type: string
                          description: >-
                            ID of the tax document. For `NOT_FOUND` it is the id
                            exactly as you sent it.
                          example: 7a1c5e90-2b3d-4c6f-8e1a-9d4b0f2c7a35
                        reason:
                          type: string
                          enum:
                            - NOT_FOUND
                            - FILE_NOT_AVAILABLE
                          description: >-
                            Why the document is not in the zip. `NOT_FOUND`: no
                            tax document with that id belongs to your
                            organization (selection mode only).
                            `FILE_NOT_AVAILABLE`: the document exists but has no
                            file of the requested type yet, for example because
                            it is not authorized yet or was denied.
                          example: FILE_NOT_AVAILABLE
                        nfseNumber:
                          type: string
                          description: >-
                            NFSe number given by the city hall, as text. Present
                            only for `FILE_NOT_AVAILABLE`, and only when the
                            document already has one.
                          example: '1042'
                        rpsNumber:
                          type: string
                          description: >-
                            RPS number of the document, as text. Present only
                            for `FILE_NOT_AVAILABLE`, and only when the document
                            has one.
                          example: '1042'
                        status:
                          type: string
                          description: >-
                            Current status of the tax document. Present only for
                            `FILE_NOT_AVAILABLE`.
                          example: AUTHORIZATIONPROCESS
                      required:
                        - taxDocumentId
                        - reason
                      description: >-
                        A tax document that was requested or matched but is not
                        in the zip.
                    description: >-
                      Every requested or matched tax document that is not in the
                      zip, and why. Empty when the zip holds all of them. They
                      are also listed in the zip's `manifest.csv`.
                    example:
                      - taxDocumentId: 7a1c5e90-2b3d-4c6f-8e1a-9d4b0f2c7a35
                        reason: FILE_NOT_AVAILABLE
                        rpsNumber: '1042'
                        status: AUTHORIZATIONPROCESS
                required:
                  - fileName
                  - url
                  - expiresInSeconds
                  - total
                  - included
                  - missing
                description: >-
                  The zip with the files of the requested tax documents, and
                  what was left out of it.
        '404':
          description: >-
            `TAX_DOCUMENT_BATCH_DOWNLOAD_EMPTY` — None of the requested or
            matched documents has a file of the requested type, so there is
            nothing to put in the zip.


            `TAX_ISSUER_NOT_FOUND` — Filter mode only: the organization has no
            active tax issuer.
          content:
            application/json:
              schema:
                type: object
                properties:
                  traceId:
                    type: string
                    description: >-
                      Identifier of the request that failed. Quote it when
                      contacting support.
                    example: 1-68ee2a1b-3c4d5e6f7a8b9c0d1e2f3a4b
                  code:
                    type: string
                    enum:
                      - TAX_DOCUMENT_BATCH_DOWNLOAD_EMPTY
                      - TAX_ISSUER_NOT_FOUND
                    description: >-
                      Stable, machine-readable error code. Branch on this, never
                      on `message`.
                  origin:
                    type: string
                    enum:
                      - ACCOUNTING
                    description: Service that produced the error.
                  message:
                    type: string
                    description: >-
                      Human-readable explanation. Its wording may change without
                      notice.
                required:
                  - traceId
                  - code
                  - origin
                  - message
              example:
                traceId: 1-68ee2a1b-3c4d5e6f7a8b9c0d1e2f3a4b
                code: TAX_DOCUMENT_BATCH_DOWNLOAD_EMPTY
                origin: ACCOUNTING
                message: >-
                  None of the requested tax documents has a file available for
                  download
        '422':
          description: >-
            `TAX_DOCUMENT_BATCH_DOWNLOAD_LIMIT_EXCEEDED` — Filter mode only: the
            filters match more documents than one zip can hold. The limit in the
            message is 1000 for `XML` and 200 for `PDF`.


            `BAD_REQUEST` — A path parameter is not a valid ID, the body is not
            a JSON object, it has neither `taxDocumentIds` nor a filter or has
            both, a field is invalid, or a selection is above the limit;
            `fields` lists each problem.
          content:
            application/json:
              schema:
                type: object
                properties:
                  traceId:
                    type: string
                    description: >-
                      Identifier of the request that failed. Quote it when
                      contacting support.
                    example: 1-68ee2a1b-3c4d5e6f7a8b9c0d1e2f3a4b
                  code:
                    type: string
                    enum:
                      - TAX_DOCUMENT_BATCH_DOWNLOAD_LIMIT_EXCEEDED
                      - BAD_REQUEST
                    description: >-
                      Stable, machine-readable error code. Branch on this, never
                      on `message`.
                  origin:
                    type: string
                    enum:
                      - ACCOUNTING
                    description: Service that produced the error.
                  message:
                    type: string
                    description: >-
                      Human-readable explanation. Its wording may change without
                      notice.
                  fields:
                    type: array
                    description: >-
                      One entry per invalid request field (validation errors
                      only).
                    items:
                      type: object
                      properties:
                        field:
                          type: string
                          description: >-
                            Path of the invalid field, e.g. `label` or
                            `values[0].value`.
                          example: label
                        message:
                          type: string
                          description: Why the field was rejected.
                          example: label is required
                        code:
                          type: string
                          description: >-
                            `<FIELD>_<REASON>` — e.g. `LABEL_REQUIRED`,
                            `TYPE_ONE_OF`, `VALUES_VALUE_TYPE_ERROR`.
                          example: LABEL_REQUIRED
                        values:
                          type: array
                          items:
                            type: string
                          description: >-
                            The accepted values, when the field is an
                            enumeration.
                      required:
                        - field
                        - message
                        - code
                required:
                  - traceId
                  - code
                  - origin
                  - message
              example:
                traceId: 1-68ee2a1b-3c4d5e6f7a8b9c0d1e2f3a4b
                code: TAX_DOCUMENT_BATCH_DOWNLOAD_LIMIT_EXCEEDED
                origin: ACCOUNTING
                message: >-
                  Too many tax documents match this batch download; narrow the
                  filters or select fewer documents (limit: 1000)

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.