NextSign API
Documents

Retrieve a Document

Fetch one library document with GET /v3/api/documents/{id} — its versions and, for a .docx, the exact fields you can fill when creating a case.

Returns one document from your library: its versions, and — for a .docx — the fields a case built from it can fill, each with its type, label, whether it is required, its options and its bounds. This is the page to read before creating a case from a document.

GET https://api.nextsign.dk/v3/api/documents/{id}

Authenticated with an API key — see Authorization.

Quickstart

curl https://api.nextsign.dk/v3/api/documents/6a58c2a06f829bebd9232c1b \
  -H "Authorization: Bearer $NEXTSIGN_API_KEY"
const response = await fetch(
  `https://api.nextsign.dk/v3/api/documents/${documentId}`,
  { headers: { Authorization: `Bearer ${process.env.NEXTSIGN_API_KEY}` } },
);

const { document } = await response.json();
const required = document.version.fields.filter((f) => f.required).map((f) => f.path);
import os, requests

response = requests.get(
    f"https://api.nextsign.dk/v3/api/documents/{document_id}",
    headers={"Authorization": f"Bearer {os.environ['NEXTSIGN_API_KEY']}"},
)

document = response.json()["document"]
required = [f["path"] for f in document["version"]["fields"] if f["required"]]

Path Parameter

ParameterTypeDescription
idstringThe document id, from List Documents

Query Parameters

ParameterTypeDefaultDescription
versionIdstringcurrent versionDescribe a specific version instead of the current one. Must be a version of this document

Every version is listed under versions; only the selected one has its fields expanded under version.


Response

200 OK
{
  "document": {
    "id": "6a394ed08ee8c3669f2c3e17",
    "name": "Offer letter.docx",
    "format": "docx",
    "private": false,
    "shared": false,
    "createdAt": "2026-04-22T08:30:12.004Z",
    "updatedAt": "2026-04-22T08:30:12.551Z",
    "currentVersion": {
      "id": "6a394ed08ee8c3669f2c3e1a",
      "versionNumber": 1,
      "name": "Offer letter.docx",
      "format": "docx",
      "createdAt": "2026-04-22T08:30:12.480Z",
      "fieldCount": 5
    },
    "versions": [
      {
        "id": "6a394ed08ee8c3669f2c3e1a",
        "versionNumber": 1,
        "name": "Offer letter.docx",
        "format": "docx",
        "createdAt": "2026-04-22T08:30:12.480Z"
      }
    ],
    "version": {
      "id": "6a394ed08ee8c3669f2c3e1a",
      "versionNumber": 1,
      "name": "Offer letter.docx",
      "format": "docx",
      "createdAt": "2026-04-22T08:30:12.480Z",
      "fields": [
        {
          "path": "name",
          "type": "string",
          "subtype": "dropdown",
          "label": "Name",
          "description": null,
          "required": true,
          "default": null,
          "options": [
            { "value": "inam", "label": "Inam" },
            { "value": "andreas", "label": "Andreas" }
          ],
          "validations": null,
          "visible": null,
          "item": null,
          "template": null
        },
        {
          "path": "role",
          "type": "string",
          "subtype": null,
          "label": "Role",
          "description": "The position being offered.",
          "required": false,
          "default": null,
          "options": null,
          "validations": { "maxLength": 80 },
          "visible": null,
          "item": null,
          "template": null
        },
        {
          "path": "start_date",
          "type": "string",
          "subtype": "date",
          "label": "Start date",
          "description": null,
          "required": false,
          "default": null,
          "options": null,
          "validations": null,
          "visible": null,
          "item": null,
          "template": null
        },
        {
          "path": "is_senior",
          "type": "boolean",
          "subtype": "checkbox",
          "label": "Is senior",
          "description": null,
          "required": false,
          "default": null,
          "options": null,
          "validations": null,
          "visible": null,
          "item": null,
          "template": null
        },
        {
          "path": "terms",
          "type": "array",
          "subtype": null,
          "label": "Terms",
          "description": null,
          "required": false,
          "default": null,
          "options": null,
          "validations": null,
          "visible": null,
          "item": {
            "type": "object",
            "fields": [
              { "path": "title", "type": "string", "subtype": null, "label": "Title", "description": null, "required": false, "default": null, "options": null, "validations": null, "visible": null, "item": null, "template": null },
              { "path": "description", "type": "string", "subtype": "textarea", "label": "Description", "description": null, "required": false, "default": null, "options": null, "validations": null, "visible": null, "item": null, "template": null }
            ]
          },
          "template": null
        }
      ],
      "automaticFields": [
        { "path": "company_name", "source": "global" },
        { "path": "today", "source": "global" }
      ]
    },
    "access": null
  }
}

