Resources

Conventions

The things that are true everywhere, so they are not repeated on every endpoint.

Contents
ConcernBehaviour
IdentifiersIntegers, assigned by the server, unique per table. Never reused after a delete. Not guessable in any useful sense, but also not a secret, authorization is the control, not obscurity.
Timestampscreated_at is a UTC datetime serialised as a string, with microseconds: "2026-09-04 15:22:07.114820". Note the space, not a T: it is not ISO 8601 and a strict parser will reject it.
Datestest_date and similar are plain YYYY-MM-DD strings, stored verbatim. No timezone conversion is applied. The date on the report is the date you sent.
OrderingProjects and records are returned newest first. Assemblies and equipment follow sort_order, then insertion.
PaginationThere is none. List endpoints return the full collection. This is honest rather than aspirational: a project has tens of assemblies, not thousands. Do not build a client that depends on a page parameter appearing.
NullsOptional strings come back as "", not null. Optional relations and dates come back as null. last_tested and last_status are null on a device that has never been tested.
Unknown fieldsIgnored on input. Do not send extra keys expecting them to persist, outside form_data, they will not.
IdempotencyThere are no idempotency keys. GET and DELETE are naturally safe to repeat; a repeated POST creates a second row. On a timeout during a create, list and check before retrying.
Parse created_at deliberately

The space-separated form will fail new Date() in some engines and datetime.fromisoformat() on older Pythons. Normalise the separator, or parse with an explicit format, rather than assuming it round-trips.