SDK npm package is not published yet and API environments may be unavailable.View status
Ananke Trust

Issuance

Create and deliver verifiable digital documents. This page covers the issuance request, required inputs, lifecycle states, and error handling.

Overview

Issuance creates a new document under your tenant. The document is signed, stored, and optionally anchored for tamper-evidence. You can deliver the document to a recipient via email or retrieve it programmatically.

Issuance request

Send a POST request to /v1/trust/issuances with a JSON body. The SDK wraps this as client.trust.documents.issue().

SDK — Issue a document
const doc = await client.trust.documents.issue({
  templateId:     "tmpl-uuid",
  recipientName:  "Jane Doe",
  recipientEmail: "jane@example.com",
  documentTitle:  "Certificate of Completion",
  fields: [
    { key: "certNumber", value: "C-2026-001" },
    { key: "course",     value: "Platform Engineering" },
    { key: "grade",      value: "Distinction" },
  ],
});
curl — Issue a document
curl -X POST https://api.anankelabs.net/v1/trust/issuances \
  -H "x-api-key: ak_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "templateId": "tmpl-uuid",
    "recipientName": "Jane Doe",
    "recipientEmail": "jane@example.com",
    "documentTitle": "Certificate of Completion",
    "fields": [
      { "key": "certNumber", "value": "C-2026-001" },
      { "key": "course", "value": "Platform Engineering" }
    ]
  }'

Required fields

FieldTypeDescription
templateIdstringID of the template to use for this issuance.
recipientNamestringFull name of the document recipient.
fieldsarrayKey–value pairs matching the template's field schema.

Optional fields

FieldTypeDescription
recipientEmailstringRecipient email address. If provided, Ananke Labs may deliver the document via email.
documentTitlestringCustom title for this specific document.
externalIdstringYour system's ID for correlation and duplicate detection.
pdfBuffer | Blob | stringPDF file to attach (see PDF attachment section below).
expiresAtstring (ISO 8601)Optional expiration date for the document.

PDF attachment

You can attach a PDF to an issuance. The SDK normalises multiple input formats:

  • Buffer — Node.js Buffer (most common server-side)
  • Uint8Array / ArrayBuffer — Raw bytes
  • Blob / File — Browser types
  • string — Base64-encoded content
Attach a PDF
import { readFileSync } from "node:fs";

const doc = await client.trust.documents.issue({
  templateId:     "tmpl-uuid",
  recipientName:  "Jane Doe",
  fields:         [{ key: "certNumber", value: "C-2026-001" }],
  pdf:            readFileSync("./certificate.pdf"),
});

Response

A successful issuance returns the created document object:

201 Created
{
  "data": {
    "id": "uuid",
    "reference": "TRF-ABCD1234",
    "status": "Active",
    "recipientName": "Jane Doe",
    "recipientEmail": "jane@example.com",
    "documentTitle": "Certificate of Completion",
    "templateId": "tmpl-uuid",
    "fields": [
      { "key": "certNumber", "value": "C-2026-001" }
    ],
    "createdAt": "2026-03-18T10:00:00Z"
  }
}

Lifecycle states

StatusDescriptionVerification verdict
ActiveDocument is valid and verifiable.valid
SuspendedTemporarily disabled. Can be reactivated.suspended
RevokedPermanently invalidated. Terminal state.revoked
ExpiredPast the expiration date. Cannot be reactivated.expired

Lifecycle transitions

After issuance, you can change a document's status using the lifecycle endpoint:

Suspend a document
await client.trust.documents.lifecycle(doc.id, {
  action: "suspend",
  reason: "Under review",
});

Valid transitions:

  • Active → Suspended
  • Active → Revoked
  • Suspended → Active (reinstate)
  • Suspended → Revoked

Revoked and Expired are terminal — no further transitions are possible.

Replacement

Replacement creates a new document version linked to the original. The original is automatically revoked. Use this when the document content has changed but the credential should remain traceable.

Replace a document
const replacement = await client.trust.documents.replace(doc.id, {
  recipientName: "Jane Doe",
  fields: [
    { key: "certNumber", value: "C-2026-002" },
    { key: "course",     value: "Platform Engineering — Updated" },
  ],
});

Duplicate detection

Before issuing, you can check for duplicates using the externalId or field values:

Duplicate check
POST /v1/trust/issuances/duplicate-check
{
  "templateId": "tmpl-uuid",
  "externalId": "your-system-id-123"
}

Returns 409 Conflict if a matching document already exists, or 200 OK if clear.

Errors

StatusReason
400Missing or invalid fields. Check the validation error details.
404Template not found under this tenant.
409Duplicate detection fired — a matching document already exists.
422Template is archived or field schema mismatch.

Next steps