---
title: "Download Payment Batch File"
method: GET
path: "/companies/{company_id}/payment-batches/{batch_id}/file"
tags: ["payments"]
---

# Download Payment Batch File

`GET /companies/{company_id}/payment-batches/{batch_id}/file`

## Request

- Base URL: `https://app.zeno-works.ch` (the document declares no server; this is the origin it was published from)
- URL: `https://app.zeno-works.ch/companies/{company_id}/payment-batches/{batch_id}/file`
- Auth: none declared

The stored pain.001 bytes — **409 unless approved/exported**.

The first download stamps ``approved → exported`` (+ who/when), so this GET
mutates and runs inside ``db.tx()`` (idempotent — only that one edge writes).
That first download is the release: it re-checks every bill first (ZENO-231) and
answers 422 ``{"msg"}`` — stamping nothing — when one was paid, credited, re-batched
or edited since approval; cancel the batch and create a new one. Re-downloading an
exported batch serves the same bytes.

**Accountant/owner despite being a GET (ZCT-257).** The role sweep enumerates routes
by VERB, so a write behind a GET is structurally invisible to it — this is the live
instance of the blind spot that sweep's docstring names. A plain member could
otherwise download the bank payment-instruction file AND advance the batch's state,
stamping themselves as the exporter on a document that goes to the bank.

## Path parameters

- `company_id` string, required
- `batch_id` string, required

## Headers

- `authorization` string, nullable

## Cookies

- `access_token` string, nullable

## Response `200`

Successful Response

- unknown

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/zeno-works/apis/zeno-api.md) · [All operations](https://skmtc.dev/zeno-works/apis/zeno-api/llms.txt) · [OpenAPI document](https://skmtc.dev/zeno-works/apis/zeno-api/revisions/1eb93dde146c?raw)
