Signature Integration API
The canonical server-to-server entry point for document signing on the Assentify Digital Experience Platform (DXP). One key-authenticated call renders a template or signs your PDF bytes, then returns the signed document inline.
Base URL · Auth · ExamplesIntroduction
The Signature Integration endpoint is the canonical server-to-server entry point for signing on the Assentify platform. It replaces ad-hoc use of POST /api/signature/{stepId} for non-workflow callers, consolidating template rendering, visual verification, and cryptographic signing behind a single, key-authenticated call.
One endpoint serves two operating modes. In Mode A you reference a tenant-owned template by TemplateId and Assentify renders it fresh (token placeholders resolved, signature imagery embedded) before signing. In Mode B you supply an existing PDF as base64 via PdfBase64 and Assentify signs the bytes you provide.
Authentication and Headers
The endpoint is decorated [AllowAnonymous] plus [ApiKeyFilter]. It does not use the user-bearer-token flow. Tenant identity comes from the X-Tenant-Identifier header, not from a JWT claim.
| Header | Required | Value |
|---|---|---|
| x-ms-key | Yes | Integration API key (issued by Assentify). Validated by ApiKeyFilter. |
| X-Tenant-Identifier | Yes | Tenant GUID. Used to route template lookup, blob storage, and cert-service signing. Returns 400 if missing or not a valid GUID. |
| Content-Type | Yes | application/json |
- Request an integration API key from Assentify. This is the value you send in the x-ms-key header on every call.
- Obtain your tenant GUID and send it in the X-Tenant-Identifier header. It routes template lookup, blob storage, and cert-service signing.
- Set Content-Type to
application/jsonand POST your request body.
Sign a document
Renders a tenant-owned template or signs supplied PDF bytes, then returns the signed PDF inline. Authenticate with the x-ms-key and X-Tenant-Identifier headers described above.
Request body: IntegrationSignatureRequest
TemplateId or PdfBase64. The request is rejected with 400 if both are set, or if neither is set.{
"templateId": 67890, // long. Mode A: render tenant-owned template + sign.
// Must be a template that belongs to X-Tenant-Identifier (404 if not found).
"pdfBase64": null, // string. Mode B: sign existing PDF bytes (base64).
// Tokens / template render are IGNORED in this mode.
// === OPTIONAL (both modes) ===
"documentName": "Contract-2026.pdf", // Used as response FileName. Default: template.Name in TemplateId mode.
"enableVisualVerifier": true, // bool, default false. Enables the rich appearance
// (watermarks / barcode / labels / QR). See Visual Verifier.
"signatureLabelLine1": "Signed by MARION CHEPKOGEI",
"signatureLabelLine2": "2026-04-24",
"faceWatermarkFields": { // Dict<string,string>. Positioned face-watermark data.
"name": "MARION CHEPKOGEI",
"id": "A1234567"
},
"signatureWatermarkDiagonalFields": { // Dict<string,string>. Diagonal watermark content.
"tenant": "AssentifyDemo",
"reference": "REQ-2026-04-24-001"
},
"encryptedFields": { // Dict<string,string>.
},
// === OPTIONAL (TemplateId mode only, IGNORED if PdfBase64 is set) ===
"signature": "iVBORw0KGgoAAAANS…", // Base64 PNG. Embedded into signature token elements
// in the rendered HTML and also passed to cert-service appearance.
// When omitted, no visual sig image is embedded.
// cryptographic signing still occurs.
"tokens": { // Token values for template placeholders.
"1773": "MARION", // Key = Token ID (long as string).
"1774": "CHEPKOGEI" // Value = replacement text or image URL.
// Non-numeric keys are skipped with a warning log.
},
// === FORWARD-COMPAT (accepted, not yet enforced) ===
"hasOtp": false,
"otpCode": null
}
| Field | Type | Applies to | Description |
|---|---|---|---|
| templateId | long | Mode A | Renders a tenant-owned template and signs it. Must belong to the X-Tenant-Identifier tenant (404 if not found). |
| pdfBase64 | string | Mode B | Signs existing PDF bytes supplied as base64. Tokens and template rendering are ignored in this mode. |
| documentName | string | Both | Used as the response FileName. Default: template.Name in TemplateId mode. |
| enableVisualVerifier | bool | Both | Default false. Enables the rich appearance (watermarks, barcode, labels, QR). See Visual Verifier. |
| signatureLabelLine1 | string | Both | First line of the signature label (for example, signer name). |
| signatureLabelLine2 | string | Both | Second line of the signature label (for example, signing date). |
| faceWatermarkFields | Dict<string,string> | Both | Positioned face-watermark data. |
| signatureWatermarkDiagonalFields | Dict<string,string> | Both | Diagonal watermark content. |
| encryptedFields | Dict<string,string> | Both | Carried verbatim into the PDF417 barcode payload (see Visual Verifier). |
| signature | string (Base64 PNG) | Mode A only | Embedded into signature token elements in the rendered HTML and passed to cert-service appearance. When omitted, no visual signature image is embedded; cryptographic signing still occurs. Ignored if PdfBase64 is set. |
| tokens | Dict<string,string> | Mode A only | Token values for template placeholders. Key = Token ID (long as string); value = replacement text or image URL. Non-numeric keys are skipped with a warning log. Ignored if PdfBase64 is set. |
| hasOtp | bool | Forward-compat | Accepted, not yet enforced. |
| otpCode | string | Forward-compat | Accepted, not yet enforced. |
Response: SignatureResponse
{
"fileName": "Contract-2026.pdf", // from DocumentName, or "signed-document.pdf"
"signedDocumentUri": "", // 260427-ebl: ALWAYS empty string in both modes
// are stateless (no blob upload). Save the
// returned `signedDocument` bytes yourself.
"signedDocument": "JVBERi0xLjQKJeLjz9…", // base64-encoded signed PDF bytes
"status": "Completed", // "Completed" | "Failed"
"otpStatus": "NotRequired", // always "NotRequired" today (Phase-2 follow-up)
"message": null // populated on failure
}
| Field | Type | Description |
|---|---|---|
| fileName | string | From DocumentName, or "signed-document.pdf". |
| signedDocumentUri | string | Always an empty string (260427-ebl). Both modes are stateless; there is no blob upload. Save the returned signedDocument bytes yourself. |
| signedDocument | string | Base64-encoded signed PDF bytes. |
| status | string | "Completed" or "Failed". |
| otpStatus | string | Always "NotRequired" today (Phase-2 follow-up). |
| message | string | Populated on failure. |
Two modes in one endpoint
Mode A: TemplateId (render fresh from template, then sign)
Assentify looks up the template owned by the X-Tenant-Identifier tenant (404 if it does not exist there), renders it with the supplied tokens, and signs the result. Each token key is a Token ID (long as string) and each value is the replacement text or image URL; non-numeric keys are skipped with a warning log. When signature is provided, the Base64 PNG is embedded into signature token elements in the rendered HTML and also passed to the cert-service appearance. When omitted, no visual signature image is embedded, but cryptographic signing still occurs.
Mode B: PdfBase64 (sign existing PDF bytes)
Supply the document as base64-encoded PDF bytes in pdfBase64 and Assentify signs exactly what you send. Template rendering does not run and tokens are ignored, as are the other TemplateId-only fields (signature). Options shared by both modes (documentName, enableVisualVerifier, labels, and watermark dictionaries) apply as normal. A base64 decode failure is rejected with 400.
Visual Verifier
enableVisualVerifier (default false) enables the rich signature appearance (watermarks, barcode, labels, and QR). When EnableVisualVerifier = true, the appearance is populated as follows.
| Appearance input | In | Type | Populated from |
|---|---|---|---|
| TenantIdentifier | appearance | string | The X-Tenant-Identifier header. |
| PersonalIdentifier | appearance | string | Empty string. |
| DocumentName | appearance | string | The DocumentName field. |
| PrimaryColorHex | appearance | string | Tenant brand color. |
| SignatureImageBytes | appearance | bytes | Signature (when supplied). |
| SignatureLabelLine1 / SignatureLabelLine2 | appearance | string | The corresponding request fields. |
| FaceWatermarkFields | appearance | Dict<string,string> | The corresponding request field. |
| SignatureWatermarkDiagonalFields | appearance | Dict<string,string> | The corresponding request field. |
| EncryptedFields | appearance | Dict<string,string> | Carried into the PDF417 barcode payload, verbatim. |
HTTP status codes
| Code | When |
|---|---|
| 200 OK | Endpoint completed. Body is SignatureResponse. A 200 does not guarantee a cryptographic signature (see below). |
| 400 Bad Request | Missing or invalid X-Tenant-Identifier, XOR rule violated (both or neither of TemplateId/PdfBase64), or service-raised ArgumentException (for example, base64 decode failure). |
| 401 Unauthorized | Missing or invalid x-ms-key (enforced by ApiKeyFilter). |
| 404 Not Found | TemplateId does not exist in the X-Tenant-Identifier tenant (TemplateId mode only). Body is the message string. Does not differentiate "wrong tenant" from "does not exist" (no info leak). |
| 500 Internal Server Error | Template render failure, and similar. Cert-service failures no longer return 500; they are swallowed (see below). |
status field of the SignatureResponse ("Completed" versus "Failed", with message populated on failure) before treating a document as signed.Sample request (curl)
curl --location 'https://signme.assentify.com/api/signature/integration' \
--header 'Content-Type: application/json' \
--header 'X-Tenant-Identifier: a6454235-7100-46fa-858a-08dbcbc01489' \
--header 'x-ms-key: <YOUR_INTEGRATION_API_KEY>' \
--data '{
"DocumentName": "Consent-Form-QA.pdf",
"TemplateId": 76,
"EnableVisualVerifier": true,
"SignatureLabelLine1": "Signed by MARION CHEPKOGEI",
"SignatureLabelLine2": "2026-04-24",
"Tokens": {},
"EncryptedFields": {
"tenant_id": "a6454235-7100-46fa-858a-08dbcbc01489",
"reference": "TEST-001"
}
}'
<YOUR_INTEGRATION_API_KEY> with the integration API key issued by Assentify. The x-ms-key header is mandatory.