curl --request POST \
--url https://app.vumasign.com/api/v1/templates/{templateId}/validate-values \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{}'import requests
url = "https://app.vumasign.com/api/v1/templates/{templateId}/validate-values"
payload = {}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({})
};
fetch('https://app.vumasign.com/api/v1/templates/{templateId}/validate-values', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.vumasign.com/api/v1/templates/{templateId}/validate-values"
payload := strings.NewReader("{}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"ok": false,
"results": [
{
"index": 0,
"status": "ok",
"fields": 1
},
{
"index": 1,
"status": "value_address_unknown",
"message": "`values[1]`: no field of this template is addressed (null, \"full_name\"). A value that matches nothing would leave the box blank and report success, so it is refused instead. Nothing was created."
}
]
}{
"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>"
}
}What creating an envelope would say about your values, without creating one.
CHECK A BINDING BEFORE YOU SEND. Takes the values and subjects you would send to POST /api/v1/envelopes for this template and answers, for EVERY entry, what create would do with it — where create stops at the first refusal. It writes nothing and needs no Idempotency-Key; it is a POST only because the body can be large.
⚠️ 200 WHENEVER THE REQUEST ITSELF IS WELL FORMED, whatever the verdicts. ok in the body is the answer. Each refused entry carries the status and the sentence create would refuse it with, and when several are refused, create answers the first duplicate_address if there is one, and otherwise the lowest index.
⚠️ IT ASKS ONLY WHAT CREATE ASKS OF values. It does not check validation_type or masks (create does not), the recipients (they are a property of a send, not of a binding), or whether the template can make an envelope at all. A subjects map the template refuses is answered invalid_request, with create’s sentence.
A test key and a live key get the same answer: a template has no environment.
curl --request POST \
--url https://app.vumasign.com/api/v1/templates/{templateId}/validate-values \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{}'import requests
url = "https://app.vumasign.com/api/v1/templates/{templateId}/validate-values"
payload = {}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({})
};
fetch('https://app.vumasign.com/api/v1/templates/{templateId}/validate-values', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.vumasign.com/api/v1/templates/{templateId}/validate-values"
payload := strings.NewReader("{}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"ok": false,
"results": [
{
"index": 0,
"status": "ok",
"fields": 1
},
{
"index": 1,
"status": "value_address_unknown",
"message": "`values[1]`: no field of this template is addressed (null, \"full_name\"). A value that matches nothing would leave the box blank and report success, so it is refused instead. Nothing was created."
}
]
}{
"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
The template’s id, as returned by the list endpoint.
A template id.
"01960000-0000-4000-8000-0000000007e1"
Body
The values and subjects you would send to create, and nothing else.
The values to judge.
Optional. Values to prefill, as triples. Omitted means none. ⚠️ A signature, a date_signed, a signer_name and a signer_email may not be prefilled — they are acts, or they are written by this system.
Show child attributes
Show child attributes
Optional. WHO THIS ENVELOPE IS ABOUT, as a map from a subject key the template declares to true (on this envelope) or false (not). A field addressed to a subject that is not on the envelope is hidden from the signer and not required.
A subject you do not name takes the template’s own rule: a required subject is on every envelope, and a conditional one is absent unless somebody says otherwise. Omitting subjects altogether opens the same sections as naming nobody — but see the next paragraph, because the two are not the same request. A key the template does not declare is refused, and so is false for a required subject — both invalid_request, and nothing is created.
⚠️ IT SETS WHAT THE DOCUMENT OPENS WITH, NOT WHAT IT MUST STAY. The signer can switch a conditional subject on or off on the signing page, in either direction, and every such change is recorded in the envelope’s audit history.
⚠️ NAME AS true EVERY conditional SUBJECT YOU PREFILL. A value in values for a conditional subject you did not name as present is handled in one of two ways, depending on whether subjects is in the request at all:
subjectssent (even{}): the subject is absent — byfalse, or by the template’s rule when unnamed — so the value contradicts the request and is refused withinvalid_request. Nothing is created.subjectsomitted: the value is accepted and stored, but the subject is absent by the template’s rule when the envelope is sent, so the prefilled section opens HIDDEN until the signer switches it on.
See Subjects.
Show child attributes
Show child attributes
{ "spouse": true, "dependant_2": false }
Response
A verdict for every entry of values, in the order sent, and ok saying whether create would accept them all. A refused entry is still a 200: the request was well formed.