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

# List Certificate Uploads

> Retrieve a paginated list of certificate uploads

Retrieve a paginated list of certificate uploads for your account, ordered
by id ascending. Filter by status and customer. Uploads in every status are
included — filter by `status` to narrow.

<Note>
  Remember to include the `X-API-Version: 2026-03-01` header — older versions
  return `INVALID_REQUEST` (400). Certificate endpoints are live-only — using a
  `sk_test_*` key returns `TESTMODE_NOT_SUPPORTED` (400).
</Note>

## Filtering by status

`status` accepts the certificate-upload vocabulary. This is a separate
vocabulary from certificate statuses — an upload is a processing job, a
certificate is its output.

| Value        | Description                                                                                    |
| ------------ | ---------------------------------------------------------------------------------------------- |
| `processing` | Numeral is still downloading or classifying the document. `certificate_ids` is empty.          |
| `completed`  | Processing finished. `certificate_ids` lists the resulting certificates.                       |
| `failed`     | Processing failed. `error_message` explains why.                                               |
| `duplicate`  | The same document bytes and filename were already submitted. The document was not reprocessed. |

Any other value returns `INVALID_REQUEST` (400).

## Filtering by customer

Pass `customer_id` together with `id_type` to narrow by buyer:

* `id_type=id` (default) — match against the Numeral customer id.
* `id_type=reference_customer_id` — match against your reference id.

Only live, live-mode customers match. An unknown `id_type` returns
`INVALID_REQUEST` (400) with the message
"Invalid id\_type. Must be one of: id, reference\_customer\_id".

## Pagination

Responses use cursor pagination. `next_cursor` is the last id of the
current page and is present only when `has_more` is `true` — pass it back
as `cursor` to fetch rows with a greater id. A malformed cursor returns
`INVALID_REQUEST` (400) with the message "Invalid cursor."

## No `document_url` on list items

List items deliberately omit `document_url` — presigned links are expensive
to mint. Fetch
[`GET /tax/certificate-uploads/{upload_id}`](/api-reference/v2026-03-01/endpoint/get_certificate_upload)
for the document.


## OpenAPI

````yaml GET /tax/certificate-uploads
openapi: 3.0.1
info:
  title: Numeral API
  description: >-
    API for sales tax calculations - Version 2026-03-01. This version adds
    IP-based tax resolution for calculations and platform calculations, in
    addition to Merchant management and Platform Calculations.
  license:
    name: MIT
  version: '2026-03-01'
servers:
  - url: https://api.numeralhq.com/
security:
  - bearerAuth: []
