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
  • metrics for ML-generated quality scores
  • 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.
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.

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

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
  • 429 Too Many Requests - Rate limit exceeded (see Rate Limiting)
  • 500 Internal Server Error - Server error

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