Skip to main content
GET /api/v1/templates/{templateId} says where every box on a template is. Two endpoints serve what those boxes are drawn on: the pages themselves, as PDF. With both, a person or a model can do what a person filling in the form does, and read the page to decide which of your values belongs in which box. That matters on real forms, where a field is named checklist.17 and “ID or passport number” is printed beside several boxes on one page.

The join

A template holds one or more documents, and each field says which document and which page it is on. (document_id, page) is the key throughout. A page number alone is not enough, because a template whose pack holds several documents has a page 1 in each.

One page, or the whole document

Both need a key holding documents:read (or a key with full access). A test key (vsk_test_) reads them exactly as a live key does: templates belong to the organisation, not to an environment. Both serve only a document that a template of your organisation holds, and only while that template is not archived. For a template uploaded as a Word file, both serve the PDF Vumasign made from it, which is what every rect is measured against. The Word file itself is never served here.

What you get is a viewing copy

The PDF is rebuilt, not the file as it was uploaded: Vumasign makes the copy once, when the document is uploaded (or, for a document uploaded before copies were made, the first time it is asked for), and serves that copy every time after. It keeps each page’s content and the appearance saved with each annotation it keeps, so field boxes draw as they were saved, and it does nothing. A box saved without an appearance of its own draws empty, and content the original keeps on a hidden layer is shown, because layers are not carried. Fonts and images come across as they are drawn, so open the copy in an up-to-date viewer, as you would any PDF.
  • Kept, as drawn: the page’s content, and annotations of these kinds only: Text, Link, FreeText, Line, Square, Circle, Polygon, PolyLine, Highlight, Underline, Squiggly, StrikeOut, Stamp, Caret, Ink, Watermark, Widget. Each keeps its position, its appearance and its plain properties, and nothing it could do.
  • Links: a link keeps a go-to to a page that is in the same copy, or an address beginning http://, https:// or mailto:. Any other link is still drawn and does nothing.
  • Removed: everything else. That includes document-level scripts, the open action, embedded files, the uploader’s document metadata, the form itself, every page and annotation action, and annotations of any other kind, file attachments, sounds, movies, screens, rich media and 3D among them.
The form is not fillable. To put values into the boxes, send them as values when you create an envelope. ⚠️ Upload blank forms. A form that was filled in before it was uploaded still shows what was typed into it on the pages these endpoints serve.

Drawing the fields on a page

Your API key stays on your server. The server asks Vumasign for the template and the page and hands them to your own front end; the browser renders the page with pdf.js and outlines each field on it, labelled with its data_key. On the server (Node, with no dependencies):
In the browser, from your own origin:
Because rect is a fraction of the page as displayed, it is multiplied by the size of the rendered page, whatever scale you render at. pages[].rotation is information, not an instruction: width, height and every rect already describe the page as it is displayed, so do not rotate them again.

Refusals

Every reason you cannot have a document is the same refusal, not_found: an id that names nothing, another organisation’s document, a document no live template of yours holds, and an id that is not a uuid. “This exists but is not yours” would itself be a disclosure. The page endpoint also answers not_found for a page number the document does not have, and that one message says how many pages there are, because by then the document has been found under your key. internal_error means the stored file could not be produced or was not the document recorded; it is ours, not yours. Every uploaded PDF is read in an isolated service, one document at a time, with a fixed memory limit and a fixed time limit. A document that needs more than either is refused at upload with document_too_complex, and nothing is stored. A document stored before uploads were checked this way can meet the same refusal here, the first time its copy is made; its template, with every field and where it is, is still readable. While that service is starting up, at capacity, or slow to answer, these endpoints answer service_unavailable with Retry-After; retry after that many seconds.