paths:
  /tax/certificate-uploads:
    get:
      summary: List Certificate Uploads
      description: >-
        Retrieve a paginated list of certificate uploads, ordered by id
        ascending. Filter by status and customer. List items omit `document_url`
        — fetch a single upload for the document link. Live-only.
      operationId: listCertificateUploads_v20260301
      parameters:
        - name: X-API-Version
          in: header
          required: true
          schema:
            type: string
            enum:
              - '2026-03-01'
          description: >-
            Must be `2026-03-01` or later. Older versions return
            `INVALID_REQUEST` (400).
        - name: status
          in: query
          required: false
          schema:
            $ref: '#/components/schemas/CertificateUploadStatus'
          description: >-
            Filter by upload status. Any other value returns `INVALID_REQUEST`
            (400).
        - name: customer_id
          in: query
          required: false
          schema:
            type: string
          description: >-
            Filter to one customer. Interpreted per `id_type`. Matches only
            live, live-mode customers.
        - name: id_type
          in: query
          required: false
          schema:
            type: string
            enum:
              - id
              - reference_customer_id
            default: id
          description: >-
            How to interpret `customer_id`. Use `id` (the default) for the
            Numeral customer id, or `reference_customer_id` for your own id. Any
            other value returns `INVALID_REQUEST` (400).
        - name: cursor
          in: query
          required: false
          schema:
            type: string
          description: >-
            Pagination cursor — pass `next_cursor` from the previous response
            (an `upl_*` id; the bare numeric form is also accepted). Returns
            rows with an id greater than the cursor. Malformed values return
            `INVALID_REQUEST` (400).
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 10
          description: Max items per page (1–100). Defaults to 10.
      responses:
        '200':
          description: Certificate upload list
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CertificateUploadListResponse'
              example:
                object: list
                certificate_uploads:
                  - id: upl_4469
                    object: tax.certificate_upload
                    status: failed
                    customer: null
                    certificate_ids: []
                    error_message: >-
                      Document could not be classified as an exemption
                      certificate.
                    created_at: '2026-09-15T16:41:37.000Z'
                    livemode: true
                  - id: upl_4470
                    object: tax.certificate_upload
                    status: completed
                    customer:
                      id: cust_6126acaf-7379-411a-8ada-00005bac0715
                      reference_customer_id: '20506'
                    certificate_ids:
                      - cert_a8f3d2c1-1b9a-4c5e-8d7e-6f4a3b2c1d0e
                    error_message: null
                    created_at: '2026-09-15T16:58:02.000Z'
                    livemode: true
                  - id: upl_4471
                    object: tax.certificate_upload
                    status: processing
                    customer:
                      id: cust_6126acaf-7379-411a-8ada-00005bac0715
                      reference_customer_id: '20506'
                    certificate_ids: []
                    error_message: null
                    created_at: '2026-09-15T17:04:11.000Z'
                    livemode: true
                has_more: true
                next_cursor: upl_4471
        '400':
          description: >-
            `INVALID_REQUEST` (bad `status`, `id_type`, `cursor`, or API version
            below 2026-03-01) or `TESTMODE_NOT_SUPPORTED`
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    CertificateUploadStatus:
      type: string
      enum:
        - processing
        - completed
        - failed
        - duplicate
      description: >-
        Processing state of a certificate upload. This is a separate vocabulary
        from certificate `status` — an upload is a processing job, a certificate
        is its output. `processing` is the only non-terminal state; `completed`
        (certificates produced), `failed` (see `error_message`), and `duplicate`
        (same document already submitted) are terminal.
    CertificateUploadListResponse:
      type: object
      description: A paginated list of certificate uploads.
      properties:
        object:
          type: string
          enum:
            - list
        certificate_uploads:
          type: array
          items:
            $ref: '#/components/schemas/CertificateUploadResponse'
        has_more:
          type: boolean
          description: Whether there are more uploads to fetch.
        next_cursor:
          type: string
          description: >-
            Pass as `cursor` on the next request. Present only when `has_more`
            is `true`.
          example: upl_4471
      required:
        - object
        - certificate_uploads
        - has_more
    Error:
      type: object
      description: Standard error response format for API version 2026-01-01
      properties:
        code:
          type: integer
          description: HTTP status code
          example: 400
        type:
          type: string
          description: Machine-readable error type
          example: MISSING_FIELD
        message:
          type: string
          description: Human-readable error message
          example: Required field 'address_country' is missing
      required:
        - code
        - type
        - message
    CertificateUploadResponse:
      type: object
      description: >-
        A certificate upload — the asynchronous processing job created by `POST
        /tax/certificates`.
      properties:
        id:
          type: string
          description: >-
            Upload id, `upl_<number>`. Endpoints that accept an upload id also
            accept the bare numeric form.
          example: upl_4471
        object:
          type: string
          description: 'The type of object: `tax.certificate_upload`'
          example: tax.certificate_upload
        status:
          $ref: '#/components/schemas/CertificateUploadStatus'
        customer:
          allOf:
            - $ref: '#/components/schemas/CertificateUploadCustomer'
          nullable: true
          description: >-
            The customer supplied at submission. `null` when the upload was
            submitted without a customer — attribution then happens during
            processing.
        certificate_ids:
          type: array
          items:
            type: string
            example: cert_a8f3d2c1-1b9a-4c5e-8d7e-6f4a3b2c1d0e
          description: >-
            Certificates produced by this upload, usable with the certificate
            endpoints. Empty while `status` is `processing`; populated at
            `completed`. One document can yield multiple certificates.
        error_message:
          type: string
          nullable: true
          description: >-
            Human-readable reason processing failed. Also set on `duplicate`
            uploads when the original upload had failed, so you can see why
            re-submitting the same bytes will not help.
        created_at:
          type: string
          format: date-time
          nullable: true
        livemode:
          type: boolean
          enum:
            - true
          description: Always `true` — these endpoints are live-only.
      required:
        - id
        - object
        - status
        - customer
        - certificate_ids
        - error_message
        - created_at
        - livemode
    CertificateUploadCustomer:
      type: object
      description: The customer the upload was attributed to at submission.
      properties:
        id:
          type: string
          example: cust_6126acaf-7379-411a-8ada-00005bac0715
        reference_customer_id:
          type: string
          nullable: true
          example: '20506'
      required:
        - id
        - reference_customer_id
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer

````