Skip to content
Docs
Sign in

Approvals API

Create artworks, upload versions, make and email proof links, follow their status and read the full history of decisions.

For integrators

The approvals API does what the Approvals page and the proof page do: artworks, versions, proof links, emails to reviewers, resets and the history. Every endpoint is under your team, at /a/<team_slug>/artwork-approvals/api/v1/.

Every call takes the same authentication as the rest of the API: an API key of a team member, or a signed-in session that also sends its CSRF token when it changes data (see authentication).

Every member of the team can read and write. Reviewers don't use this API: they comment and decide on the proof page. How approvals work is in How approvals work.

From upload to approval#

ARTWORKS=https://app.example.com/a/acme/artwork-approvals/api/v1/artworks/
VERSIONS=https://app.example.com/a/acme/artwork-approvals/api/v1/versions/
LINKS=https://app.example.com/a/acme/artwork-approvals/api/v1/approval-requests/
AUTH="Authorization: Api-Key $API_KEY"

# 1. Create an artwork (the answer has its id, here 42)
curl -s -X POST "$ARTWORKS" -H "$AUTH" -H "Content-Type: application/json" -d '{"name": "Carton 200"}'

# 2. Upload its first version (the answer is the version, here id 43)
curl -s -X POST "$VERSIONS" -H "$AUTH" -F artwork=42 -F pdf_file=@carton-200.pdf -F notes="First proof"

# 3. Read the version's Simple and Advanced links (the simple one here has id 44), then email it
curl -s -X POST "${VERSIONS}43/share-links/" -H "$AUTH"
curl -s -X POST "${LINKS}44/send/" -H "$AUTH" -H "Content-Type: application/json" \
  -d '{"emails": ["buyer@example.com"], "message": "Please check the barcode."}'

# 4. Follow the status of the version's links, and read the history
curl -s "${LINKS}?version=43" -H "$AUTH"
curl -s "${ARTWORKS}42/history/" -H "$AUTH"

Artworks#

GET /a/{team_slug}/artwork-approvals/api/v1/artworks/

artworks_list · View in API reference

POST /a/{team_slug}/artwork-approvals/api/v1/artworks/

artworks_create · View in API reference

GET /a/{team_slug}/artwork-approvals/api/v1/artworks/{id}/

artworks_retrieve · View in API reference

PATCH /a/{team_slug}/artwork-approvals/api/v1/artworks/{id}/

artworks_partial_update · View in API reference

PUT /a/{team_slug}/artwork-approvals/api/v1/artworks/{id}/

artworks_update · View in API reference

GET /a/{team_slug}/artwork-approvals/api/v1/artworks/{id}/versions/

Every uploaded version of this artwork, newest first.

artworks_versions · View in API reference

FieldDescription
idThe artwork's id.
nameThe artwork's name, up to 255 characters. The only field you can write.
created_atWhen the artwork was created.
updated_atLast activity: uploads, links, emails, decisions, resets and comments move it forward.
version_countHow many versions the artwork has.
latest_versionThe newest version (a version object), or null before the first upload.

The list is paged (100 per page, newest activity first); versions/ of an artwork returns all of them as a plain array, newest first. Artworks can't be deleted through the API.

Versions#

POST /a/{team_slug}/artwork-approvals/api/v1/versions/

Upload a PDF as the next version of an artwork.

artwork_versions_upload · View in API reference

GET /a/{team_slug}/artwork-approvals/api/v1/versions/

artwork_versions_list · View in API reference

GET /a/{team_slug}/artwork-approvals/api/v1/versions/{id}/

artwork_versions_retrieve · View in API reference

GET /a/{team_slug}/artwork-approvals/api/v1/versions/{id}/pdf/

Download the version's PDF (team members only; the file is never public).

artwork_versions_pdf · View in API reference

GET /a/{team_slug}/artwork-approvals/api/v1/versions/{id}/advanced-preview/

Build status of the separations preview (ready, building, failed, missing or stale).

artwork_versions_advanced_preview · View in API reference

POST /a/{team_slug}/artwork-approvals/api/v1/versions/{id}/advanced-preview/

Build the separations preview now, or retry a failed build.

artwork_versions_advanced_preview_build · View in API reference

An upload is multipart, with these fields:

