Skip to content
Taylorz CRM Developers
Esc
↑↓navigate↵open⌘Jpreview
On this page

Document generation

A template plus a record becomes a document: generation is queued, status is polled, and a download is a short-lived signed URL that cannot be recalled.

Every endpoint here needs the documents module. Generation is asynchronous — this is the one module in the API where a write does not finish the work.

Storage has to be configured first

Before anything else: a workspace whose document storage is not set up refuses generation with document_storage_unconfigured. That is an administrator’s setting, not something a client can arrange, so handle it as a prerequisite rather than a transient failure.

A template binds to an object

POST /document-templates takes a name, the objectId its documents are rendered from, a layout, and a version.

A template may only name fields that object has. A layout referring to a field that does not exist answers template_field_unavailable, at creation rather than at render time, so a broken template cannot be saved and discovered later.

Generating is a queue, not a response

POST /documents takes templateId, recordId and the record’s revision. It queues the work and answers immediately.

The revision pins which version of the record is rendered, the same way an approval pins what its approvers read. A document therefore shows the record as it was when generation was asked for, not as it is when the file is opened.

template_revision_mismatch means the template changed between reading it and asking for the document. Re-read the template and submit again.

Polling for the result

GET /documents/{id} answers a status of pending, ready or failed, with an inputHash and — once there is output — an outputHash.

Poll until ready or failed. There is no callback and no streaming; pending means keep waiting. The two hashes are how a client can tell a re-render from the same inputs apart from a new one.

Retrying and downloading

POST /documents/{id}/retry is for failed documents only. A pending or ready one is refused with document_not_failed, so a retry cannot reset work in progress or discard a finished file.

POST /documents/{id}/download answers a short-lived signed URL. Two things follow from that:

  • A document that is not ready has nothing to sign, and answers document_not_ready.
  • The link cannot be recalled. Once issued it works until it expires, whoever holds it. Treat it as a bearer credential for that one file: do not log it, do not put it in a redirect a third party can read, and issue it at the moment the user asks rather than ahead of time.

It is a POST rather than a GET because issuing a credential is an action, not a read.

One scope covers four endpoints

documents.read lists templates and documents.manage creates them, but generating, reading status, retrying and downloading all need documents.generate. There is no narrower scope for fetching a finished file, so a token that may download may also generate.

Was this page helpful?