API v1
Your own registration system can register exhibits in your expo and follow their status. The API belongs to one expo: it is the expo of the key you use. It only registers: once an exhibit is accepted, it is evaluated together with the rest of the expo's exhibits when you run the expo's evaluation, never at the moment it arrives.
Before you start
- In the expo's Setup, add API to the registration methods.
- In the expo's API keys tab, create a key. You see it once; it starts with
jpk_.
Every request carries Authorization: Bearer <key>. The limit is 60 requests per minute per key. Errors are JSON, {"detail": "..."}, with the usual status: 401 (bad or revoked key), 403 (the expo does not accept the API method, or the exhibitor was declined), 404, 422 (the request is not acceptable, the detail says why), 429.
Register an exhibit
POST https://api.stamp.show/api/v1/exhibits
{
"exhibitor": { "email": "ana@example.com", "name": "Ana Pérez", "country": "PE", "phone": "+51 1 555 0100" },
"exhibit": { ...an Open Exhibit document... }
}
| Field | |
|---|---|
exhibitor.email | Required. The exhibitor is created in the expo (accepted) the first time, and reused afterwards. No invitation e-mail is sent. |
exhibitor.name / country / phone | Optional. country is ISO 3166-1 alpha-2. They only fill what is still empty. |
exhibit | Required. An Open Exhibit document: title, class, frames and sheets, and for every sheet (and synopsis page) an image.uri we download. The document's rulesets must include the expo's (FIP or APS), its class must be one the expo accepts, and its id makes a retried request harmless: the same id answers the first submission again (200). |
Images must be JPEG or PNG, at most 15 MB each, on a public host that answers without redirects. If you give a checksum, it is verified. The answer is 202 with the submission:
{
"id": "k3m9x2qa7p",
"source_id": "exh-001",
"status": "processing",
"error_message": null,
"created_at": "2027-03-01T10:15:00Z",
"exhibit": { "title": "The 1856 issue", "class": "traditional", "exhibitor_email": "ana@example.com", "application_status": "draft" },
"evaluation": null
}
Follow a submission
GET /api/v1/exhibits/{id} and GET /api/v1/exhibits (the expo's submissions, newest first).
status | |
|---|---|
processing | The images are being downloaded (a failed download is retried three times). |
ready | The exhibit is registered: exhibit.application_status is accepted. The organizer was told by e-mail. |
failed | error_message says why. See below. |
evaluation stays null until the organizer evaluates the expo's exhibits. Then it shows status (pending, running, completed, failed) and, when completed, total_score, medal, criteria_breakdown, global_justification and considerations. Poll the exhibit to read it: nothing is pushed to your system.
When something goes wrong
There is nothing for your system to retry by hand. Whoever can fix the problem is told by e-mail:
- The exhibitor, when the problem is in what was sent: an image that cannot be downloaded or read, a checksum that does not match, a synopsis the expo requires. They get a link to the exhibitor portal, where the exhibit is waiting as a draft with whatever did arrive, and finish it by hand. If the expo does not use the portal, the organizer is told instead.
- The organizer, when the problem is on our side, or the expo's entry limit was reached (the draft is withdrawn in that case). Your system can submit again once it is fixed: a failed submission does not block the same document
id.
Example
curl -X POST https://api.stamp.show/api/v1/exhibits \
-H "Authorization: Bearer jpk_..." -H "Content-Type: application/json" \
-d @submission.json
Rotating a key
Rotating generates a new secret; the previous one keeps working for 48 hours so you can switch without downtime. Revoking disables a key at once.