This document records the API consistency audit performed for the TimeTracker backend, REST API, and native clients (desktop and mobile). It describes findings and the standardized contracts adopted.
- Helpers in
app/utils/api_responses.pydefinesuccess_response()(returns{ "success": true, "data"?, "message"?, "meta"? }) andpaginated_response()(items indata, pagination inmeta.pagination). - Actual API uses a different convention: list endpoints return resource-named key + top-level pagination, e.g.
{ "time_entries": [...], "pagination": {...} },{ "projects": [...], "pagination": {...} }. Single-resource responses use a singular key:{ "time_entry": {...} },{ "project": {...} },{ "timer": {...} }. - Contract (kept for compatibility): List =
{ "<resource_plural>": [...], "pagination": { page, per_page, total, pages, has_next, has_prev, next_page, prev_page } }. Single ={ "<resource_singular>": {...} }. Created (201) ={ "message"?, "<resource_singular>": {...} }or similar. Clients depend on these keys; we do not switch todata/meta.
- Contract: All API v1 error responses (4xx/5xx) include:
error(string): user-facing message (backward compatible).message(string): same or more detail.error_code(string, optional): machine-readable code, e.g.unauthorized,forbidden,not_found,validation_error,no_active_timer.errors(object, optional): field-level validation errors, e.g.{ "field_name": ["message1", "message2"] }.- For 403 scope errors:
required_scope,available_scopesmay also be present.
- Contract: Any 400 due to invalid input uses the same structure:
error_code: "validation_error"and, when applicable, anerrorsobject with field-level messages. Marshmallow validation useshandle_validation_error(); manual validation usesvalidation_error_response().
- Contract: List endpoints support query params
page(default 1) andper_page(default 50, max 100). Response includes"pagination": { "page", "per_page", "total", "pages", "has_next", "has_prev", "next_page", "prev_page" }. The list key is resource-specific (e.g.time_entries,projects), notitems.
- Token extraction (Bearer, Token, X-API-Key) and
@require_api_token(scope)are consistent. Auth error responses includeerror_code(unauthorized,forbidden) for consistent machine-readable handling.
- Contract: Dates and datetimes use ISO 8601. Request parsing accepts
YYYY-MM-DDandYYYY-MM-DDTHH:MM:SS/YYYY-MM-DDTHH:MM:SSZ. Serialization format (e.g. UTC or server local) is documented in the REST API reference.
- Filter query parameters are resource-specific and documented per endpoint. Optional
sort/orderconventions may be documented for list endpoints that support them.
- REST API reference: REST_API.md β endpoints, request/response formats, pagination, errors.
- OpenAPI:
/api/openapi.jsonand Swagger UI at/api/docsβ aligned with this contract where updated.info.versionfollowsget_version_from_setup()(fromsetup.py, with optionalTIMETRACKER_VERSION/APP_VERSIONoverrides); seeapp/routes/api_docs.py.