Error responses
The document lists success codes per operation. Every operation can also answer with the one error envelope, { "error": { type, code, message, field?, expected?, received?, docs_url, request_id } }:
| Status | When |
400 | invalid_request: the body could not be parsed |
401 | unauthorized: no valid key |
402 | limit_exceeded: a plan limit or feature, the code names which |
404 | not_found: no such object in this workspace and mode; version_not_found when the pinned template version does not exist |
409 | conflict: Idempotency-Key reused with a different request, or still in flight |
410 | gone: version_retired, the pinned template version is retired; the message names the current one |
413 | payload_too_large: the payload is over 8 MiB |
422 | validation_error: the body, a header or a query value is not right; `field` says where |
429 | rate_limited: share_limit, sharing by email past the daily cap; Retry-After says when to try again |
Operations
GET /api/v1/whoami
Whoami · in the guide
Return the workspace, mode and key behind the credential; for an OAuth token also its client, scopes, expiry.
Identifies the key you sent: { workspace_id, workspace, mode, key }.
Responses
| Status | Meaning | Body |
200 | OK | WhoamiOut |
4XX | Refused: the request cannot be served as sent | ErrorOut |
5XX | Failed on our side or a dependency's; safe to retry later | ErrorOut |
GET /api/v1/reports
List Reports · in the guide
`label.<key>=<value>` (repeatable for different keys) keeps reports carrying those labels exactly.
Newest first, the key's mode only. `limit` is clamped to 1 to 200. `status` must be one of queued, rendering, ready, failed, deleted; without it deleted reports are left out. `template` takes a key, an id, or key@N for one version's reports. `replaced=false` leaves out reports a newer version replaced. `label.<key>=<value>` (read by the view, so the document does not list it) keeps reports carrying that label exactly; several keys are ANDed. `next_cursor` is null on the last page.
Parameters
| Name | In | Type | Notes |
template | query | string or null | optional |
status | query | string or null | optional |
limit | query | integer | optional, default 50 |
cursor | query | string or null | optional |
replaced | query | boolean or null | optional |
Responses
| Status | Meaning | Body |
200 | OK | ReportList |
4XX | Refused: the request cannot be served as sent | ErrorOut |
5XX | Failed on our side or a dependency's; safe to retry later | ErrorOut |
POST /api/v1/reports
Create Report · in the guide
Create a report from a template version and a payload.
Answers 200 when the report rendered within the wait, 202 while it still renders, 500 when the render failed.
Send an `Idempotency-Key` to make a retry safe.
Refuses: a connected app turning an old link off (403 `forbidden`), an `Idempotency-Key` over 128 characters
(422), one still in flight or reused with another body (409), a payload the version's contract refuses (422),
what the plan does not include (402).
Side effects: stores the sealed payload, defers `pressfox.render_report`.
200 when the render finished within 2.5 seconds, 202 while it is queued or rendering, 500 when it failed within the wait and `error` names the cause. Plan limits answer 402 with type limit_exceeded; a payload over 8 MiB answers 413. `template` may end in @N (or send `template_version`) to pin a version: 404 version_not_found for an unknown one, 410 version_retired for a retired one. The body carries `template_version`. `labels` adds labels to the template's own; `corrects` with `correction_reason` makes a correction of an issued report (409 already_replaced, correction_in_progress or report_not_ready).
Parameters
| Name | In | Type | Notes |
Idempotency-Key | header | string | optional, up to 128 characters, unique within the workspace; the same key replays the original response for 24 hours |
Request body · ReportCreate, required
| Field | Type | Notes |
template | string or null | optional |
template_id | string or null | optional |
template_version | any JSON | optional |
title | string or null | optional |
labels | any JSON | optional |
payload | any JSON | optional |
corrects | any JSON | optional |
replaces | any JSON | optional |
correction_reason | any JSON | optional |
old_link | any JSON | optional |
reshare | any JSON | optional |
correction_notice | any JSON | optional |
options | object or null | optional |
brand | string or null | optional |
brand_id | string or null | optional |
access | AccessIn or null | optional |
language | string or null | optional |
translate_from | string or null | optional |
formats | any JSON | optional |
fill | any JSON | optional |
retain_days | any JSON | optional |
zero_retention | any JSON | optional |
delivery_window_minutes | any JSON | optional |
pdf_password | any JSON | optional |
Responses
GET /api/v1/reports/{report_id}
Get Report · in the guide
Return a report: status, links and metadata. A test key reads only test reports, a live key only live ones.
Refuses: no such report in this workspace and mode (404).
A test key reads test reports only, a live key live ones; the other mode's ids answer 404.
Parameters
| Name | In | Type | Notes |
report_id | path | string | required |
Responses
| Status | Meaning | Body |
200 | OK | ReportOut |
4XX | Refused: the request cannot be served as sent | ErrorOut |
5XX | Failed on our side or a dependency's; safe to retry later | ErrorOut |
DELETE /api/v1/reports/{report_id}
Delete Report · in the guide
Delete a report: it is marked deleted now and its stored files are purged in the background.
Refuses: no such report in this workspace and mode (404).
Side effects: audit `report.deleted`, defers `pressfox.purge_report` and `pressfox.cache_purge`.
Marks the report deleted and purges its payload, HTML and PDF from storage. 204 also when it was already deleted.
Parameters
| Name | In | Type | Notes |
report_id | path | string | required |
Responses
| Status | Meaning | Body |
204 | No Content | none |
4XX | Refused: the request cannot be served as sent | ErrorOut |
5XX | Failed on our side or a dependency's; safe to retry later | ErrorOut |
POST /api/v1/reports/{report_id}/completion
Complete Report
A partial form completed (docs/capabilities/forms.md §8): the PDF the report gave, filled in a reader, as a
multipart `file` or an `application/pdf` body. Answers like `POST /reports` with the new report, which replaces
this one once ready (webhook `report.completed`). 422 `form_not_ours` when the PDF is not this report's or its
fields moved, 422 `locked_field_changed` when a field filled before was changed, 409 when nothing is left to
fill, 410 when the partial form's data expired.
Parameters
| Name | In | Type | Notes |
report_id | path | string | required |
Responses
| Status | Meaning | Body |
200 | OK | ReportOut |
202 | Accepted | ReportOut |
4XX | Refused: the request cannot be served as sent | ErrorOut |
5XX | Failed on our side or a dependency's; safe to retry later | ErrorOut |
GET /api/v1/reports/{report_id}/markdown
Get Markdown
The report's Markdown version as text (`text/markdown; charset=utf-8`): 404 `markdown_not_requested` when the
report did not ask for it, 409 `report_not_ready` while it renders or once it failed.
Parameters
| Name | In | Type | Notes |
report_id | path | string | required |
Responses
| Status | Meaning | Body |
200 | OK | none |
4XX | Refused: the request cannot be served as sent | ErrorOut |
5XX | Failed on our side or a dependency's; safe to retry later | ErrorOut |
GET /api/v1/reports/{report_id}/pdf
Get Pdf
The report's PDF (`application/pdf`), for any ready report; how a zero-retention report is collected during its
delivery window (docs/capabilities/zero-retention.md §5). A zero-retention report past its window (or deleted) is
410 `delivery_window_ended`, except while a webhook delivery about it is still retried (up to 24 hours); any
other deleted report is 404. 409 `report_not_ready` while it renders or once it failed.
Parameters
| Name | In | Type | Notes |
report_id | path | string | required |
Responses
| Status | Meaning | Body |
200 | OK | none |
4XX | Refused: the request cannot be served as sent | ErrorOut |
5XX | Failed on our side or a dependency's; safe to retry later | ErrorOut |
POST /api/v1/reports/{report_id}/links
Mint Links
Fresh signed links (up to 30 days) for a report whose access kind is `signed`; never past a zero-retention
report's window (410 `delivery_window_ended` once it is over).
Parameters
| Name | In | Type | Notes |
report_id | path | string | required |
| Field | Type | Notes |
expires_in | integer | optional, default 604800 |
Responses
| Status | Meaning | Body |
200 | OK | SignedLinksOut |
4XX | Refused: the request cannot be served as sent | ErrorOut |
5XX | Failed on our side or a dependency's; safe to retry later | ErrorOut |
POST /api/v1/reports/{report_id}/shares
Create Share · in the guide
Email the report to up to 50 people, each with their own link to the hosted page and the PDF, for 24h, 48h,
7d, 30d or `none` (still capped by the report's own expiry and retention). The sender is the workspace.
201 with the share: one email per address, each with its own link to the hosted page and the PDF. 422 invalid_email names the bad addresses; 422 report_not_ready before the render is done; 429 share_limit (with Retry-After) past the daily cap. `expires_at` null means the links do not expire.
Parameters
| Name | In | Type | Notes |
report_id | path | string | required |
Request body · ShareCreate, required
| Field | Type | Notes |
emails | array of string | required |
duration | string | optional, default "7d" |
message | string or null | optional |
ask_ack | boolean | optional, default false |
remind_after_days | integer or null | optional |
remind_until | string or null | optional |
Responses
| Status | Meaning | Body |
201 | Created | ShareOut |
4XX | Refused: the request cannot be served as sent | ErrorOut |
5XX | Failed on our side or a dependency's; safe to retry later | ErrorOut |
PATCH /api/v1/reports/{report_id}/labels
Update Labels · in the guide
`{"labels": {"client": "Northwind Shipping", "old": null}}`: set or remove labels; the others stay. Labels are
metadata: the report itself does not change.
The body is read by the view, so the document shows none. Send { "labels": { "client": "Northwind Shipping", "old_key": null } }: a string sets a label, null removes it, the others stay. Answers the report object. At most 10 labels, keys of lower-case letters, digits and underscores, values of at most 200 characters; 422 naming the field otherwise. The report itself never changes.
Parameters
| Name | In | Type | Notes |
report_id | path | string | required |
Request body, required
| Field | Type | Notes |
labels | object | required |
Responses
| Status | Meaning | Body |
200 | OK | ReportOut |
4XX | Refused: the request cannot be served as sent | ErrorOut |
5XX | Failed on our side or a dependency's; safe to retry later | ErrorOut |
POST /api/v1/assets
Upload Asset · in the guide
Upload an image to the workspace's library, as JSON with base64 `data` or as multipart.
The same bytes again answer 200 with the existing asset; a new asset answers 201.
Refuses: a body that is not JSON or misses a field (422), an unsupported type or bytes that do not match it
(`unsupported_asset_type`), an empty or oversized file (`empty_array`, `asset_too_large`), the plan's asset
storage (402 `asset_bytes_limit`).
Side effects: audit `asset.uploaded` for a new asset.
The body is read by the view, so the document shows none. Send JSON { content_type, data (base64), name? } or multipart/form-data with a `file` part and an optional `name` field. 201 for new bytes, 200 when the same bytes were already stored. The response is { asset_id, bytes, content_type, name, width, height, created_at }, with asset_id in the form asset:<id>.
Responses
| Status | Meaning | Body |
200 | OK | AssetOut |
201 | Created | AssetOut |
4XX | Refused: the request cannot be served as sent | ErrorOut |
5XX | Failed on our side or a dependency's; safe to retry later | ErrorOut |
GET /api/v1/assets/{asset_id}
Get Asset · in the guide
Return an asset's metadata; the id may carry the reference prefix.
Refuses: no such asset (404 `not_found`).
The same object the upload returns. The id is accepted with or without the asset: prefix.
Parameters
| Name | In | Type | Notes |
asset_id | path | string | required |
Responses
| Status | Meaning | Body |
200 | OK | AssetOut |
4XX | Refused: the request cannot be served as sent | ErrorOut |
5XX | Failed on our side or a dependency's; safe to retry later | ErrorOut |
GET /api/v1/templates
List Templates · in the guide
Most recently updated first, `limit` at most 200 (default 50); `next_cursor` is null on the last page.
Only identity fields are read: the frozen document, theme, sample and contract stay in the database. `kind`
(`report` | `form`) keeps published templates of that kind only; each item says its `kind`.
Archived templates are left out. `current_version` is null for a template that has never been published. `versions` lists the published versions newest first (at most 50) as { number, current, retired, created_at }.
Parameters
| Name | In | Type | Notes |
limit | query | integer | optional, default 50 |
cursor | query | string or null | optional |
kind | query | string or null | optional |
Responses
| Status | Meaning | Body |
200 | OK | TemplateListPage |
4XX | Refused: the request cannot be served as sent | ErrorOut |
5XX | Failed on our side or a dependency's; safe to retry later | ErrorOut |
GET /api/v1/templates/{template_ref}/contract
Template Contract · in the guide
The payload contract of a version: `template_ref` is the key or id, optionally pinned (`inspection@2`), or
`?version=2`; neither means the current version. The number served is in `X-Pressfox-Template-Version`.
The current published version's contract: { schema, reads, unread }, or version N's with key@N or ?version=N; the X-Pressfox-Template-Version header names the version. 404 for an unknown or archived template, 422 template_not_published when nothing is published, 404 version_not_found for an unknown version, 410 version_retired for a retired one.
Parameters
| Name | In | Type | Notes |
template_ref | path | string | required |
version | query | string or null | optional |
Responses
| Status | Meaning | Body |
200 | The version's payload contract, as frozen at publish | object |
4XX | Refused: the request cannot be served as sent | ErrorOut |
5XX | Failed on our side or a dependency's; safe to retry later | ErrorOut |
GET /api/v1/brands
List Brands
Every brand of the workspace, oldest first: its key, name and whether it is the default (the default is a
designer setting; a report without `"brand"` keeps the template's own look).
Responses
| Status | Meaning | Body |
200 | OK | BrandList |
4XX | Refused: the request cannot be served as sent | ErrorOut |
5XX | Failed on our side or a dependency's; safe to retry later | ErrorOut |
GET /api/v1/verification/reports/{report_id}
Report State V1
Parameters
| Name | In | Type | Notes |
report_id | path | string | required |
Responses
| Status | Meaning | Body |
200 | OK | RecordOut |
4XX | Refused: the request cannot be served as sent | ErrorOut |
5XX | Failed on our side or a dependency's; safe to retry later | ErrorOut |
Schemas
AccessIn
| Field | Type | Notes |
kind | string | optional, default "link" |
password | string or null | optional |
expires_at | string (date-time) or null | optional |
AssetOut
| Field | Type | Notes |
asset_id | string | required |
bytes | integer | required |
content_type | string | required |
name | string | required |
width | integer or null | required |
height | integer or null | required |
created_at | string | required |
BrandItem
| Field | Type | Notes |
id | string | required |
key | string | required |
name | string | required |
is_default | boolean | required |
ErrorBody
| Field | Type | Notes |
type | string | required |
code | string | required |
message | string | required |
field | string or null | optional, default null |
expected | string or null | optional, default null |
received | string or null | optional, default null |
upgrade_plan | string or null | optional, default null |
resets_at | string or null | optional, default null |
docs_url | string | required |
request_id | string or null | optional, default null |
RecordOut
| Field | Type | Notes |
registered | boolean | required |
why | string or null | optional |
status | string or null | optional |
sha256 | string or null | optional |
issuer | string or null | optional |
issued_at | string or null | optional |
replaced_at | string or null | optional |
replaced_by | string or null | optional |
revoked_at | string or null | optional |
reason | string or null | optional |
expires_at | string or null | optional |
verify_line | boolean or null | optional |
ReportCreate
| Field | Type | Notes |
template | string or null | optional |
template_id | string or null | optional |
template_version | any JSON | optional |
title | string or null | optional |
labels | any JSON | optional |
payload | any JSON | optional |
corrects | any JSON | optional |
replaces | any JSON | optional |
correction_reason | any JSON | optional |
old_link | any JSON | optional |
reshare | any JSON | optional |
correction_notice | any JSON | optional |
options | object or null | optional |
brand | string or null | optional |
brand_id | string or null | optional |
access | AccessIn or null | optional |
language | string or null | optional |
translate_from | string or null | optional |
formats | any JSON | optional |
fill | any JSON | optional |
retain_days | any JSON | optional |
zero_retention | any JSON | optional |
delivery_window_minutes | any JSON | optional |
pdf_password | any JSON | optional |
ReportOut
| Field | Type | Notes |
filled_parties | array of string or null | optional |
pending_parties | array of string or null | optional |
report_id | string | required |
title | string | required |
labels | object | optional, default {} |
template_id | string | required |
template_key | string | required |
template_version | integer or null | optional |
brand_key | string or null | optional |
status | string | required |
mode | string | required |
language | string | optional, default "en" |
url | string | required |
pdf_url | string | required |
markdown_url | string or null | optional |
pages | integer | required |
units | integer | required |
created_at | string or null | required |
ready_at | string or null | required |
retain_until | string or null | optional |
zero_retention | boolean | optional, default false |
pdf_protected | boolean | optional, default false |
pdf_standard | string or null | optional |
delivery_expires_at | string or null | optional |
error | string or null | required |
message | string | required |
replaces | string or null | optional |
replaced_by | string or null | optional |
replaced_at | string or null | optional |
replace_kind | string or null | optional |
correction_reason | string or null | optional |
ShareCreate
| Field | Type | Notes |
emails | array of string | required |
duration | string | optional, default "7d" |
message | string or null | optional |
ask_ack | boolean | optional, default false |
remind_after_days | integer or null | optional |
remind_until | string or null | optional |
ShareOut
| Field | Type | Notes |
id | string | required |
created_at | string (date-time) | required |
created_by | string | required |
duration | string | required |
expires_at | string (date-time) or null | required |
revoked_at | string (date-time) or null | required |
message | string or null | required |
ask_ack | boolean | optional, default false |
remind_after_days | integer | optional, default 0 |
remind_until | string | optional, default "opened" |
state | string | required |
recipients | array of ShareRecipientOut | required |
ShareRecipientOut
| Field | Type | Notes |
id | string | required |
email | string | required |
status | string | required |
error | string or null | required |
sent_at | string (date-time) or null | required |
first_opened_at | string (date-time) or null | required |
last_opened_at | string (date-time) or null | required |
open_count | integer | required |
resend_count | integer | required |
revoked_at | string (date-time) or null | required |
acknowledged_at | string (date-time) or null | optional |
reminders_sent | integer | optional, default 0 |
last_reminded_at | string (date-time) or null | optional |
active | boolean | required |
SignedLinksIn
| Field | Type | Notes |
expires_in | integer | optional, default 604800 |
SignedLinksOut
| Field | Type | Notes |
url | string | required |
pdf_url | string | required |
markdown_url | string or null | optional |
expires_at | string | required |
TemplateItem
| Field | Type | Notes |
id | string | required |
key | string | required |
name | string | required |
kind | string or null | optional |
current_version | VersionRef or null | required |
source_language | string or null | optional |
languages | array of string | optional, default [] |
versions | array of VersionBrief | optional, default [] |
VersionBrief
| Field | Type | Notes |
number | integer | required |
current | boolean | required |
retired | boolean | required |
created_at | string (date-time) | required |
VersionRef
| Field | Type | Notes |
id | string | required |
number | integer | required |
kit_version | string | required |
WhoamiOut
| Field | Type | Notes |
workspace_id | string | required |
workspace | string | required |
mode | string | required |
key | string | required |
auth | string or null | optional |
client_id | string or null | optional |
client_name | string or null | optional |
connection | string or null | optional |
scopes | array of string or null | optional |
resource | string or null | optional |
expires_at | integer or null | optional |