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

# Period close

> Run a month-end close on the embedded ledger — periods, the close checklist, and what locking actually prevents.

# Period close

The general ledger runs real accounting periods: they open, they close, and they **lock**. A closed
period rejects new postings; a locked one rejects reopening. This is the workflow for month-end,
and the order matters because a close is a one-way gate for everything upstream of it.

## The period lifecycle

```
open ──close──▶ closed ──lock──▶ locked
  ▲               │
  └───reopen──────┘        (locked periods cannot reopen)
```

| Action             | Endpoint                              |
| ------------------ | ------------------------------------- |
| Create next period | `POST /api/v1/gl/periods`             |
| Close              | `POST /api/v1/gl/periods/{id}/close`  |
| Reopen             | `POST /api/v1/gl/periods/{id}/reopen` |
| Lock               | `POST /api/v1/gl/periods/{id}/lock`   |

<Warning>
  **Lock is irreversible.** Close when the month's work is done; lock when the numbers have been
  reported externally — filed, sent to investors, used in a bank covenant. The gap between close and
  lock is your correction window. Once locked, a correction goes in the *current* period as an explicit
  adjusting entry, which is exactly the audit trail you want.
</Warning>

## The close, in order

### 1 — Sweep unposted entries

```bash theme={null}
curl "https://api.stateset.com/api/v1/gl/journal-entries?status=draft&period=2026-06" \
  -H "Authorization: Bearer $STATESET_API_KEY"
```

Every draft either gets posted (`POST /api/v1/gl/journal-entries/{id}/post`) or voided
(`/{id}/void`). A draft left behind is a number that changes after you've reported it.

### 2 — Revalue foreign currency

```bash theme={null}
curl -X POST https://api.stateset.com/api/v1/gl/revalue \
  -H "Authorization: Bearer $STATESET_API_KEY" \
  -H 'content-type: application/json' \
  -d '{ "period": "2026-06" }'
```

Restates open foreign-currency balances at period-end rates. Run it **before** the trial balance,
not after — otherwise the trial balance you review is not the one you close.

### 3 — Reconcile the subledgers

The AR and AP views must agree with their control accounts:

```bash theme={null}
curl "https://api.stateset.com/api/v1/ar/aging?as_of=2026-06-30" -H "Authorization: Bearer $STATESET_API_KEY"
curl "https://api.stateset.com/api/v1/ap/aging?as_of=2026-06-30" -H "Authorization: Bearer $STATESET_API_KEY"
```

A mismatch is almost always an unapplied payment
([order to cash, step 4](/guides/commerce/order-to-cash#4--apply-it)) or an unposted bill — find it
now, because after the close it becomes a prior-period adjustment.

### 4 — Review the trial balance

```bash theme={null}
curl "https://api.stateset.com/api/v1/gl/trial-balance?period=2026-06" \
  -H "Authorization: Bearer $STATESET_API_KEY"
```

Debits equal credits by construction — the engine enforces balanced entries — so what you are
reviewing is *placement*: suspense-account balances, sign flips, anything that moved more than the
business did.

### 5 — Close

```bash theme={null}
curl -X POST https://api.stateset.com/api/v1/gl/close-month \
  -H "Authorization: Bearer $STATESET_API_KEY" \
  -H 'content-type: application/json' \
  -d '{ "period": "2026-06" }'
```

<Note>
  The [admin console](/stateset-icommerce/stateset-icommerce-admin) runs this same close as a
  **dry run first** with a per-step report, and requires typed confirmation for the real one.
  Per-item failures do not abort a close — read the report rather than assuming success. If you close
  via API, mirror that: check the response's per-step results, not just the status code.
</Note>

### 6 — Report, then lock

```bash theme={null}
curl "https://api.stateset.com/api/v1/gl/balance-sheet?period=2026-06"    -H "Authorization: Bearer $STATESET_API_KEY"
curl "https://api.stateset.com/api/v1/gl/income-statement?period=2026-06" -H "Authorization: Bearer $STATESET_API_KEY"
curl -X POST https://api.stateset.com/api/v1/gl/periods/{id}/lock         -H "Authorization: Bearer $STATESET_API_KEY"
```

## The correction that arrives late

An invoice for June surfaces in July, after the close:

* **June closed but not locked** — reopen, post, re-close. Cheap now, impossible later.
* **June locked** — post to July with a memo referencing the June document. Do not be tempted by
  `reverse` on old entries to "make room": `POST /api/v1/gl/journal-entries/{id}/reverse` creates
  the reversal *in the current period*, which is correct behaviour — it will not un-happen June.

## Related

* [Order to cash](/guides/commerce/order-to-cash) — where the AR entries come from
* [Procure to pay](/guides/commerce/procure-to-pay) — where the AP entries come from
* [General ledger reference](/api-reference/commerce/overview#financials)
