> ## 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.

# Issue tax documents in batch

> Issues a tax document (NFSe) for every row of an uploaded CSV file.

Send a `multipart/form-data` request whose `file` part is a CSV file: comma-separated, with a header row and one row per tax document to issue. The header names are case-sensitive and the column order does not matter.

| Column | Required | Meaning |
| - | - | - |
| `environment` | Yes | `LIVE` to issue a real tax document, `TEST` to issue a test one. Your tax issuer must be configured for that environment. |
| `competenceDate` | Yes | Competence date of the service, for example `2026-10-31`. |
| `totalValue` | Yes | Total value of the service in reais, for example `1500.50`. A comma is accepted as the decimal separator (`1500,50`); do not use thousands separators. |
| `statementId` | Yes | ID of the invoice statement this tax document refers to. It is the idempotency key of the row: a statement that already has an active tax document is skipped. |
| `customerName` | Yes | Name of the customer. |
| `customerEmail` | Yes | E-mail address of the customer. |
| `customerFederalDocument` | Yes | Federal document of the customer, digits only: the CNPJ (or the CPF). |
| `customerMunicipalDocument` | No | Municipal registration of the customer. |
| `customerstateDocument` | No | State registration of the customer. |
| `customerphoneNumber` | Yes | Brazilian phone number of the customer with area code, for example `34984325252` or `+5534984325252`. A number that is not a valid Brazilian one is left off the tax document. |
| `addressState` | Yes | State of the customer's address, for example `MG`. |
| `addressCity` | Yes | City of the customer's address, for example `Uberlândia`. |
| `addressStreet` | Yes | Street of the customer's address. |
| `addressNumber` | Yes | Number of the customer's address. |
| `addressComplement` | No | Complement of the customer's address. `N/A` is used when it is blank. |
| `addressNeighborhood` | Yes | Neighborhood of the customer's address. |
| `addressPostalCode` | Yes | Postal code (CEP) of the customer's address. |

The column names are exactly as listed, including the spelling of `customerstateDocument`, `customerphoneNumber` and `addressNeighborhood`. Any other column is rejected, and so is a row that misses a required column.

Every tax document is issued with fixed values. The customer is registered as a company, the service is provided in Uberlândia (MG), and its description is "LICENCIAMENTO DE SOFTWARE - SAAS". The document records an ISS rate of 2% (the NFSe itself is issued with the ISS rate registered for your tax issuer), not withheld at source. The municipal service description is "Licenciamento ou cessão de direito de uso de programas de computação.", the operation nature is "Prestação de Serviços", and there are no deductions, no discounts and no observation. The municipal service code, the service list item, the CNAE and the tax configuration come from your tax issuer's configuration for the row's `environment`.

The whole upload is validated first: if any row is invalid nothing is issued, and `fields` points at the row by its position, where `invoices[0]` is the first row after the header. When the upload is valid, the response only means the rows were accepted. Each row is then issued in the background, so a row can still fail later; a row whose statement already has an active tax document is skipped, which makes it safe to upload the same file again. A row the tax provider rejects for invalid data is skipped as well: fix its data and upload it again.


## OpenAPI

````yaml /api-reference/accounting.openapi.json post /realms/{realmId}/organizations/{organizationId}/tax-document/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/batch:
    post:
      tags:
        - Tax Documents (NFSe)
      summary: Issue tax documents in batch
      description: Issues a tax document (NFSe) for every row of an uploaded CSV file.
      operationId: postRealmsByRealmIdOrganizationsByOrganizationIdTaxDocumentBatch
      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:
          multipart/form-data:
            schema:
              type: object
              properties:
                file:
                  type: string
                  format: binary
                  description: >-
                    The CSV file, with a header row and one row per tax document
                    to issue. The columns are listed in the operation
                    description. Required, not empty, at most 4 MB; its file
                    name must end in `.csv`, or its content type be `text/csv`,
                    `application/vnd.ms-excel` or `text/plain`.
              required:
                - file
              additionalProperties: false
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    description: >-
                      Confirms what was requested. It only means the rows were
                      accepted, not that every document was already issued or
                      cancelled.
                    example: Batch issuance requested.
                  count:
                    type: number
                    description: Number of CSV rows accepted for processing.
                    example: 25
                required:
                  - message
                  - count
                description: >-
                  Acknowledgement that a CSV batch was accepted. Each row is
                  processed in the background.
        '400':
          description: >-
            `TAX_ISSUER_PROVIDER_ID_NOT_FOUND` — The tax issuer is not
            registered with the tax provider yet.
          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_ISSUER_PROVIDER_ID_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_ISSUER_PROVIDER_ID_NOT_FOUND
                origin: ACCOUNTING
                message: Tax issuer provider id not exists
        '404':
          description: >-
            `TAX_ISSUER_NOT_FOUND` — The organization has no active tax issuer.


            `ISSUER_PROPERTIES_NOT_FOUND` — The tax issuer has no configuration
            for any environment.
          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_ISSUER_NOT_FOUND
                      - ISSUER_PROPERTIES_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_ISSUER_NOT_FOUND
                origin: ACCOUNTING
                message: Tax issuer not found
        '422':
          description: >-
            `BAD_REQUEST` — A path parameter is not a valid ID, the request is
            not `multipart/form-data`, the `file` part is missing, empty, larger
            than 4 MB or not a readable CSV, or a row failed validation;
            `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:
                      - 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: BAD_REQUEST
                origin: ACCOUNTING
                message: >-
                  Bad Request: Your request is invalid or incomplete. Please
                  make sure you are requesting with the right fields.
                fields:
                  - field: file
                    message: file is required
                    code: FILE_REQUIRED

````

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