The REST API lets your own systems do what your team does in the app: create estimates and send designer links, nest parts, run imposition jobs, and manage equipment and teams. Requests and responses are JSON, except file uploads (multipart) and file downloads.
What you can automate#
Almost every API lives under your team's address, so the team is part of each URL. <team_slug> is the Team ID
from your team settings.
| Area | Base path | Guide |
|---|---|---|
| Estimating | /a/<team_slug>/estimating/api/v1/ |
Estimating API |
| Nesting | /a/<team_slug>/nesting/api/v1/ |
Nesting API |
| Imposition | /a/<team_slug>/imposition-layout/api/v1/ |
Imposition API |
| Equipment | /a/<team_slug>/production/api/v1/ |
Equipment API |
| Teams | /teams/api/ and /a/<team_slug>/team/api/ |
Teams API |
| Files | /a/<team_slug>/files/api/v1/ |
Files API |
| Prepress, preflight and approvals | under /a/<team_slug>/ |
Prepress, Preflight, Approvals |
Every endpoint of every area is listed in the API reference.
API access for custom integrations (also called the workflow API) means these REST endpoints, used with an API
key by software you or a developer build. It does not include a visual workflow builder or prebuilt third-party
connectors. Workflow endpoints require Production, the Production trial, or an active Plant agreement when accessed
with an API key. The Files API is available on every plan. Each operation also respects the team's feature access.
If an operation is outside your plan, the API returns 403 with code: plan_required.
API keys and authentication#
Send an API key in the Authorization header of every request:
GET /a/acme/nesting/api/v1/limits/ HTTP/1.1
Host: app.example.com
Authorization: Api-Key YOUR_API_KEY
export API_KEY="paste your key here"
curl -sS -H "Authorization: Api-Key $API_KEY" \
"https://app.example.com/a/acme/nesting/api/v1/limits/"
- Getting a key. Create one under API Keys on your profile (see Your account, 2FA and API keys). The key is shown once.
- A key acts as its owner. It can reach every team the owner belongs to, with the owner's role there. Use a dedicated user for an integration if you want to limit what it can reach, and invite that user only to the teams it needs.
- Failures. A missing, wrong or revoked key, or a key whose owner is not a member of the team in the URL, gets
403with adetailmessage. - Keep it secret. Send keys only over HTTPS, keep them out of code repositories and front-end JavaScript, and revoke a key you no longer use.
Browser sessions#
Pages of the app call the same APIs with the signed-in user's session cookie. If you build on that (for example a
script in a page served by the app), requests that change data (POST, PUT, PATCH, DELETE) must also send the
CSRF token from the csrftoken cookie in an X-CSRFToken header. Server-to-server integrations should use an API key
instead.
Errors#
Errors are JSON. Most look like one of these:
{"detail": "Authentication credentials were not provided."}
{"name": ["This field is required."], "metadata": ["Metadata must be 16 KB or smaller."]}
The nesting API lists every problem with the path of the field in the request:
{"errors": [{"path": "parts[3].outline", "message": "Give at least 3 points as [x, y]."}]}
| Status | Meaning |
|---|---|
400 |
The request is invalid. The body names the fields. |
403 |
No valid key or session, or the user can't do this in this team. |
404 |
The object doesn't exist in this team. |
405 |
The method isn't supported here (for example PUT where only PATCH exists). |
409 |
A conflict, such as an external_id that is already used, or a job that has already finished. |
410 |
A designer link was revoked or has expired. |
413 |
The request is too large: a JSON body over 5 MB, or over a nesting limit. |
422 |
A nest found no valid layout. |
429 |
Too many requests: see limits. |
503 |
A service the request needs, such as nesting, is unavailable. Try again later. |
Limits#
- Request size. JSON bodies to the estimating, nesting, imposition and equipment APIs are limited to 5 MB
(
413). File uploads have their own limits, given in each guide. - Starting nests is limited to 60 per minute per user (
429). Polling a job is not limited this way. - Nest size and time have their own limits: see Nesting API.
Other endpoints have no published rate limit. Poll at a sensible interval (see polling) and back off when
you get a 429 or a 503.
Pagination#
Lists that can grow without bound are paged, 100 items per page:
{"count": 250, "next": "https://app.example.com/a/acme/estimating/api/v1/estimates/?page=2", "previous": null,
"results": [{"id": 42, "name": "Menu 11x17"}]}
Follow next until it is null. Paged lists include estimates, nest jobs, teams and invitations. Short lists, such
as materials, machines, printers and an estimate's designer links, come back as a plain JSON array.
Versions and stability#
The version is part of the path (/api/v1/). Within a version, new fields and endpoints may be added, but existing
fields keep their names and meaning. Write clients that ignore fields they don't know. Operation ids (such as
estimating_estimates_create) are stable, so generated clients keep their method names.
The OpenAPI schema and reference#
The whole API is described by an OpenAPI 3 schema, which you can read without signing in. It describes the shape of every endpoint but contains no data, and every call still needs a key or a session.
| What | Where |
|---|---|
Schema (YAML; add ?format=json for JSON) |
https://app.example.com/api/schema/ |
| API reference (read) | https://app.example.com/api/schema/redoc/ |
| Interactive reference (try calls) | https://app.example.com/api/schema/swagger-ui/, also Help › API docs in the app |
To call the API from your own language, generate a client from the schema with any OpenAPI generator. The schema
declares the Authorization header as its security scheme.
Polling instead of webhooks#
The API doesn't send webhooks. Long-running work gives you something to poll instead:
- Nest jobs return a job URL. Poll it every one or two seconds until the status is
succeeded,failedorcancelled. See Nesting API. - Estimates show
designer_submitted_atonce a customer has finished in the designer. List estimates withupdated_sinceset to the time of your last poll, every 30 to 60 seconds. See Estimating API.