From 6f5dae6a4459a2771c5508027e70b2107693982d Mon Sep 17 00:00:00 2001 From: "Aaron K. Clark" Date: Tue, 19 May 2026 02:59:44 -0500 Subject: [PATCH] docs(readme): add the missing /v1/whoami row to the endpoint table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Endpoints table in README.md listed every /v1/* domain endpoint plus /healthz, /metrics, /docs, and /openapi.json, but missed `/v1/whoami` — the identity-probe endpoint that returns `{authenticated, isMaster, companyId}` for the calling authKey. The route exists in `app/routers/router.js` (line 82) and in the OpenAPI spec (`app/config/openapi.js:388`), so SDK clients reading the spec found it; readers of the README didn't. Add a one-line entry between `/openapi.json` and `/v1/customer/:id` that calls out the distinct auth contract — header MUST be present (403 if missing) but the key need NOT resolve (200 with `authenticated: false` for unknown keys). That's the discriminator that makes whoami useful as a wiring-check vs. inferring from a domain endpoint's 4xx. Co-Authored-By: Claude Opus 4.7 (1M context) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f7a2014..b6dcf41 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ Working example at [node.timetrackerapi.com](http://node.timetrackerapi.com). | `GET /metrics` | no (or bearer)| Prometheus scrape endpoint. Default Node.js metrics + per-request `http_requests_total` / `http_request_duration_seconds`. Authentication is OPTIONAL: leave `METRICS_BEARER_TOKEN` unset for an open scrape (private-network deployment) or set it to require `Authorization: Bearer `. | | `GET /docs` | no | Interactive Swagger UI for the full API. | | `GET /openapi.json` | no | Raw OpenAPI 3.0 spec (machine-readable). | +| `GET /v1/whoami` | header | Returns `{authenticated, isMaster, companyId}` for the calling `authKey`. Header MUST be present (403 if missing) but the key need NOT resolve — an unknown key returns 200 with `authenticated: false`. Useful for SDK clients to distinguish "network plumbing wrong" from "credential wrong" without inferring from a domain endpoint's 4xx. | | `GET /v1/customer/:id` | yes (`authKey`) | Single customer lookup. Master key sees all; non-master only sees customers in its own company. | | `GET /v1/customer/bycompany/:id` | yes (`authKey`) | Customers in a company (paginated). Master sees any; non-master only its own. Query params: `limit` (default 100, max 500), `offset` (default 0). Archived customers (`custArch = true`) are filtered out. | | `POST /v1/customer` | yes (`authKey`) | Create a customer. Master key may target any `custCompId`; non-master keys can only create within their own company (and `custCompId` defaults to that). Returns 201 + the created customer. |