---
title: "Consume Session Token"
method: POST
path: "/api/v1/account/session"
tags: ["account"]
---

# Consume Session Token

`POST /api/v1/account/session`

## Request

- Base URL: `https://api.billcommons.org`
- URL: `https://api.billcommons.org/api/v1/account/session`
- Auth: none declared

D7: consumes a magic-link token (POST only -- a GET must never
consume it). Origin-checked like every other unsafe method on this
router (B7). Sets the session cookie and returns either `204` (nothing
new to reveal) or `200 {"key": ...}` when this login just auto-minted
the customer's first Developer key (D5, revealed INLINE -- no
reveal-ciphertext needed for a synchronous JSON response).

Item 3 fix (part 1 of 3): the token is claimed with ONE atomic
`UPDATE ... WHERE used_at IS NULL ... RETURNING`, replacing the pre-fix
check-then-set (a `SELECT`, then `row.used_at = now` applied only at
`db.commit()` much later) that let two concurrent calls with the SAME
token both pass the "is it unused" check before either had committed.

Fixlist item 6 fix: `_session_secret()` is resolved FIRST, before any
write. Pre-fix, a misconfigured instance (`ACCOUNT_SESSION_SECRET`
unset -- startup only logs an ERROR for this, per item 20, and keeps
serving) burned the magic-link token, upserted the customer, and
auto-minted the customer's ONE Developer key (`mint_developer_key_if_
first_login` never mints a second) all the way through `db.commit()`
below -- and only THEN called `_sign_session` -> `_session_secret()`,
which raises. The customer got an unhandled 500 with the token already
consumed, the key already minted, and no way to ever read that key's
plaintext (`reveal_ciphertext` is null on this inline-reveal path by
design, D5) -- permanently unreadable and burning one of two active
key slots, recoverable only via a second key from the account UI.
Failing here, before any of that is written, turns a misconfiguration
into a clean, retriable failure instead of an unrecoverable one.

## Request body

- SessionRequest
  - `token` string, required

## Response `200`

Successful Response

- unknown

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/billcommons/apis/bill-commons-api.md) · [All operations](https://skmtc.dev/billcommons/apis/bill-commons-api/llms.txt) · [OpenAPI document](https://skmtc.dev/billcommons/apis/bill-commons-api/revisions/bfb8cd50a317?raw)
