Skip to main content
This page covers the request and response formats used across the Gumnut API.

Request Format

Headers

All requests should include:
For file uploads, use multipart/form-data:

Request Body

Send JSON payloads for most endpoints:

Query Parameters

Use query parameters for filtering, pagination, and opt-in expansions:

Asset expansions with include

Asset responses are intentionally lean by default. Pass include when you need additional fields:
  • metadata for camera, EXIF, GPS, and location fields
  • faces for automatic and manual face boxes
  • people for deduplicated people records
  • file_data for device IDs, timestamps, checksums, and file size
  • variants for non-thumbnail asset_urls rungs such as small, preview, fullsize, and original. For video assets, the rendered-image rungs use _image suffixes such as thumbnail_image and preview_image, while original stays the playable video file.
quality_score is a top-level nullable field on asset responses, not an include expansion. A null value means no score is available. You can repeat include or send a comma-delimited value. For example, include=faces&include=people and include=faces,people are equivalent. When present, each face row includes a source field so you can distinguish automatic detections from manual user-drawn boxes. If your client renders anything larger than the default thumbnail, or offers a download-original action, request include=variants. The API reference already marks those richer asset_urls fields as opt-in, so sending the token keeps your integration aligned with the lean response model. If you expose a browser download button, link to asset_urls.original.url. A plain top-level navigation or <a href> saves the original file with its original filename. The same URL still works for inline video playback and fetch requests, so you do not need a separate download-only field.
Asset URLs are signed capabilities. Use the complete URL exactly as returned, including its query parameters, for every GET or HEAD request. Gumnut validates the signature before serving content from the cache or storage, so a missing or invalid signature returns 403 Forbidden even when the asset was recently cached.

Response Format

Successful Responses

Successful requests return JSON with appropriate HTTP status codes:
Expanded fields stay null or absent until you request them with include.

Asset timestamp fields

Gumnut uses different timestamps for different jobs:
  • local_datetime is Gumnut’s best local capture timestamp for the asset.
  • If Gumnut knows the capture offset, local_datetime includes it, for example 2024-07-15T12:00:00-07:00.
  • If the source only records a wall-clock capture time and not its offset, local_datetime is returned without a timezone suffix, for example 2024-07-15T12:00:00.
  • If the upload has no embedded capture datetime, Gumnut can derive local_datetime from file timestamps instead of echoing raw UTC file time, so the asset still lands on the expected local calendar day.
  • created_at is when Gumnut created the asset record. It is not the capture time.
  • file_data.file_created_at and file_data.file_modified_at describe the uploaded file on the source device. Request them with include=file_data when you need file-level timestamps or when you need to compare the raw file time with Gumnut’s inferred local_datetime.
Use local_datetime when you want to group or filter by when an asset was captured. Use created_at when you need to track when the asset record arrived in Gumnut. Status codes:
  • 200 OK - Request succeeded
  • 201 Created - Resource created
  • 204 No Content - Request succeeded with no content
Some named create endpoints use both 200 and 201: 201 means Gumnut created a new resource, while 200 means it returned an existing matching resource. See Named Creates and Retries for the matching rules and 409 Conflict cases.

Error Responses

Errors return a consistent JSON structure:
Status codes:
  • 400 Bad Request - Invalid request
  • 401 Unauthorized - Authentication required
  • 403 Forbidden - Insufficient permissions
  • 404 Not Found - Resource not found
  • 409 Conflict - Gumnut could not associate a Clerk sign-in with an existing account. Resolve the identity conflict before retrying; repeated requests with unchanged verification and identity state will not resolve it. Some endpoints also return operation-specific conflicts.
  • 429 Too Many Requests - Rate limit exceeded, or too many concurrent requests (see Rate Limiting)
  • 500 Internal Server Error - Server error
  • 503 Service Unavailable - Authentication provider temporarily unavailable. Retry sign-in later.

Best Practices

Error Handling

  • Implement exponential backoff for retries on 429 and 5xx errors
  • Handle rate limits gracefully using the Retry-After header (see Rate Limiting)
  • Log errors with the request ID for debugging
  • Validate input before sending requests

Security

  • Never expose API keys in client-side code
  • Use HTTPS for all requests
  • Implement proper authentication flows