The data model (Productions, steps, media, References), the statuses, and the conventions shared by every endpoint: pagination, filters, errors, quotas.
A Production is a batch of media that follows a workflow. Each step of the workflow is a bench; the benches are created with the Production, from its template (/production/template).
The benchsteptype field gives the role of each step:
benchsteptype | Step |
|---|---|
| 10 | Live (shooting) |
| 20 | Post-production, Phase 1 |
| 30 | Post-production, Phase 2 |
| 40 | Exports / Approval |
The Live and the Exports / Approval step always exist; Post-production is optional (zero, one or two phases). Each account can rename its steps: rely on benchsteptype, not on the label.
A Production is identified by bench_root_id, the id of its first step; each step has its own bench_id. Media are uploaded to the Live and Post-production steps. Files are never uploaded to step 40: media reach it when the exports are triggered (POST /production/{bench_root_id}/export), and are then submitted for approval there.
The status of the Production (benchstatus):
benchstatus | Meaning |
|---|---|
| 10 | Active |
| 20 | In progress |
| 30 | Finished |
| 35 | Being archived |
| 40 | Archived |
| 50 | Flushed |
A media (picture) is the file being worked on: photos, videos, PDFs and 3D share the same object. It carries the Reference (ref), the View code (view_type_code), the step it is in (bench_id), its tags (taginfo) and its picturestatus:
picturestatus | Meaning | Steps where it applies |
|---|---|---|
| 1 | Ignored | |
| 5 | To reshoot | Live |
| 10 | Not selected | Live |
| 30 | Selected | Live, Post-production |
| 35 | Refused by a retoucher | Post-production |
| 31 | Refused at approval | Approval |
| 40 | Submitted for approval | Approval |
| 50 | Approved | Approval |
| 51 | Ready to publish | Approval (Publication) |
| 52 | Publication error | Approval (Publication) |
| 55 | Published | Approval (Publication) |
| 80 | Archived | Approval |
To get the file: thumbnail gives a thumbnail, GET /picture/{id}/download the original file, and POST /picture/{id}/publicurl a temporary link usable without a token (one hour by default, seven days at most), handy to pass it to a third-party system.
A Reference (reference) is a product of the Catalog, identified by its ref code. POST /reference creates or updates it; POST /reference/bulk imports a batch. The Specifications describe the expected media: /specification/category (expected View codes per product category) and /specification/format (dimensions, resolution, ICC profile, weight, file format).
| Endpoint | Content |
|---|---|
/account/me | User, accessible accounts, api_host of each account |
/shootingmethod | Shooting methods |
/shotlist | Shotlists |
/stock, /stock/batch, /stock/zone | Logistics: Articles, shelves, zones |
/broadcast | Publication of the approved media |
/webhook | Webhook subscriptions |
The complete list is on api.grand-shooting.com.
/picture and /reference return 100 items per page. The next page is requested with the offset header (0, 100, 200…); the response gives the total in X-Total-Count, and the position in X-Offset and X-Count.
curl -i -H "Authorization: Bearer $GS_TOKEN" -H "offset: 100" \
"https://api.grand-shooting.com/v3/picture?bench_root_id=1234"
offset is limited to 10,000. Beyond that, paginate with a cursor: sort on the id and start again from the last one received.
curl -H "Authorization: Bearer $GS_TOKEN" \
"https://api.grand-shooting.com/v3/picture?sort_by=picture_id&picture_id=gt:987654"
Any field of the object can be used as a filter in the URL parameters:
| Syntax | Effect |
|---|---|
picturestatus=50 | Equality |
picturestatus=40&picturestatus=50 | Repeated field: OR |
date_mod=gte:2026-10-01 | Operators gt:, gte:, lt:, lte: (two bounds on the same field are combined with AND) |
ref=null:true | Empty value (null:false: value set) |
search=dress | Full-text search |
sort_by=-date_mod | Descending sort (+ or nothing: ascending) |
Dates use the ISO 8601 format (2026-10-01T07:00:00.000Z).
The API follows the standard HTTP codes. Errors have a JSON body:
{
"code": 404,
"error": "Not Found",
"message": "Resource was not found"
}
The most frequent ones: 400 (missing or invalid field, the message says which one), 401 (missing or invalid token, or a write with a read-only token), 403 (action not allowed for this account), 429 (quota exceeded). Some bulk endpoints answer 207 with the result of each item.
The quota is 5 requests per second per account, shared by all the tokens of the account. Beyond that, the API answers 429. The X-RateLimit-UserLimit, X-RateLimit-UserRemaining and X-RateLimit-UserReset headers let you slow down before being blocked. Prefer the bulk endpoints (/reference/bulk, /upload/url, POST /picture/picturestatus) to loops of single calls, and webhooks to repeated polling.
Endpoints have no idempotency key. POST /reference is an upsert on ref: replaying it does not create a duplicate. For uploads, check the response for each file before retrying.