Docs/Long Polling

Long Polling

Use long polling when your server cannot receive inbound webhook requests — for example, during local development or when deployed behind a restrictive firewall.

When to use long polling

Server behind a firewall or NAT (no public URL)

Shared hosting that blocks incoming webhooks

Hosting with restrictive upload size limits (since you pull images, not receive them)

Local development without tunneling (ngrok, etc.)

Serverless environments with short execution timeouts

When you need to process images at your own pace

Production note

For production use, webhooks are recommended. Long polling requires your server to maintain a continuous polling loop and acknowledge each image individually.

Endpoints

GET/api/v1/sessions/:id/poll

Long-polls for the next unacknowledged image. The server holds the connection open for up to 30 seconds. If an image becomes available, it is returned immediately. If no image arrives within 30 seconds, the server returns a 204 No Content response.

Query parameters

ParameterTypeDescription
timeoutintegerMax seconds to wait. Default 30, max 30.
GET/api/v1/images/:imageId/download

Downloads the raw image bytes. Returns the image with the appropriate Content-Type.

POST/api/v1/images/:imageId/ack

Acknowledges that your server has successfully received and processed the image. Unacknowledged images will be returned again on the next poll request. Must be called within 5 minutes of receiving the image.

Polling loop example

# Single poll request (returns 200 with image info, 204 if nothing, 410 if done)
curl -H "Authorization: Bearer aptr_xxxx" \
  "https://api.apertur.ca/v1/sessions/sess_01HX.../poll?timeout=30"

# Download an image
curl -H "Authorization: Bearer aptr_xxxx" \
  -o photo.jpg \
  "https://api.apertur.ca/v1/images/img_01HX.../download"

# Acknowledge an image
curl -X POST -H "Authorization: Bearer aptr_xxxx" \
  "https://api.apertur.ca/v1/images/img_01HX.../ack"

Poll response format

{
  "image_id": "img_01HX...",
  "image_index": 0,
  "filename": "photo.jpg",
  "mime_type": "image/jpeg",
  "size_bytes": 245000,
  "session_status": "uploading",
  "tags": {
    "user_id": "usr_abc123"
  }
}

Download the image bytes using GET /api/v1/images/:imageId/download.