Printy3D

Getting started

Authentication & keys

Every request carries a secret API key as a bearer token. Keys are test or live, carry scopes, and can be rotated without downtime.

Sending the key#

Put the key in the Authorization header of every /v1 request. Only the presigned storage URLs (uploads and downloads) are called without it.

export PRINTY3D_API_KEY=p3d_test_...   # from the console
API=https://printy3d-api-staging.onrender.com
curl -sS "$API/v1/org" -H "Authorization: Bearer $PRINTY3D_API_KEY"

A missing or malformed header answers 401 unauthenticated; an unknown, revoked or expired key answers 401 invalid_api_key. A key without the scope an endpoint needs answers 403 insufficient_scope.

Test keys and live keys#

Test (p3d_test_…)Live (p3d_live_…)
JobsInspect, repair, tools and Exact Check in a sandboxThe real engine (GPUs; CPUs for Exact Check)
Resultssimulated: true; the geometry is not processed (a one-triangle mesh, labelled thumbnails)Real analysis and meshes
CostFree, never touches creditsCredits: 1 credit = 1 second of run time
AvailableAs soon as you sign upOnce your account is approved
ExportsOnly formats the job generatedAny format; conversions are charged
DataTest files and jobs onlyLive files and jobs only

Objects, statuses, headers and errors are the same in both modes, so code written against test keys works unchanged with a live key. Test mode is for integrating the request, upload, poll and download flow, not for judging repair quality. Every object carries livemode.

Scopes#

A key can do only what its scopes allow. Give each integration the smallest set it needs; the console offers Full access, Run jobs and Read only presets, or pick scopes yourself.

ScopeAllows
files:readList and read uploaded files, formats and repair profiles
files:writeUpload and complete files
jobs:readRead jobs and their events
jobs:writeCreate and cancel jobs, request exports
artifacts:readList and download job outputs
webhooks:manageManage webhook endpoints
keys:manageCreate, rotate and revoke API keys
usage:readRead the credit balance and transactions
org:readRead the account (organization)

The scope each endpoint needs is listed in the API reference. webhooks:manage registers, lists and deletes webhook endpoints. A key created with an API key (rather than in the console) can never have more scopes than the key that created it.

Creating, rotating and revoking keys#

The console is the simplest place to manage keys. A key with keys:manage can do the same over the API, for the mode it belongs to:

GET/v1/api_keyskeys:manage
POST/v1/api_keyskeys:manage
# Create a read-only key that expires at the end of the year.
curl -sS "$API/v1/api_keys" \
  -H "Authorization: Bearer $PRINTY3D_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"name": "dashboard", "scopes": ["jobs:read", "artifacts:read"], "expires_at": "2026-12-31T23:59:59Z"}'
# -> 201 {"api_key": {...}, "secret": "p3d_test_..."}   (the secret is shown once)

# Rotate it: a new secret, the old one keeps working for an hour.
curl -sS -X POST "$API/v1/api_keys/$KEY_ID/rotate" \
  -H "Authorization: Bearer $PRINTY3D_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"grace_seconds": 3600}'

# Revoke it.
curl -sS -X DELETE "$API/v1/api_keys/$KEY_ID" -H "Authorization: Bearer $PRINTY3D_API_KEY"
  • The secret is returned once, in the 201 answer. Replaying the same request with the same Idempotency-Key returns the key with secret: null and Idempotent-Replayed: true; rotate the key if you lost the secret.
  • Rotation creates one successor with the same mode and scopes. The old key keeps working for grace_seconds (0 to 604,800, default 86,400 = 24 h); its superseded_by and grace_until say so. A key can be rotated once.
  • Revocation takes effect at once and cannot be undone; revoking an already revoked key is harmless.
  • An account holds at most 25 active keys; creating a 26th answers 409.
  • Key metadata (prefix, last_used_at, expires_at) is always readable; the secret and its hash never are.

Your account#

Each person who signs up gets a personal account (an organization in API terms). Files, jobs, keys and credits belong to it. GET /v1/org returns it with its plan_id and status (active, suspended or deleting). Objects of another account are always 404 not_found, never 403.