Upload Sessions
An upload session represents a single mobile photo collection event. Sessions reference pre-configured destinations where images are delivered. You can fan out to multiple destinations simultaneously.
Create a session
Create a session by specifying which destinations should receive the uploaded images. If you omit destination_ids, the API key's default destinations are used.
/api/v1/upload-sessionsRequest body
| Field | Type | Required | Description |
|---|---|---|---|
| destination_ids | string[] | No | Array of pre-configured destination UUIDs. Falls back to the API key's default destinations if omitted. |
| long_polling | boolean | No | Enable pull-based delivery alongside push destinations. |
| tags | string[] | No | String array of tags for correlating uploads (e.g. user:123, order:456). |
| expires_in_hours | integer | No | Session lifetime in hours (1–168). Mutually exclusive with expires_at. |
| expires_at | string | No | Absolute expiration as ISO 8601 datetime. Mutually exclusive with expires_in_hours. |
| max_images | integer | No | Maximum number of images allowed in this session. |
| allowed_mime_types | string[] | No | Restrict accepted formats. Subset of image/jpeg, image/png, image/webp, image/heic. |
| max_image_dimension | integer | No | Maximum pixel dimension (width or height) for uploaded images. |
| password | string | No | Require a password to access the upload page (4–128 characters). |
curl -X POST https://api.apertur.ca/api/v1/upload-sessions \
-H "Authorization: Bearer aptr_xxxx" \
-H "Content-Type: application/json" \
-d '{
"destination_ids": [
"d290f1ee-6c54-4b01-90e6-d701748f0851",
"7c9e6679-7425-40de-944b-e07fc1f90ae7"
],
"tags": ["user:123", "order:456"],
"expires_in_hours": 24,
"max_images": 10
}'Destinations
Destinations are pre-configured delivery targets managed in your dashboard under Project → Destinations. Apertur supports 9 destination types across four categories.
Cloud Storage
Amazon S3 or any S3-compatible storage (MinIO, Backblaze B2, DigitalOcean Spaces, etc.).
endpoint, region, bucket, accessKey, secretKey, pathTemplate, customHeaders
Azure Blob Storage containers.
connectionString, container, pathTemplate
Cloud Drives
Google Drive. Connected via OAuth — tokens are automatically refreshed.
folderId, pathTemplate
Dropbox. Default folder: /Apps/Apertur.
folderPath
Microsoft OneDrive. Default folder: /Apertur.
driveId, folderPath
Box.com. Default folder: root.
folderId
Server
FTP, FTPS, or SFTP. Supports password and private key authentication.
host, port, username, password, protocol, remotePath, privateKey
WebDAV-compatible servers (Nextcloud, ownCloud, etc.).
url, username, password, remotePath
HTTP
HTTP POST to your endpoint. Supports multipart, JSON base64, and binary formats. HMAC signature included.
url, secret, format (multipart / json_base64 / binary)
Destination management
Manage destinations via the API or the dashboard under Project → Destinations.
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/projects/:projectId/destinations | Create a new destination |
| GET | /api/v1/projects/:projectId/destinations | List all destinations |
| PATCH | /api/v1/projects/:projectId/destinations/:destId | Update a destination |
| DELETE | /api/v1/projects/:projectId/destinations/:destId | Delete a destination |
OAuth-based destinations (google_drive, dropbox, onedrive, box) are created through an OAuth authorization flow initiated from the dashboard.
Long polling
Long polling is a boolean option on the session, not a destination type. When enabled, your server can poll for images alongside any push destinations. This is useful when your server cannot accept inbound requests. See the Long Polling documentation for details.
{
"destination_ids": ["d290f1ee-..."],
"long_polling": true
}Response
The response includes a uuid to identify the session and the list of resolved destinations.
{
"uuid": "sess_01HX4ABCDEFGHIJKLMN",
"destinations": [
{ "id": "d290f1ee-...", "type": "s3", "name": "Production S3" },
{ "id": "7c9e6679-...", "type": "webhook", "name": "My Webhook" }
],
"long_polling": false,
"expires_at": "2024-03-29T10:00:00Z",
"password_protected": false
}| Field | Type | Description |
|---|---|---|
| uuid | string | Unique session identifier |
| destinations | object[] | Array of resolved destinations (id, type, name) |
| long_polling | boolean | Whether pull-based delivery is enabled |
| expires_at | string | ISO 8601 expiration datetime |
| password_protected | boolean | Whether the session requires a password |
Delivery status
Track per-image, per-destination delivery progress for any session.
/api/v1/upload-sessions/:uuid/delivery-statuscurl https://api.apertur.ca/api/v1/upload-sessions/sess_01HX4ABCDEFGHIJKLMN/delivery-status \ -H "Authorization: Bearer aptr_xxxx"
{
"session_id": "sess_01HX4ABCDEFGHIJKLMN",
"images": [
{
"image_id": "img_01HX...",
"image_index": 0,
"deliveries": [
{
"destination_id": "d290f1ee-...",
"destination_name": "Production S3",
"destination_type": "s3",
"status": "delivered",
"delivered_at": "2024-03-28T10:01:23Z"
},
{
"destination_id": "7c9e6679-...",
"destination_name": "My Webhook",
"destination_type": "webhook",
"status": "pending",
"attempts": 1,
"next_retry_at": "2024-03-28T10:02:00Z"
}
]
}
]
}Retry policy
Failed deliveries are retried up to 5 times with increasing delays: 5s, 30s, 2min, 10min, 1hr.
Session options
These optional fields let you customize session behavior.
| Option | Description | Default |
|---|---|---|
| password | Require a password to access the upload page (4–128 chars) | None (no password) |
| max_images | Limit the number of images a user can upload | Plan default |
| expires_in_hours | Session lifetime in hours (1–168) | 24 hours |
| expires_at | Absolute expiration as ISO 8601 datetime | - |
| allowed_mime_types | Restrict accepted image formats | All supported types |
| max_image_dimension | Max pixel dimension (width or height) | No limit |
| tags | String array for correlating uploads with your data | [] |
Session status
| Status | Description |
|---|---|
| pending | Session created, waiting for user to scan and submit photos |
| uploading | User is actively uploading images |
| completed | All images processed and delivered |
| expired | Session expired before the user submitted photos |
| failed | Delivery failed after all retries exhausted |