List diary entries
Lists diary entries, most-recent-first, paginated. Filters map onto the domain browse: `projectId` and `userId` are repeatable. An API key is **Admin-equivalent and tenant-wide**, so this returns every entry in the tenant. The narrower per-role visibility introduced by SUP-449 — a Site Manager sees their sites plus their own, Site Crew only their own — applies to signed-in users of the web app; there is no crew-scoped API credential. **This read closes expired shifts before it answers** (ADR 0012, amended): open shifts past 12 hours inside the read's scope are auto-closed first, so the list can contain entries created by this very call — `origin` `auto_closed`, `createdBy` null, `durationMinutes`/`hours` **null** (hours *missing*, never 0, zero in totals), `closedAutomaticallyReason` `12h`. An hourly database job runs the same sweep whether or not anyone reads, so the entries exist before they are asked for. Writes never sweep.
Lists diary entries, most-recent-first, paginated. Filters map onto the
domain browse: projectId and userId are repeatable.
An API key is Admin-equivalent and tenant-wide, so this returns every entry in the tenant. The narrower per-role visibility introduced by SUP-449 — a Site Manager sees their sites plus their own, Site Crew only their own — applies to signed-in users of the web app; there is no crew-scoped API credential.
This read closes expired shifts before it answers (ADR 0012, amended):
open shifts past 12 hours inside the read's scope are auto-closed first, so
the list can contain entries created by this very call — origin
auto_closed, createdBy null, durationMinutes/hours null (hours
missing, never 0, zero in totals), closedAutomaticallyReason 12h. An
hourly database job runs the same sweep whether or not anyone reads, so the
entries exist before they are asked for. Writes never sweep.
The per-tenant API key, copied from Settings → API & integrations.
Sent as the x-api-key request header. The key is tenant-scoped and acts
with Admin-equivalent, tenant-wide access.
In: header
Query Parameters
Page size, 1–200. Defaults to 50.
Opaque cursor from a previous page's nextCursor. Omit for the first page.
Filter by project id (repeatable).
Filter by crew-member user id (repeatable).
Inclusive start of the entry-date range (YYYY-MM-DD).
Inclusive end of the entry-date range (YYYY-MM-DD).
Free-text match on description and crew name.
Response Body
application/json
application/json
curl -X GET "https://example.com/diary-entries"{ "data": [ { "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", "entryDate": "2019-08-24", "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8", "projectName": "string", "projectArchived": true, "userId": "2c4a230c-5085-4924-a3e1-25fb4fc5965b", "crewMemberName": "string", "durationMinutes": 0, "hours": 0, "description": "string", "photoCount": 0, "submittedAt": "2019-08-24T14:15:22Z", "latitude": 0, "longitude": 0, "locationAccuracyM": 0, "siteLocation": { "verdict": "on_site", "distanceM": 0, "accuracyM": 0, "missingReason": "no_site" }, "origin": "manual", "attendanceRecordId": "681c1ed7-6de0-4306-80e5-8ea16505936b", "checkInAt": "2019-08-24T14:15:22Z", "checkOutAt": "2019-08-24T14:15:22Z", "checkInLocation": { "verdict": "on_site", "distanceM": 0, "accuracyM": 0, "missingReason": "no_site" }, "checkOutLocation": { "verdict": "on_site", "distanceM": 0, "accuracyM": 0, "missingReason": "no_site" }, "createdBy": "25a02396-1048-48f9-bf93-102d2fb7895e", "createdByName": "string", "closedAutomaticallyAt": "2019-08-24T14:15:22Z", "closedAutomaticallyReason": "12h", "siteTimezone": "string", "marks": [ "no_check_in" ] } ], "nextCursor": "string"}{ "error": { "code": "unauthorized", "message": "Missing or invalid API key." }}Delete is not available via the API DELETE
Deleting a diary entry stays in the app (Admin only, on the entry's detail page); this verb is answered with a `405` pointing there.
Edit is not available via the API PUT
Editing a diary entry stays in the app; this verb is answered with a `405` pointing there.