FieldDescription
artworkRequired. The artwork's id; the version gets the artwork's next number.
pdf_fileRequired. The PDF, at most 200 MB. The name must end in .pdf and the file must be a PDF.
notesOptional. What changed in this version, up to 5,000 characters.
client_file_pathOptional. Where the file came from on your side, such as a path or an order reference (up to 1,024 characters). It is kept with the version and never shown to reviewers.
files_folderOptional. The id of a Files folder for the artwork's first file. Default: the Approvals folder. Later versions always go to the artwork's file, wherever it is.

It answers 201 with the version. The upload makes the version's Simple and Advanced links, and starts preflight and the print preview. The PDF is kept in Files too (see Proofs and Files). A version reads as:

FieldDescription
idThe version's id.
artworkThe artwork's id.
version_number1, 2, 3 and so on, per artwork.
pdf_urlThe team download of the PDF (the pdf action). It needs your API key or session.
original_filenameThe uploaded file's name.
client_file_pathWhat you sent as client_file_path, or empty.
spot_colorsThe names of the spot colours found in the PDF, in the order they were found.
notesThe version's notes.
uploaded_atWhen the version was uploaded.
advanced_previewThe separations preview: status ready, building (with progress), failed, missing or stale.
file_idThe id of the Files file the version was made from, or null for a version from before Files.
file_versionThe id of that version in Files, or null.
file_version_numberIts version number in Files (v5), which is independent of version_number; or null.
file_latest_version_numberThe file's current version number in Files, or null when the file is in the trash. Higher than file_version_number: a newer version is waiting in Files.

GET …/advanced-preview/ only reports the preview's status and never starts a build. POST to the same address builds it now, or again after a failure, and answers with the new status. versions/ can be filtered with ?artwork=42.

Versions from Files#

POST /a/{team_slug}/artwork-approvals/api/v1/versions/from-file/

Send a PDF version from Files for approval: the next version of the artwork that already proofs that file (or of `artwork`, or of a new artwork), using the same bytes, never a copy.

artwork_versions_from_file · View in API reference

POST …/versions/from-file/ sends a PDF that is already in Files for approval, by the id of its file version (the Files API lists them). Nothing is uploaded: the version shows the same bytes. It takes JSON with these fields:

FieldDescription
file_versionRequired. The id of a ready PDF version in your team's Files, at most 200 MB.
artworkOptional. The artwork that gets the version. Default: the artwork that already proofs this file, else a new one.
nameOptional. The name of a new artwork, up to 255 characters. Default: the file name without .pdf.
notesOptional. What changed in this version, up to 5,000 characters.
share_modesimple (default) or advanced: the link emailed to the reviewers.
emailsOptional. Up to 50 reviewer addresses to email the link to. They become invited approvers.
same_reviewerstrue also emails the approvers of the artwork's previous version (default false). Nobody is emailed again when no version was added.
messageOptional text above the link in the email, up to 5,000 characters.
curl -s -X POST "${VERSIONS}from-file/" -H "$AUTH" -H "Content-Type: application/json" \
  -d '{"file_version": 42, "same_reviewers": true, "message": "The barcode is fixed."}'

Without artwork, the version goes to the artwork that already proofs the file, or to a new artwork named name (or after the file). It answers 201 with the new version. When that artwork's latest version already shows this file version, nothing is added and it answers 200 with that version, so a retried request never adds a second one (the reviewers in emails are still invited to it). Compare a version's file_version_number with file_latest_version_number to find artworks with a newer version waiting in Files (see Proofs and Files).

POST /a/{team_slug}/artwork-approvals/api/v1/versions/{id}/share-links/

The version's default simple and advanced links (created when missing).

artwork_versions_share_links · View in API reference

POST /a/{team_slug}/artwork-approvals/api/v1/versions/{id}/request-approval/

Create a simple or advanced share link for this version (same as POST approval-requests).

artwork_versions_request_approval · View in API reference

POST /a/{team_slug}/artwork-approvals/api/v1/approval-requests/

Generate a simple or advanced viewer link and optionally email it to reviewers.

approval_requests_create · View in API reference

GET /a/{team_slug}/artwork-approvals/api/v1/approval-requests/

approval_requests_list · View in API reference

GET /a/{team_slug}/artwork-approvals/api/v1/approval-requests/{id}/

approval_requests_retrieve · View in API reference

POST /a/{team_slug}/artwork-approvals/api/v1/approval-requests/{id}/send/

Email this link to reviewers (they are added as approvers).

approval_requests_send · View in API reference

POST /a/{team_slug}/artwork-approvals/api/v1/approval-requests/{id}/reset/

