---
title: "Starts closing every billing period awaiting review that ended before a date, optionally limited
 to those worth no more than a given amount."
method: POST
path: "/billing-periods/close-bulk"
tags: ["Billing"]
---

# Starts closing every billing period awaiting review that ended before a date, optionally limited
 to those worth no more than a given amount.

`POST /billing-periods/close-bulk`

Answers 202 with a run identifier and closes the periods in the background — each one costs a
 full invoice recomputation, so a selection of a few hundred takes minutes. Poll
 GET /billing-periods/close-bulk/{bulkCloseId} for progress, per-period verdicts and the
 total written off. Each period is closed exactly as the per-period close does, and one period
 failing is recorded against that period rather than abandoning the rest. A period whose live
 residual exceeds maxNetInvoiceableAmount is refused rather than written off, so a
 selection built for small residuals cannot write off a real bill that arrived after the last
 settlement. Set dryRun to compute what the sweep would write off without minting
 write-off vouchers or closing anything. Answers 409 Conflict while another sweep is still
 running; only one runs at a time.

## Request body

- BulkCloseBillingPeriodsEndpointInput
  - `endedBefore` string, date-time, required — Only periods that ended before this date are closed.
  - `maxNetInvoiceableAmount` number, double, nullable — When set, only periods with at most this much left to invoice are closed, and a period whose amount has grown past it since it was last settled is refused.
  - `reason` string, required — Why the remaining amounts will never be invoiced.
  - `dryRun` boolean — Report what the sweep would write off without closing anything or minting any vouchers.

## Response `202`

Accepted

- BulkCloseBillingPeriodsEndpointOutput
  - `bulkCloseId` string, required — The run to poll for the sweep's progress.
  - `dryRun` boolean, required — Whether this run only reports what it would have written off.

## Other responses

- `400` — Bad Request
- `401` — Unauthenticated
- `403` — Forbidden

---

[API](https://skmtc.net/rapidata/apis/rapidata-api.md) · [All operations](https://skmtc.net/rapidata/apis/rapidata-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/rapidata/rapidata-api/revisions/5f993bd211f5/schema)
