Skip to content
Docs
Sign in

Preflight API

Queue a preflight for an approval version, an imposition artwork or a version in Files, read its findings, find the latest report and apply fixes.

For integrators

The preflight API runs the same checks as the Preflight page. Queue a report for an approval artwork version, an imposition artwork or a version of a file in Files, poll it until it finishes, and read its findings. Every endpoint is under your team, at /a/<team_slug>/preflight/api/reports/.

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).

What the checks look for and what the results mean is in How preflight works.

Run preflight and read the result#

REPORTS=https://app.example.com/a/acme/preflight/api/reports/
AUTH="Authorization: Api-Key $API_KEY"

# 1. Queue a report for approval version 42 with the Packaging preset (202; the answer has its id, here 7)
curl -s -X POST "$REPORTS" -H "$AUTH" -H "Content-Type: application/json" \
  -d '{"version": 42, "profile": "preset:packaging"}'

# 2. Poll it every few seconds until the status is no longer "running"
curl -s "${REPORTS}7/" -H "$AUTH"

# 3. Or ask for the newest report of the version
curl -s "${REPORTS}latest/?version=42" -H "$AUTH"

Queue a report#

POST /a/{team_slug}/preflight/api/reports/

preflight_reports_create · View in API reference

The body names one target and optionally a profile:

Field Meaning
version An approval artwork version id.
imposition_artwork An imposition artwork id: its file in use (the print-ready file once there is one) is checked, with its die.
file_version The id of a version of a file in Files (the id of a version in the Files API). It must be ready; its die, if any, is found from its cut lines.
profile preset:<key> for a built-in preset (digital, offset, wide_format, packaging, flexo_label), profile:<id> for a team profile, or empty for the team default (else a preset suited to the artwork; see profiles and presets).

Give exactly one of version, imposition_artwork and file_version. The answer is 202 Accepted with the report, status running. When the same check of the same target is already waiting to start, you get that report instead of a new one. A target or profile of another team is 404.

New approval versions, and new PDF versions in Files, are preflighted without a call: see on upload and when a PDF arrives in Files. A file in Files shows the result of its current version's latest report as its preflight_status.

Read a report#

GET /a/{team_slug}/preflight/api/reports/{id}/

a_preflight_api_reports_retrieve · View in API reference

Poll until status is no longer running: then it is pass, warn, fail or error. A report that waits more than an hour to start, or runs more than 15 minutes, becomes error on its own.

FieldMeaning
idThe report id.
statusrunning, pass, warn, fail or error.
countsFindings by severity: {error, warning, info}.
findingsThe findings, errors first, with messages in the language of the request.
targetWhat was checked, such as the artwork name and version ("Postcard A v2").
artwork_versionThe approval artwork version id, or null.
imposition_artworkThe imposition artwork id, or null.
file_versionThe Files version id, or null. Also set on an approval version's report when that proof round is the Files version's own bytes.
file_nameThe name of the checked file.
file_sha256The SHA-256 of the checked file (empty until the check starts).
profileThe team profile id, or null when a preset was used or the profile was deleted.
profile_labelThe name of the profile or preset the report ran with.
engine_versionThe version of the checks. A new version can give different results for the same file.
duration_msHow long the report took, in milliseconds (null while running).
created_atWhen the report was queued.
completed_atWhen it finished (null while running).
errorWhy the report could not run, when status is error; else empty.
pagesPer page (up to 200): width, height, rotation, view, matrix and the trim, bleed and media boxes, to place finding boxes on your own page images.
urlThe report page in the app.
{
  "id": 7,
  "status": "warn",
  "counts": {"error": 0, "warning": 1, "info": 0},
  "findings": [
    {
      "id": "f1",
      "check": "image_resolution",
      "severity": "warning",
      "code": "image_low_ppi",
      "message": "Image prints at 250 ppi (2000 × 1500 px); at least 300 ppi is needed.",
      "params": {"pixels": "2000 × 1500", "ppi": 250, "limit": 300, "count": 1},
      "page": 1,
      "bbox": [18.0, 72.0, 594.0, 504.0],
      "bboxes": [[18.0, 72.0, 594.0, 504.0]],
      "count": 1,
      "fixup": null
    }
  ],
  "target": "Postcard A v2",
  "artwork_version": 42,
  "imposition_artwork": null,
  "file_version": null,
  "file_name": "postcard-a.pdf",
  "profile": null,
  "profile_label": "Packaging and folding carton",
  "duration_ms": 2140,
  "error": "",
  "url": "/a/acme/preflight/reports/7/"
}

(Some fields are left out of the example.)

Findings#

Field Meaning
id The finding's id within the report: f1, f2 … in the order shown, errors first.
check The check key, such as image_resolution (see Preflight checks at a glance).
severity error, warning or info.
code What was found (the table below). Stable across languages: match on it, not on message.
message The finding in words, in the language of the request.
params The values in the message, such as ppi and limit, plus count.
page The page number, from 1; null for a problem of the whole file.
bbox The first location, [x0, y0, x1, y1] in points, or null.
bboxes Up to 25 locations.
count How many occurrences the finding stands for.
fixup The key of the fix it offers (set_boxes, remove_interactive, remove_encryption, downsample_images), or null.

Locations are in points on the page as stored in the PDF: before its rotation, with the origin at the top left of the visible page (the CropBox) and y growing downwards. Each entry of pages gives the page's width and height, its rotation, the rotated size as displayed (view) and the matrix [a, b, c, d, e, f] that maps a location onto it, with the trim, bleed and media boxes in the same coordinates.

Finding codes#

Values in braces come from params.

