Request a presigned diary-photo upload URL
**Step 1 of the presigned diary-photo upload** — the image-only sibling of the document upload. Validates the declared image (JPG/PNG only — no PDF) and returns a short-lived, single-use **signed PUT URL** (`uploadUrl`) plus the computed `storagePath`. **The image bytes never travel through this API call.** After this returns, the caller PUTs the raw image bytes directly to `uploadUrl` (a plain HTTP `PUT` with the file as the request body and the matching `Content-Type`) — out of band — then passes the returned `storagePath` in the `photoPaths` array of `POST /diary-entries`. **There is no register step**: creating the diary entry writes the `diary_photo` row(s) (ADR 0001 §5). Any crew member assigned to the project may log diary photos (not manager-only); an Admin/API key is implicitly on every project. Blocked on read-only/archived projects.
Step 1 of the presigned diary-photo upload — the image-only sibling
of the document upload. Validates the declared image (JPG/PNG only — no
PDF) and returns a short-lived, single-use signed PUT URL
(uploadUrl) plus the computed storagePath.
The image bytes never travel through this API call. After this
returns, the caller PUTs the raw image bytes directly to uploadUrl (a
plain HTTP PUT with the file as the request body and the matching
Content-Type) — out of band — then passes the returned storagePath in
the photoPaths array of POST /diary-entries. There is no register
step: creating the diary entry writes the diary_photo row(s) (ADR
0001 §5).
Any crew member assigned to the project may log diary photos (not manager-only); an Admin/API key is implicitly on every project. Blocked on read-only/archived projects.
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
Path Parameters
Resource id.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/projects/497f6eca-6276-4993-bfeb-53cbbbba6f08/diary-photos/upload-url" \ -H "Content-Type: application/json" \ -d '{ "filename": "string", "contentType": "string" }'{ "storagePath": "string", "uploadUrl": "string", "bucket": "string"}{ "error": { "code": "unauthorized", "message": "Missing or invalid API key." }}{ "error": { "code": "read_only", "message": "Your subscription is inactive. This action is read-only." }}{ "error": { "code": "not_found", "message": "Not found." }}{ "error": { "code": "validation", "message": "One or more inputs are invalid.", "fields": { "fieldName": "A message explaining what's wrong with this field." } }}List diary entries GET
Lists the tenant's diary entries, most-recent-first, paginated. Filters map onto the domain browse: `project` and `user` are repeatable.
List a project's document metadata GET
Lists document **metadata** (never the binary) for one project, paginated. `project` is required; `kind` narrows to one library, omitted returns both (OHS first, then Project Information).