Overview
The Photo Timeline endpoints let participants discover their photos by when they were captured. Use the days endpoint to render a date / hour picker, then fetch a windowed slice of photos with the images endpoint. Photos are bucketed and queried by the capture timestamp recorded on each image; photos without a timestamp are excluded from both endpoints.
Photo timeline must be enabled for the event. Check the timeline_search flag from Event Details before calling either endpoint.
This endpoint always returns every timestamped photo mapped to the event. It does not honour internal visibility flags such as show_all_images.
Endpoints
GET /api/v1/ext/{org_id}/event/{event_id}/timeline/days
GET /api/v1/ext/{org_id}/event/{event_id}/timeline/images
Path Parameters
| Parameter | Type | Required | Description |
|---|
org_id | number | Yes | Your organisation ID. |
event_id | number | Yes | The event whose timeline you want to query. |
GET /timeline/days — Day and Hour Buckets
Returns per-day and per-hour photo counts for the timeline picker. Days are ordered ascending by date; within each day, hours are ordered ascending by hour. Dates are UTC calendar dates in YYYY-MM-DD format and hours are UTC hour values (0–23).
Query Parameters
This endpoint takes no query parameters.
Example Request
curl -i \
-H "X-API-Key: <your_9pic_api_key>" \
"https://api.9pic.ai/api/v1/ext/903/event/456/timeline/days"
Example Response
Buckets Found
No Timeline Data
{
"responseType": "success",
"message": "Timeline buckets",
"data": {
"days": [
{
"date": "2024-01-01",
"total": 125,
"hours": [
{ "hour": 10, "count": 98 },
{ "hour": 11, "count": 27 }
]
},
{
"date": "2024-01-02",
"total": 42,
"hours": [
{ "hour": 9, "count": 42 }
]
}
]
}
}
{
"responseType": "success",
"message": "No timeline data",
"data": {
"days": []
}
}
GET /timeline/images — Windowed Photos
Returns paginated photo objects (large URL, thumbnail URL, image ID, width, height) captured within a [from, to) Unix-epoch-second window, ordered by ascending capture timestamp.
Query Parameters
| Parameter | Type | Required | Description |
|---|
from | number | Yes | Window start as Unix epoch seconds. Inclusive. |
to | number | Yes | Window end as Unix epoch seconds. Exclusive. Must be greater than from. |
page | number | No | Page number (default: 1). |
page_size | number | No | Images per page (default: 32, max: 100). |
Example Request
curl -i \
-H "X-API-Key: <your_9pic_api_key>" \
"https://api.9pic.ai/api/v1/ext/903/event/456/timeline/images?from=1704103200&to=1704108000&page=1&page_size=32"
Example Response
Images Found
Empty Window
{
"responseType": "success",
"message": "Records for timeline window",
"data": {
"images": [
{
"img_url": "https://photos.9pic.ai/imgs/456/large/a4402318-0cf4-4e1e-b8e8-ac8e8f2fc244.jpg",
"height": 4860,
"width": 3240,
"image_id": "a4402318-0cf4-4e1e-b8e8-ac8e8f2fc244",
"thumbnail_url": "https://photos.9pic.ai/imgs/456/small/a4402318-0cf4-4e1e-b8e8-ac8e8f2fc244.jpg",
"original_url": null
},
{
"img_url": "https://photos.9pic.ai/imgs/456/large/b5513429-1d05-5f2f-c9f9-bd9f9g3gd355.jpg",
"height": 4860,
"width": 3240,
"image_id": "b5513429-1d05-5f2f-c9f9-bd9f9g3gd355",
"thumbnail_url": "https://photos.9pic.ai/imgs/456/small/b5513429-1d05-5f2f-c9f9-bd9f9g3gd355.jpg",
"original_url": null
}
],
"pagination": {
"total": 125,
"currentPage": 1,
"totalPages": 4,
"hasNextPage": true,
"hasPreviousPage": false,
"page_size": 32
}
}
}
{
"responseType": "success",
"message": "No images found",
"data": {
"images": [],
"pagination": {
"total": 0,
"currentPage": 0,
"totalPages": 0,
"hasNextPage": false,
"hasPreviousPage": false,
"page_size": 32
}
}
}
Response Models
| Model | Description |
|---|
| TimelineDaysResponse | Top-level envelope for GET /timeline/days. |
| TimelineDayItem | One date bucket inside data.days[]. |
| TimelineHourBucket | One hour bucket inside data.days[].hours[]. |
| TimelineImagesResponse | Top-level envelope for GET /timeline/images. |
| ImageItem | Image object returned inside data.images[]. |
| PaginationInfo | Pagination metadata returned inside data.pagination. |
original_url is null in the timeline response. Use Download Original Photos with method: "image_ids" to fetch presigned download links for the originals once a participant picks photos from their window.
Error Responses
| Status | Meaning |
|---|
400 | to is not greater than from. |
401 | API key is missing. |
403 | API key is invalid, inactive, token/event ownership mismatch, or photo timeline is disabled for this event. |
404 | Event configuration not found. |
422 | Required from or to query parameter is missing or not an integer. |
429 | Rate limit exceeded. Back off and retry. |
500 | Internal failure. |
See Errors for canonical descriptions and retry guidance.