CodeMessage
image_low_ppiImage prints at {ppi} ppi ({pixels} px); at least {limit} ppi is needed.
image_lineart_low_ppi1-bit image prints at {ppi} ppi; line art needs at least {limit} ppi.
image_high_ppiImage prints at {ppi} ppi, more than the {limit} ppi the press can use.
colour_image{space} image.
colour_vector{space} colour used in vector artwork.
colour_text{space} colour used for text.
colour_shading{space} colour used in a gradient.
colour_blendTransparency blends in {space}: the flattened result is converted from it.
font_not_embeddedFont {font} ({type}) is not embedded.
text_smallText smaller than {limit} pt (smallest {size} pt).
text_small_reverseReverse text smaller than {limit} pt (smallest {size} pt).
text_multi_inkText up to {limit} pt printed with {inks} inks (smallest {size} pt).
text_rich_blackRich black text up to {limit} pt: black plus other inks, {inks} in all (smallest {size} pt).
line_zeroZero-width lines: they print as the thinnest line the device can make.
line_thinLines thinner than {limit} pt (thinnest {width} pt).
line_thin_reverseReverse lines thinner than {limit} pt (thinnest {width} pt).
overprint_usedObjects set to overprint.
white_overprintWhite objects set to overprint: they will disappear.
technical_knockoutTechnical lines ({inks}) knock out the artwork beneath: set them to overprint.
black_text_knockoutBlack text up to {limit} pt knocks out: overprinting avoids halos from misregistration.
black_line_knockoutBlack lines up to {limit} pt knock out: overprinting avoids halos from misregistration.
registration_in_artworkRegistration colour (every plate at 100%) used inside the trim.
tint_too_lowTints lighter than {limit}% (lightest {tint}%) can drop out on press.
transparency_alphaTransparent objects (lowest opacity {opacity}%).
transparency_blendObjects using the {mode} blend mode.
transparency_maskObjects with a soft mask.
transparency_groupTransparency group.
transparency_page_groupThe page is a transparency group.
tac_overInk coverage reaches {max}% (limit {limit}%) over {area}% of the page.
spot_missingExpected spot colour {name} is not in the file.
spot_unexpectedUnexpected spot colour {name}.
spot_near_duplicateSpot colours {a} and {b} look like the same ink.
spot_inconsistentSpot colour {name} is defined {definitions} different ways.
spot_too_many{count} printing spot colours (limit {limit}): {names}.
die_missingNo die or cut line ink was found.
page_size_mismatchTrim size is {width} × {height} pt ({width_mm} × {height_mm} mm); expected {expected_width} × {expected_height} pt ({expected_width_mm} × {expected_height_mm} mm).
page_size_mixedThe pages have {sizes} different trim sizes.
page_count_mismatchThe file has {found} pages; {expected} were expected.
page_count_multipleThe file has {found} pages, not a multiple of {multiple}.
no_trimboxNo TrimBox: the whole page is taken as the trim.
box_outside_mediaThe TrimBox or BleedBox extends beyond the page (MediaBox).
bleedbox_inside_trimThe BleedBox is smaller than the TrimBox.
bleedbox_smallThe artwork has bleed but the BleedBox gives less than {required} pt ({required_mm} mm).
bleed_shortArtwork stops short of the {required} pt ({required_mm} mm) bleed along {percent}% of the edges it touches.
bleed_missingArtwork touches the trim but the page has no room for {required} pt ({required_mm} mm) bleed.
die_bleedbox_smallThe artwork bleeds past the die but the BleedBox gives less than {required} pt ({required_mm} mm).
die_bleed_shortArtwork stops before {required} pt ({required_mm} mm) of bleed beyond the die along {percent}% of the outline it touches.
die_bleed_missingArtwork touches the die but the page has no room for {required} pt ({required_mm} mm) bleed.
text_in_marginText within {margin} pt ({margin_mm} mm) of the edge (closest {closest} pt).
javascriptJavaScript found ({places}).
annotationsComments or markup: {types}.
form_fieldsForm fields.
encryptedThe file is encrypted.
pdf_version_lowPDF {version} is older than {minimum}.
no_output_intentNo output intent: the file does not state its print condition (PDF/X).
check_failedThis check could not run ({error}).

The latest report#

GET /a/{team_slug}/preflight/api/reports/latest/

preflight_reports_latest · View in API reference

Pass version, imposition_artwork or file_version. The answer is the newest report of that target, running or not, or 404 ("No preflight report yet.").

Apply a fix#

POST /a/{team_slug}/preflight/api/reports/{id}/fixups/{key}/

preflight_reports_fixup · View in API reference

POST /a/acme/preflight/api/reports/7/fixups/set_boxes/ applies a fix the report offers (a fixup of one of its findings) to the file of an approval version or a version in Files. The fixed file becomes the artwork's next version, or the file's next version in Files (source preflight_fix), and is queued for preflight with the same profile. The answer is 201 with:

Field Meaning
version The new approval version's id, or null for a file in Files.
file_version The new version's id in Files, or null for an approval version.
detail What the fix did, such as "Trim 210 × 297 mm.", or empty.
report The new version's queued report, or null while Files is still processing the new version (it is checked automatically once it is ready).

Fixes of imposition artwork are downloads, offered on the report page only: the API answers 400. A fix that can't run answers 400 with the reason, such as a fix the report doesn't offer, a newer version of the artwork or file, a file in the Files trash, or a file that changed since the report. See Preflight fixes.

Errors and limits#

Status When
400 Not exactly one of version, imposition_artwork and file_version; a profile not written as preset:<key> or profile:<id>; a fix that can't run.
404 No such report, target or profile in the team (or a version in Files that isn't ready yet), or no report yet for latest.
429 More than 30 preflights, or 10 fixes, a minute by the same person (the app and the API count together).

A report that could not check its file has status error and says why in error; see when a report can't run.

Last updated Sept. 28, 2026