Put the request back to pending (clears every reviewer's decision).

approval_requests_reset · View in API reference

POST …/versions/{id}/share-links/ returns the version's own links, {"simple": {…}, "advanced": {…}}, and makes any that are missing. request-approval/ and POST approval-requests/ make a new, separate link each time, with these fields:

FieldDescription
versionRequired on approval-requests/. The version's id; request-approval/ takes it from its URL.
share_modesimple (default) or advanced: the viewer the link opens.
emailsOptional. Up to 50 reviewer addresses. They become invited approvers of the link.
subjectOptional email subject, up to 255 characters. Default: "Approval requested: <artwork> v<number>".
messageOptional text above the link in the email, up to 5,000 characters.
send_emailtrue (default) emails the link to emails; false only adds them as approvers.

Warning: Addresses given with send_email: false

The emails of a new link become invited approvers even when no email is sent. An invited address can only comment and decide from its personal link, so these reviewers can't decide until you email them the link with send/, and the link stays pending until they do.

send/ emails an existing link and adds the addresses as approvers:

FieldDescription
emailsRequired. 1 to 50 reviewer addresses. Each gets a personal link and becomes an approver.
messageOptional text above the link in the email, up to 5,000 characters.

reset/ puts the link back to pending, like Reset to pending on the proof page (see Decisions, locking and reset):

FieldDescription
reasonOptional. Why the link is reset, up to 2,000 characters. Kept in the history.

A link reads as:

FieldDescription
idThe link's id.
tokenThe secret part of the link's address. Anyone who has it can open the proof.
urlThe reviewer link to open or send.
share_modesimple or advanced.
viewsThe proof views the link was made with: ["flat"], or with "3d" for a 3D proof.
sceneThe id of the link's 3D proof, or null.
statuspending, approved or rejected (the link's own status).
artworkThe artwork's id.
versionThe version's id.
version_numberThe version's number.
requested_byThe name of the team member who made the link, or empty.
email_subjectThe subject its emails use.
email_messageThe message sent with it when it was made.
created_atWhen the link was made.
recipientsThe link's reviewers (see below).
commentsEvery comment made on the link (see below).

Its recipients are:

FieldDescription
idThe reviewer's id on this link.
emailTheir email address, in full.
nameThe name they gave, or empty.
roleapprover or viewer.
decisionpending, approved or rejected.
decision_atWhen they last decided, or null.

and its comments:

FieldDescription
idThe comment's id.
pageThe page, from 1; 0 for a general comment made with a decision.
xDistance from the left edge of the page, in points.
yDistance from the top edge of the page, in points.
widthThe width of the marked area in points; 0 for a spot.
heightThe height of the marked area in points; 0 for a spot.
surfaceflat or 3d.
anchorFor 3D comments: where the pin sits on the carton, and the camera it was made with.
contentThe comment's text, up to 5,000 characters.
commenterThe email address of who wrote it.
created_atWhen it was written.

The list is paged and can be filtered with ?version=, ?artwork= and ?status=pending|approved|rejected. A link's status is its own; the status the dashboard shows for a version combines its links (see How approvals work).

History#

GET /a/{team_slug}/artwork-approvals/api/v1/artworks/{id}/history/

Newest-first timeline: uploads, share links, decisions and resets.

artworks_history · View in API reference

The history is a plain array, newest first, of every entry of the artwork: id, kind, label, actor, at, version_id, version_number, request_id and details. The kinds are:

In the timelineAPI labelAPI kindWhat it records
v2 uploadedVersion uploadeduploadedA version was uploaded or sent from Files: its number, file name and notes, and the version number of its file in Files.
Simple link created for v2 (or Advanced link, 3D proof link)Share link createdlink_createdA link was made: Simple, Advanced or 3D, and its reviewers. Every upload makes the version's Simple and Advanced links.
Simple link emailed for v2Link sent to reviewerssentA link was emailed: to whom, and the message.
Approved v2, or Rejected v2DecisiondecisionA reviewer approved or rejected: the general comment, the status after it, and whether the address was verified by an invitation link.
Reset to pending (was approved)Reset to pendingresetA team member reset a link to pending: the reason, the status before and the decisions it cleared.
Comment on v2CommentcommentA comment: the start of its text, and its page, the 3D proof, or general.

The details of a decision hold the whole decision record: decision, comment, name, share_mode, resulting_status, verified, file_sha256, views (offered), viewed (opened), acknowledged and acknowledgement (the text confirmed), ip and user_agent. A reset holds reason, previous_status, cleared_decisions and demoted_approvers. See History and notifications.

Errors#

  • 400 with field errors for invalid input: for example {"pdf_file": ["Only PDF files are supported."]} for a file that isn't a PDF, {"emails": {"0": ["Enter a valid email address."]}} for a bad address, {"emails": ["Ensure this field has no more than 50 elements."]} for more than 50, and {"emails": ["This list may not be empty."]} for send/ without addresses. An id of another team in the body (artwork on upload, version on approval-requests/) is a field error too ({"artwork": ["Invalid pk …"]}). Other refusals are 400 with {"detail": "…"}.
  • 400 for from-file/ with a file_version that isn't a ready version of a file in your team's Files (a file in the trash doesn't count: {"file_version": ["…"]}), or that isn't a PDF of at most 200 MB ({"detail": "…"}), and for a files_folder that doesn't exist or is in the trash.
  • 507 with {"code": "quota_exceeded", "detail": "…", "needed": …, "free": …, "limit": …} when your team's Files storage is full and an upload can't be kept (see Storage). Other refusals from Files answer with their own code, detail and status.
  • 502 with {"detail": "The email could not be sent. Try again later."} when an email can't be sent. Nothing is saved then: no link is made and nobody is added.
  • 404 for an id of another team in the URL, and for the PDF of a version whose file is missing.

The general rules for keys, errors and paging are on API overview.

Every operation#

API operations tagged artwork-approvals
MethodPathWhat it does
GET /a/{team_slug}/artwork-approvals/api/v1/approval-requests/ approval_requests_list
POST /a/{team_slug}/artwork-approvals/api/v1/approval-requests/ Generate a simple or advanced viewer link and optionally email it to reviewers.
GET /a/{team_slug}/artwork-approvals/api/v1/approval-requests/{id}/ approval_requests_retrieve
POST /a/{team_slug}/artwork-approvals/api/v1/approval-requests/{id}/reset/ Put the request back to pending (clears every reviewer's decision).
POST /a/{team_slug}/artwork-approvals/api/v1/approval-requests/{id}/send/ Email this link to reviewers (they are added as approvers).
GET /a/{team_slug}/artwork-approvals/api/v1/artworks/ artworks_list
POST /a/{team_slug}/artwork-approvals/api/v1/artworks/ artworks_create
GET /a/{team_slug}/artwork-approvals/api/v1/artworks/{id}/ artworks_retrieve
PUT /a/{team_slug}/artwork-approvals/api/v1/artworks/{id}/ artworks_update
PATCH /a/{team_slug}/artwork-approvals/api/v1/artworks/{id}/ artworks_partial_update
GET /a/{team_slug}/artwork-approvals/api/v1/artworks/{id}/history/ Newest-first timeline: uploads, share links, decisions and resets.
GET /a/{team_slug}/artwork-approvals/api/v1/artworks/{id}/versions/ Every uploaded version of this artwork, newest first.
GET /a/{team_slug}/artwork-approvals/api/v1/versions/ artwork_versions_list
POST /a/{team_slug}/artwork-approvals/api/v1/versions/ Upload a PDF as the next version of an artwork.
GET /a/{team_slug}/artwork-approvals/api/v1/versions/{id}/ artwork_versions_retrieve
GET /a/{team_slug}/artwork-approvals/api/v1/versions/{id}/advanced-preview/ Build status of the separations preview (ready, building, failed, missing or stale).
POST /a/{team_slug}/artwork-approvals/api/v1/versions/{id}/advanced-preview/ Build the separations preview now, or retry a failed build.
GET /a/{team_slug}/artwork-approvals/api/v1/versions/{id}/pdf/ Download the version's PDF (team members only; the file is never public).
POST /a/{team_slug}/artwork-approvals/api/v1/versions/{id}/request-approval/ Create a simple or advanced share link for this version (same as POST approval-requests).
POST /a/{team_slug}/artwork-approvals/api/v1/versions/{id}/share-links/ The version's default simple and advanced links (created when missing).
POST /a/{team_slug}/artwork-approvals/api/v1/versions/from-file/ Send a PDF version from Files for approval: the next version of the artwork that already proofs that file (or of `artwork`, or of a new artwork), using the same bytes, never a copy.

All “artwork-approvals” operations in the API reference

Last updated Sept. 28, 2026