PrintShelf API
Every account has an API key. Find yours on the Account page. Pass it as a Bearer token on every request.
Authentication
Authorization: Bearer <your-api-key>
The same key works for all endpoints. You can regenerate it from the Account page if needed. Keep it secret — it has full read/write access to your account.
Base URL
https://printshelf.app
Interactive docs (Swagger UI) are available at /docs. ReDoc is at /redoc.
Quick start — log a print
curl -X POST https://printshelf.app/api/prints \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Benchy",
"source_platform": "manual",
"status": "printed",
"rating": 4,
"filament_used_g": 15.2,
"print_time_mins": 48,
"is_public": true
}'
Endpoints
Prints
GET | /api/prints | List your prints. Params: queued, status, printer_id, limit, offset |
POST | /api/prints | Log a new print |
POST | /api/prints/queue | Add to queue (forces queued=true) |
GET | /api/prints/{id} | Get a single print |
PATCH | /api/prints/{id} | Update a print (partial — only send fields you want to change) |
POST | /api/prints/{id}/printed | Move a queued print to printed |
DELETE | /api/prints/{id} | Delete a print |
Filaments
GET | /api/filaments | List your filaments |
POST | /api/filaments | Add a filament spool |
GET | /api/filaments/{id} | Get a single filament |
PATCH | /api/filaments/{id} | Update a filament |
DELETE | /api/filaments/{id} | Delete a filament |
Printers
GET | /api/printers | List your printers |
POST | /api/printers | Register a printer |
GET | /api/printers/{id} | Get a single printer |
PATCH | /api/printers/{id} | Update a printer |
DELETE | /api/printers/{id} | Delete a printer |
Print fields
| Field | Type | Notes |
|---|---|---|
title | string | Required. Max 300 chars. |
designer | string | Optional. |
source_platform | string | manual, printables, makerworld, thingiverse, cults3d, myminifactory |
source_url | string | Model page URL. |
photo_url | string | URL to your photo. Use POST /api/uploads/photo to upload to R2. |
printer_id | int | Must belong to your account. |
filament_ids | int[] | Array of filament IDs. Must belong to your account. |
status | string | printed, failed, partial |
rating | int | 1–5. |
queued | bool | True = in queue. False = logged print. |
is_public | bool | Show on public shelf. |
print_date | date | ISO 8601 — 2026-06-02. |
layer_height | float | mm, e.g. 0.20. |
infill_pct | int | 0–100. |
supports | bool | true / false. |
print_time_mins | int | Total minutes. |
filament_used_g | float | Grams. |
video_url | string | YouTube, TikTok, Instagram, etc. |
notes | string | Free text. |
Upload a photo
curl -X POST https://printshelf.app/api/uploads/photo \ -H "Authorization: Bearer YOUR_API_KEY" \ -F "file=@/path/to/photo.jpg"
Returns {"url": "https://cdn.printshelf.app/..."}. Pass that URL as photo_url when creating or updating a print.
Import from a model URL
curl -X POST https://printshelf.app/api/import-url \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://www.printables.com/model/12345"}'
Scrapes the page and returns title, designer, thumbnail_url, and source_platform. Makerworld is partially supported — title only; use the Chrome extension for full imports.
Responses
All endpoints return JSON. Lists return {"items": [...], "total": N, "limit": N, "offset": N}.
| Status | Meaning |
|---|---|
200 | OK |
201 | Created |
204 | Deleted |
400 | Bad request — check field values |
401 | Missing or invalid API key |
402 | Free-tier limit hit — upgrade to Pro |
404 | Not found or doesn't belong to your account |
429 | Rate limited — slow down |
Get your API key
Sign up or log in to get your API key from the Account page.