---
title: "Queue 1 to 100 validations as one batch"
method: POST
path: "/v2/einvoices/batches"
tags: ["jobs"]
---

# Queue 1 to 100 validations as one batch

`POST /v2/einvoices/batches`

## Request

- Base URL: `https://api.ironfang.com/finance`
- URL: `https://api.ironfang.com/finance/v2/einvoices/batches`
- Auth: HTTP bearer

Accepts 1 to 100 jobs together, all or none: a job that would be
refused refuses the batch, and the Problem's `detail` names it by
position (`Job 3: ...`), as `errors[].field` does (`jobs[3].options`).
The documents together are at most 25 MiB (26,214,400 bytes) and the
envelope at most 36 MiB. PDFs are inspected on acceptance, within the
30-second hybrid deadline for the whole batch; a batch that cannot
be is `504 validation_timeout` and nothing is queued, so send fewer
PDFs at once. Each job then runs, is charged and is retained on its
own.

**Idempotency.** An `Idempotency-Key` names the whole batch: the
same key and envelope return the original batch (`200`), a
different envelope `409 idempotency_conflict`. Keys are V2's own,
apart from V1 batches and from synchronous validation.

## Headers

- `Idempotency-Key` string

## Request body

- BatchRequest
  - `jobs` JobRequest[], required
    - `document_base64` string, byte, required: The document's bytes, standard padded base64 without line breaks. XML at most 5 MiB, a PDF at most 20 MiB decoded.
    - `media_type` 'application/xml' | 'text/xml' | 'application/pdf', required: What the document is. The content must agree, or the job is `415 unsupported_content_type`.
    - `options` ValidationOptions: The multipart `options` part. The same names as the query parameters. Unknown or repeated keys are `400`.
      - `document_type` 'invoice' | 'credit_note' | 'auto'
      - `family` 'peppol-bis-billing-3' | 'xrechnung' | 'zugferd-facturx': An invoice family. `zugferd-facturx` is one family: ZUGFeRD and Factur-X are corresponding release names of the same standard.
      - `ruleset` string
      - `scope` 'xml' | 'hybrid_pdf'
      - `variant` 'core' | 'extension' | 'cvd' | 'minimum' | 'basic-wl' | 'basic' | 'en16931' | 'extended' | 'xrechnung': A variant or profile within a family. XRechnung: `core`, `extension`, `cvd`. ZUGFeRD / Factur-X: `minimum`, `basic-wl`, `basic`, `en16931`, `extended`, `xrechnung` (the ZUGFeRD XRECHNUNG reference profile). Peppol BIS Billing 3 has none. Recognition is not support: the ruleset list is the only statement of what is validated.

## Response `200`

The batch this Idempotency-Key already names, unchanged.

- Batch
  - `api_version` 'v1' | 'v2', required: The API a result was made through.
  - `counts` JobCounts, required
    - `cancelled` integer, required
    - `completed` integer, required
    - `failed` integer, required
    - `queued` integer, required
    - `running` integer, required
  - `created_at` string, date-time, required
  - `id` string, required
  - `jobs` Job[], required
    - `api_version` 'v1' | 'v2', required: The API a result was made through.
    - `attempts` integer, required
    - `batch_id` string
    - `created_at` string, date-time, required
    - `engine_image_digest` string, required
    - `expires_at` string, date-time, required: When an unfinished job is failed as job_expired and its document erased.
    - `failure_code` 'validation_timeout' | 'validator_unavailable' | 'internal_error' | 'generation_failed' | 'job_cancelled' | 'job_expired'
    - `finished_at` string, date-time
    - `id` string, required
    - `operation` 'validate' | 'generate', required: V2 jobs validate; a V1 job may generate.
    - `operation_id` string, required
    - `outcome` 'valid' | 'invalid' | 'indeterminate'
    - `position` integer, required: The job's place in its batch; 0 outside one.
    - `result_available` boolean, required
    - `result_url` string
    - `ruleset_id` string, required
    - `schema` 'ironfang/finance/einvoice/job/v2', required
    - `status` 'queued' | 'running' | 'completed' | 'failed' | 'cancelled', required
    - `usage_charged` boolean, required
  - `schema` 'ironfang/finance/einvoice/batch/v2', required
  - `status` 'queued' | 'running' | 'completed' | 'failed' | 'cancelled' | 'partial', required: queued until a job starts; running while any is unfinished; then the one status every job shares, or partial.

## Other responses

- `202`: Accepted and queued. Location names the batch. Cache-Control is no-store.
- `400`: The request is malformed.
- `401`: The credential is missing or not accepted.
- `402`: The free allowance is used up and paid usage cannot continue until the billing account is put right: paused, no working payment method, a payment awaiting confirmation, or restricted. Nothing was accepted.
- `403`: The key lacks the scope this operation needs, or paid Ironfang Finance usage needs an approved business and the free allowance is used up. Nothing was accepted.
- `409`: The Idempotency-Key was used for a different request.
- `410`: The release was withdrawn from every use, or the billing account is closed. Nothing was queued.
- `413`: The body is over the limit for its media type.
- `415`: The media type, encoding or content is not accepted.
- `422`: The job cannot be validated as asked, for the reasons synchronous validation would refuse it. Nothing was queued or charged.
- `429`: Rate limited, the queue full, or the billing account can admit no more of this work this month. Nothing was queued.
- `500`: Ironfang Finance failed. Not a verdict on anything.
- `503`: The release's engine is not available, durable jobs are not configured, or billing is briefly unavailable. Nothing was queued.
- `504`: A PDF could not be inspected within the admission deadline. Nothing was queued.

---

[API](https://skmtc.dev/ironfang/apis/ironfang-finance-e-invoicing-api-2.md) · [All operations](https://skmtc.dev/ironfang/apis/ironfang-finance-e-invoicing-api-2/llms.txt) · [OpenAPI document](https://skmtc.dev/ironfang/apis/ironfang-finance-e-invoicing-api-2/revisions/8140667e556b?raw)
