Photos

Request a presigned standalone-photo upload URL

**Step 1 of the presigned standalone-photo upload** — the no-diary-entry sibling of `.../diary-photos/upload-url`. Validates the declared image (JPG/PNG only) 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` — out of band — then passes the returned `storagePath` in the `storagePaths` array of `POST /projects/{id}/photos`. No diary entry is involved. Any crew member assigned to the project may upload photos; an Admin/API key is implicitly on every project. Blocked on read-only/archived projects.

POST
/projects/{id}/photos/upload-url

Step 1 of the presigned standalone-photo upload — the no-diary-entry sibling of .../diary-photos/upload-url. Validates the declared image (JPG/PNG only) 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 — out of band — then passes the returned storagePath in the storagePaths array of POST /projects/{id}/photos. No diary entry is involved.

Any crew member assigned to the project may upload photos; an Admin/API key is implicitly on every project. Blocked on read-only/archived projects.

Authorization

x-api-key<token>

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

id*string

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/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."    }  }}