Skip to main content
This page collects the behaviours that most often trip up people building against the NSEV WebPortal API for the first time. Each one is easy to miss and easy to design around once you know about it.

PDF input pitfalls

The API accepts PDFs that already carry structure - signatures, signing fields, form fields - and it converts or repairs documents on upload. A few behaviours follow from that. Adding form fields to a PDF/A breaks PDF/A conformance. PDF/A uploads are only allowed when the source is pdfa1a or pdfa2a. If you then add form fields through the API, the “/A” conformance is broken and you are left with a regular PDF. To recover PDF/A, set DocumentOptions.PdfOptions.TargetFormat to pdfa1a or pdfa2a on the add-document call: the breaking still happens, but once all fields have been filled or saved the document is reconverted to the target format, producing a PDF/A document again. This conversion only takes effect when document conversion is enabled in the tenant configuration.
When itsme is used as a signing method, TargetFormat of pdfa1a or pdfa2a is mandatory. The platform does not check whether you set it, so this is on you to get right.
A PDF that already contains signatures is never auto-repaired. The PdfErrorHandling step that detects and fixes minor PDF flaws will not modify a document that already has signatures, because fixing it would invalidate those signatures. The presence of a flaw on an already-signed document may then surface as a warning or an error depending on which PdfErrorHandling mode you choose on the add-document call (see the DocumentOptions.PdfOptions.PdfErrorHandling property in the Add document API reference). Plan for the strict modes (DetectFail, DetectFixFail) to reject such a document rather than silently accepting it. Detected fields are not kept unless you ask. When you upload a document that was prepared elsewhere - for example through the Document Portal - and it contains existing signatures, signing field markers, or form field markers, the resulting document comes back not fully processed: when you fetch it, IsActionNeeded is true, and HasSignatures, HasSigningFields and HasFormFields tell you what was detected. You must explicitly decide what to keep with POST /packages/{packageId}/documents/{documentId}/actions before the document moves to Draft and becomes usable. Two of those choices are mutually exclusive: you cannot keep existing signatures and use form fields at the same time, so KeepSignatures and KeepFormFields cannot both be true in one request. On the asynchronous add-document call the same KeepSignatures, KeepSigningFields and KeepFormFields options can be supplied up front under DocumentOptions. Signature- and text-field names must be alphanumeric. When you upload a PDF whose existing signature or text fields were created in another tool, the field names must contain only letters and numbers. Special characters such as accented letters, slashes and dots are not supported. Separately, when an uploaded PDF contains text fields whose name matches the Text Field format configured for your tenant, those text fields are converted to empty signature fields and the original text field is not displayed - this is intended behaviour, and it does not apply to documents that already contain one or more signatures.

An API stakeholder is not a Contact

The API has no Contact resource. Contacts exist only in the WebPortal UI, as an address-book convenience for people who set up packages by hand; when a Contact is used to set up a package it ultimately becomes an ordinary person stakeholder on that package - the same object you create directly through the API. So when you add a stakeholder via the API you are always defining the party on the package itself, never referencing a saved address-book entry. The one place the WebPortal’s saved entities surface in the API is the contactGroup stakeholder type, which references a contact group by its ContactGroupCode - and even that is converted to a plain group stakeholder when the package is activated.
For the full stakeholder/actor model and the three stakeholder types, see The package model → A stakeholder is not a Contact.

The initiator does not need document-group access

A package can be assigned to a document group with DocumentGroupCode. In a default configuration an initiator uploads packages to their personal My Documents folder (code 00001), which is visible only to that user and cannot be shared. To enable collaboration, an administrator can configure additional document groups that different users may access, so they can work on one another’s documents. The surprise is that the initiator does not need to be a member of, or have permissions on, the document group the package is assigned to. To upload to the My Documents folder, omit DocumentGroupCode or set it to 00001; to upload elsewhere, pass that group’s code.
DocumentGroupCode is a string, even though the values look numeric - the leading zeroes in 00001 are part of the value, not formatting. List the configured groups and their codes with GET /documentGroups. An unknown code returns 404 DocumentGroup.NotFoundWithCode.

Package and document naming rules

A package Name and a document Name are both shown in the WebPortal, and the package name is also used as the file name when the package is downloaded as a .zip. Two rules catch people out:
  • Do not add a file extension to the name value.
  • Avoid forbidden and HTML-sensitive characters. Do not use file-name characters such as slash (/), backslash (\), question mark (?), percent (%), asterisk (*), colon (:), pipe (|), single quote ('), double quote ("), less-than (<) or greater-than (>). This list is not exhaustive - also avoid HTML-sensitive characters such as ampersand (&) and apostrophe.
Both names are 1–150 characters.
When itsme is used as a signing method, restrict the name to characters supported by ISO 8859-15. That covers most usual characters, but some software-generated characters - curly apostrophes and long dashes, for example - are not supported.

The Web Application Firewall is strict

Requests pass through a Web Application Firewall before they reach the API, and it rejects things the API itself might otherwise tolerate. Two rules cause most of the surprise:
  • Send strictly valid JSON. Inline comments, trailing commas, and any other malformed JSON are rejected before the API sees them.
  • Send a non-empty User-Agent header. The default user agent for tools like curl or wget may be blocked.
Both are covered in full, with examples, in Best Practices.