The document-level fields are the ones List Documents returns, plus:

FieldDescription
versionsEvery version, newest first. Pin one with versionId when creating a case, otherwise the current version is used
versionThe selected version, with its fields expanded
version.fieldsWhat you can fill — see Fields. Empty for a pdf
version.automaticFieldsWhat exists in the document but is filled for you — see Automatic fields. Sending a value for one of these is rejected
accessFor a shared document, how it was shared: { "type": "referral" } or { "type": "purchase" }. null for your own

Fields

Each entry in version.fields is one value you may send under tags when creating a case, keyed by its path.

FieldDescription
pathThe key to send. Dotted for a field inside a group: address.city is sent as { "address": { "city": "…" } }
typestring, number, boolean or array
subtypeA hint about the kind of string or number: date, email, phone, url, textarea, dropdown, radio, address, template, checkbox, … or null
labelWhat the dashboard shows for this field
descriptionHelp text the document's author wrote, or null
requiredWhether a value must be sent. A field with a default counts as filled
defaultThe value used when you send none
optionsFor a dropdown or radio: the allowed values. Send the value, not the label
validationsBounds the author set — any of minLength, maxLength, match (a regular expression), min, max
visibleWhen set, the field only applies if the rule holds against the other values — see Conditional fields
itemFor an array: the shape of one row
templateFor a template string: the embedded {tags} you may fill — see Template fields

What to send, by type

typeSendExample
stringa string"Aarhus"
string with subtype: "date"any string Date can parse; ISO 8601 is safest"2026-09-01"
string with optionsone of the options[].value strings"andreas"
numbera JSON number — not a numeric string37.5
booleantrue or false. A required boolean must be truetrue
arraya list of rows shaped like item — objects when item.type is object, scalars otherwise[{ "title": "Pay", "description": "Monthly" }]
a group (dotted path)nested objects{ "address": { "city": "Aarhus", "zip": "8000" } }

Values are inserted into the document as you send them — a number is not reformatted and a date is not localised. The dashboard formats what a person types; the API trusts that you already have.

Conditional fields

A field with a visible rule set applies only when the rule holds:

{
  "path": "cvr",
  "required": true,
  "visible": { "match": "all", "rules": [{ "field": "is_company", "operator": "isTrue" }] }
}

Here cvr is required when is_company is true, and must not be sent otherwise — a value for a field that is hidden by its rule is rejected, because the produced document would silently ignore it. match is all or any; operator is one of equals, notEquals, contains, gt, lt, isFilled, isEmpty, isTrue, isFalse; field always names a top-level path.

Template fields

A subtype: "template" string is a passage of editable text with {tags} inside it that the author chose to expose:

{
  "path": "intro",
  "subtype": "template",
  "default": "Dear {name}, welcome to {company_name}.",
  "template": { "tags": [{ "key": "name", "label": "Name", "default": null }] }
}

Send either a plain string to replace the whole text, or { "text": "…", "values": { "name": "Bo" } } to keep (or edit) the text and fill its tags. Tags that are not listed under template.tags resolve from the document's other values automatically.


Automatic fields

automaticFields lists the keys that are in the document but are not yours to fill. Sending a value for any of them is a 400:

sourceFilled from
globalYour account — {company_name}, {today}, the sender's name and email, and the custom global fields set up under Dashboard → Config. See Automatic tags
hiddenThe field's own default. The author marked it hidden so it renders as a constant
computedOther fields — a sum, a lookup, a formatted copy — resolved when the document is produced

Errors

errorStatusMeaning
validation-failed400The id is malformed, or versionId is not a version of this document. See details
document-not-found404No such document in your library
400 Bad Request
{
  "error": "validation-failed",
  "details": [{ "field": "versionId", "message": "is not a version of this document" }]
}

404 does not mean the document does not exist — only that it is not yours to use. A document from another company, a colleague's private document, one that lives inside a public form, and an id that was never issued all answer identically, on purpose. See What you see.

Reading never changes anything, so every request here is safe to retry. Full detail in Errors.