curl --request GET \
--url https://app.vumasign.com/api/v1/documents/{documentId}/content \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.vumasign.com/api/v1/documents/{documentId}/content"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.vumasign.com/api/v1/documents/{documentId}/content', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://app.vumasign.com/api/v1/documents/{documentId}/content"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}"<string>"{
"error": {
"code": "unauthenticated",
"message": "<string>"
}
}{
"error": {
"code": "unauthenticated",
"message": "<string>"
}
}{
"error": {
"code": "unauthenticated",
"message": "<string>"
}
}{
"error": {
"code": "unauthenticated",
"message": "<string>"
}
}{
"error": {
"code": "unauthenticated",
"message": "<string>"
}
}{
"error": {
"code": "unauthenticated",
"message": "<string>"
}
}{
"error": {
"code": "unauthenticated",
"message": "<string>"
}
}A template document, every page, as one PDF.
THE WHOLE DOCUMENT. The pages GET /api/v1/templates/{templateId} describes, all of them, in order, as one PDF: what a person or a model reads to match your data to the boxes on a form. GET /api/v1/documents/{documentId}/pages/{pageNumber} serves one page of the same document.
⚠️ IT IS REBUILT, NOT THE FILE AS UPLOADED. Every page is copied into a new PDF that keeps what the pages draw and nothing they do: no document-level scripts, open action, embedded files or the uploader’s metadata; no file-attachment or media annotations; and no page or annotation actions, except that a link keeps a go-to to a page of this document or an address beginning http://, https:// or mailto:. Field boxes draw from the appearance saved with them, and the form is not fillable. For a template uploaded as Word, this is the PDF every Field.rect is measured against, not the Word file.
⚠️ ONLY A DOCUMENT A LIVE TEMPLATE HOLDS. The document must belong to a template of your organisation that is not archived.
⚠️ FOUR SITUATIONS ANSWER WITH THE SAME 404: no such document anywhere; a document belonging to another organisation; a document no live template of yours holds; and an id that is not a uuid. “This exists but is not yours” is itself the secret.
Never cached, by anything: Cache-Control: private, no-store.
curl --request GET \
--url https://app.vumasign.com/api/v1/documents/{documentId}/content \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.vumasign.com/api/v1/documents/{documentId}/content"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.vumasign.com/api/v1/documents/{documentId}/content', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://app.vumasign.com/api/v1/documents/{documentId}/content"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}"<string>"{
"error": {
"code": "unauthenticated",
"message": "<string>"
}
}{
"error": {
"code": "unauthenticated",
"message": "<string>"
}
}{
"error": {
"code": "unauthenticated",
"message": "<string>"
}
}{
"error": {
"code": "unauthenticated",
"message": "<string>"
}
}{
"error": {
"code": "unauthenticated",
"message": "<string>"
}
}{
"error": {
"code": "unauthenticated",
"message": "<string>"
}
}{
"error": {
"code": "unauthenticated",
"message": "<string>"
}
}Authorizations
Authorization: Bearer vsk_live_…. Chosen over a bespoke X-API-KEY header because every client, proxy and log-redaction rule already knows this one. What a key may DO is its scopes — see x-scopes at the root of this document and x-required-scope on each operation. The scope list is not written here because OpenAPI reserves a requirement’s scope array for oauth2 and openIdConnect and requires it to be empty for an http scheme.
Path Parameters
A documents[].id from GET /api/v1/templates/{templateId}. ⚠️ It is the DOCUMENT’s id, not the template’s — a template’s pack may hold several, and Field.document_id says which one a box is on.
A document id.
"01960000-0000-4000-8000-00000000d0c5"
Response
The document, every page, rebuilt. Content-Disposition: attachment; filename="document.pdf" — the filename says nothing about the template or the customer.
The PDF bytes. NOT JSON. Its refusals still are: every non-2xx is the same Error envelope in application/json.