Docs/Upload Sessions

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.

POST/api/v1/upload-sessions

Request body

FieldTypeRequiredDescription
destination_idsstring[]NoArray of pre-configured destination UUIDs. Falls back to the API key's default destinations if omitted.
long_pollingbooleanNoEnable pull-based delivery alongside push destinations.
tagsstring[]NoString array of tags for correlating uploads (e.g. user:123, order:456).
expires_in_hoursintegerNoSession lifetime in hours (1–168). Mutually exclusive with expires_at.
expires_atstringNoAbsolute expiration as ISO 8601 datetime. Mutually exclusive with expires_in_hours.
max_imagesintegerNoMaximum number of images allowed in this session.
allowed_mime_typesstring[]NoRestrict accepted formats. Subset of image/jpeg, image/png, image/webp, image/heic.
max_image_dimensionintegerNoMaximum pixel dimension (width or height) for uploaded images.
passwordstringNoRequire 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

s3

Amazon S3 or any S3-compatible storage (MinIO, Backblaze B2, DigitalOcean Spaces, etc.).

endpoint, region, bucket, accessKey, secretKey, pathTemplate, customHeaders

azure_blob

Azure Blob Storage containers.

connectionString, container, pathTemplate

Cloud Drives

google_driveOAuth

Google Drive. Connected via OAuth — tokens are automatically refreshed.

folderId, pathTemplate

dropboxOAuth

Dropbox. Default folder: /Apps/Apertur.

folderPath

onedriveOAuth

Microsoft OneDrive. Default folder: /Apertur.

driveId, folderPath

boxOAuth

Box.com. Default folder: root.

folderId

Server

ftp

FTP, FTPS, or SFTP. Supports password and private key authentication.

host, port, username, password, protocol, remotePath, privateKey

webdav

WebDAV-compatible servers (Nextcloud, ownCloud, etc.).

url, username, password, remotePath

HTTP

webhook

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.

MethodEndpointDescription
POST/api/v1/projects/:projectId/destinationsCreate a new destination
GET/api/v1/projects/:projectId/destinationsList all destinations
PATCH/api/v1/projects/:projectId/destinations/:destIdUpdate a destination
DELETE/api/v1/projects/:projectId/destinations/:destIdDelete 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
}
FieldTypeDescription
uuidstringUnique session identifier
destinationsobject[]Array of resolved destinations (id, type, name)
long_pollingbooleanWhether pull-based delivery is enabled
expires_atstringISO 8601 expiration datetime
password_protectedbooleanWhether the session requires a password

Delivery status

Track per-image, per-destination delivery progress for any session.

GET/api/v1/upload-sessions/:uuid/delivery-status
curl 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.

OptionDescriptionDefault
passwordRequire a password to access the upload page (4–128 chars)None (no password)
max_imagesLimit the number of images a user can uploadPlan default
expires_in_hoursSession lifetime in hours (1–168)24 hours
expires_atAbsolute expiration as ISO 8601 datetime-
allowed_mime_typesRestrict accepted image formatsAll supported types
max_image_dimensionMax pixel dimension (width or height)No limit
tagsString array for correlating uploads with your data[]

Session status

StatusDescription
pendingSession created, waiting for user to scan and submit photos
uploadingUser is actively uploading images
completedAll images processed and delivered
expiredSession expired before the user submitted photos
failedDelivery failed after all retries exhausted