https://handwrites.io. The team reference is a filtered edition of the shared Handwrite OpenAPI description, not a separate API version. JSON property names and route operation IDs match that description. Paths remain /api/v1/orgs; there is no invented /api/v1/teams alias.Authorization: Bearer <credential> over HTTPS. The reference permits Handwrite API keys or OAuth access tokens. App/website session authentication is separate from an external integration and does not make private cookie-based console routes into public APIs.orgs:read is needed for organisation reads; orgs:manage for organisation writes; listing an organisation's documents uses documents:read. Scope checks are followed by current membership/role, plan, policy and selected-document checks. A valid token may therefore return 403 or see fewer documents. A non-member organisation lookup returns 404 to avoid revealing it. Never interpret 404 as proof an ID does not exist globally.user%3A…. Keep org_…, doc_…, invitation IDs and token IDs distinct. Do not strip a principal prefix or substitute an email where the contract requires a principal.| Concern | Contract and app behavior |
|---|---|
| JSON | Send Content-Type: application/json for JSON bodies. Use only supported fields; runtime validators may be stricter than a generated client type. |
| Correlation | Keep Request-Id for support without retaining tokens or user content. |
| Rate limits | Respect Retry-After on 429 and returned Handwrite-Requests-* headers. Daily counting is per credential/account under the global cap. The stored dailyRequests organisation policy is not currently used by that counter; monthly audio policy is a separate control. |
| Errors | JSON errors use error.code and error.message. Generic authentication/validation/server errors and endpoint-specific errors both apply. |
| Empty success | 204 has no body. Live usage may return 304 with no body after If-None-Match. |
| CSV | Organisation usage with format=csv is a file/text response, not JSON. |
| Pagination | Follow opaque document cursors until null, even if filtering yields an empty page. Do not invent offsets or persist a partially completed sync as complete. |
| Changes | since lists changed team-owned documents including tombstones. Keep IDs and revisions; periodic full reconciliation is needed if your checkpoint falls beyond retained tombstones. |
| Replacement | Policy PUT replaces the stored rule map. Read and merge the user's intended edits before writing; it is not JSON Merge Patch. |
Idempotency-Key for creating an organisation, adding a member and creating an invitation. Use a new random key for each logical action and reuse it only for an identical retry. A replay is not a license to change the body while retaining the key. Follow the shared API's idempotency error semantics.If-Match rules. Keep unsaved edits on 409 live_session_active or 412 and reconcile them explicitly./api/org handlers are implementation details rather than supported outside-developer endpoints. See SSO and portal workflows.src/cloud/openapi.ts snapshot, src/app/api/v1/orgs/**, http.ts, orgs.ts, org-invites.ts, policies.ts, managed-tokens.ts, usage-org.ts and insights.ts. Schemas describe the published contract; source-only additions and unverified release state are identified in the app guide.