Issue a one-time WebSocket handshake token
Owner-only: the caller must be the purchase's `purchaser_id` (anything else is 404 — no existence leak). Issues a fresh one-time token for the raw `WS /ws?token=...` socket: a 32-byte random value stored as its SHA-256 hash, valid 10 minutes, consumed by the first handshake. The token is a handshake-auth shim — it proves prior REST auth for this purchase and nothing more (no refresh dance, no scopes). Reconnect = fresh token: the front re-requests before the 10-minute expiry and re-opens the socket.
/ws/tokenOwner-only: the caller must be the purchase's purchaser_id
(anything else is 404 — no existence leak). Issues a fresh one-time
token for the raw WS /ws?token=... socket: a 32-byte random value
stored as its SHA-256 hash, valid 10 minutes, consumed by the first
handshake. The token is a handshake-auth shim — it proves prior REST
auth for this purchase and nothing more (no refresh dance, no
scopes). Reconnect = fresh token: the front re-requests before the
10-minute expiry and re-opens the socket.
Authorization
bearerAuth JWT issued by IdentityX, signed with Ed25519
In: header
Query Parameters
Purchase to bind the token to.
Response Body
application/json
application/problem+json
application/problem+json
application/problem+json
curl -X GET "https://example.com/ws/token?purchase_id=497f6eca-6276-4993-bfeb-53cbbbba6f08"{
"token": "string",
"expires_at": "2019-08-24T14:15:22Z"
}{
"detail": "string",
"instance": "../dictionary",
"errors": [
{
"field": "string",
"message": "string"
}
],
"type": "http://example.com",
"status": 401,
"title": "Unauthenticated"
}{
"detail": "string",
"instance": "../dictionary",
"errors": [
{
"field": "string",
"message": "string"
}
],
"type": "http://example.com",
"status": 404,
"title": "Not Found"
}{
"detail": "string",
"instance": "../dictionary",
"errors": [
{
"field": "string",
"message": "string"
}
],
"type": "http://example.com",
"status": 500,
"title": "Internal Server Error"
}List my purchases GET
Lists the authenticated user's purchases with their items, newest first. The purchases table is the record of truth (issue #61); items come from `purchase_items` — the availability ledger (D4). Read-only; no state transitions.
Problems
Every RFC 9457 problem Univents can answer, by status.