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

SDK — Ananke Trust usage

Issue, manage, verify, and bulk-process Ananke Trust documents using the @ananke/sdk TypeScript client.

Templates

Templates define the document schema, presentment settings, and validity rules. Manage them through client.trust.templates.

List & create templates
// List all templates (paged)
const page = await client.trust.templates.list({ isActive: true });
console.log(page.items[0].name);

// Auto-paginate all templates
for await (const tmpl of client.trust.templates.listAll()) {
  console.log(tmpl.id, tmpl.name);
}

// Create a new template
const tmpl = await client.trust.templates.create({
  name: "Certificate of Completion",
  docType: "certificate",
  languages: ["en"],
  schema: [
    { key: "certNumber", label: "Certificate Number", required: true },
    { key: "courseName", label: "Course Name", required: true },
  ],
});

Template methods

MethodDescription
list(opts?)Paged list with optional search, isActive, isArchived filters
listAll(opts?)Async generator — yields all templates
get(id)Single template by ID
create(body)Create a new template
update(id, body)Full update
delete(id)Permanently delete
archive(id, reason?)Soft-archive (keeps data, hides from active lists)
unarchive(id)Restore archived template
duplicate(id, name)Copy with a new name
getCsvFields(id)Column metadata for bulk CSV uploads
setPlacementTemplate(id, placementId)Link a default Ananke TCode placement template

Issue a document

Use client.trust.documents.issue() to create a new Ananke Trust document (credential, certificate, or contract).

Issue an Ananke Trust document
import { readFileSync } from "node:fs";

const doc = await client.trust.documents.issue({
  templateId:     "tmpl-uuid",
  recipientName:  "Jane Doe",
  recipientEmail: "jane@example.com",
  fields: [
    { key: "certNumber", value: "C-2026-001" },
    { key: "courseName", value: "Advanced Security" },
  ],
  validityType:  "Years",
  validityValue: 2,
  pdf: readFileSync("./certificate.pdf"),   // Buffer, base64, Blob, or File
});

console.log(doc.reference);  // "TRF-ABCD1234"
console.log(doc.status);     // "Active"

Request fields

FieldTypeRequiredDescription
templateIdstringYesTemplate to issue against
recipientNamestringYesRecipient display name
recipientEmailstringYesDelivery email address
fieldsarrayNoTemplate field key/value pairs
adhocFieldsarrayNoExtra fields not in schema
validityTypestringNoDays, Months, Years, or Never
validityValuenumberNoDuration (paired with validityType)
pdfPdfInputNoSource PDF (Buffer, base64, Blob, File)
scheduledForstringNoISO 8601 timestamp for delayed issuance
List and search documents
// Paged listing
const page = await client.trust.documents.list({
  page: 1,
  pageSize: 50,
  status: "Active",
});
console.log(page.total, page.items.length);

// Auto-paginate all documents
for await (const doc of client.trust.documents.listAll({ status: "Active" })) {
  console.log(doc.reference);
}

// Search by field value
const results = await client.trust.documents.searchByField({
  fieldKey: "certNumber",
  fieldValue: "C-2026-001",
});

Lifecycle management

Ananke Trust documents follow a lifecycle: Active → Suspended → Revoked (or Expired). Use the named helpers for safe transitions:

Lifecycle transitions
// Suspend a document (temporary — can be reactivated)
await client.trust.documents.suspend("issuance-id");

// Revoke permanently
await client.trust.documents.revoke("issuance-id");

// Reactivate a suspended document
await client.trust.documents.reactivate("issuance-id");

// Generic lifecycle method (for less common transitions)
await client.trust.documents.lifecycle("issuance-id", "expire");
ActionEffect
suspendTemporarily suspend — shows as suspended on verification
revokePermanently revoke — irreversible
reinstateRestore a suspended document to active
expireMark as expired

Download PDF

Download rendered PDF
import { writeFileSync } from "node:fs";

const blob = await client.trust.documents.download("issuance-id");
const buffer = Buffer.from(await blob.arrayBuffer());
writeFileSync("downloaded-certificate.pdf", buffer);

Replace & resend

Replace and resend
// Replace with new data (creates a new version, revokes previous)
const updated = await client.trust.documents.replace("issuance-id", {
  recipientName: "Jane Smith",  // corrected name
  fields: [{ key: "certNumber", value: "C-2026-001-v2" }],
});

// Replace only the PDF bytes (keeps all metadata intact)
await client.trust.documents.replacePdf("issuance-id", readFileSync("./v2.pdf"));

// Resend the delivery email
await client.trust.documents.resend("issuance-id");

Duplicate check

Before issuing, you can check whether a document with the same field values already exists. This prevents accidental double-issuance.

Idempotency check
const check = await client.trust.documents.duplicateCheck({
  templateId: "tmpl-uuid",
  fields: [{ key: "certNumber", value: "C-2026-001" }],
});

if (check.isDuplicate) {
  console.log("Already issued:", check.existingReference);
} else {
  // Safe to issue
}

Verification

Verify Ananke Trust documents by reference or content hash. These are public verification operations — they validate authenticity and return the current status.

Verify an Ananke Trust document
// By reference
const result = await client.trust.verify.byReference("TRF-XXXX");
console.log(result.isValid);     // true
console.log(result.status);      // "active" | "suspended" | "revoked" | "expired"
console.log(result.issuerName);  // "Acme Corp"
console.log(result.issuedAt);    // ISO 8601

// By content hash
const hashResult = await client.trust.verify.byHash("sha256:abcd...");

// Verification history (audit trail)
const history = await client.trust.verify.history("issuance-id");

Bulk jobs

Bulk issuance lets you issue hundreds or thousands of documents from a CSV file, with an optional ZIP of per-row PDFs.

Bulk issuance workflow
import { readFileSync } from "node:fs";

// 1. Discover CSV schema
const fields = await client.trust.templates.getCsvFields("tmpl-uuid");
// fields: [{ name: "recipient_name", required: true }, ...]

// 2. Submit the bulk job
const csv = readFileSync("./batch.csv");
const zip = readFileSync("./pdfs.zip"); // optional

const job = await client.trust.bulkJobs.create({
  templateId:    "tmpl-uuid",
  issuancePath:  "DigitalFirst",
  csvFileBase64: csv.toString("base64"),
  zipFileBase64: zip.toString("base64"),
});

// 3. Poll for completion
let progress;
do {
  progress = await client.trust.bulkJobs.getProgress(job.id);
  console.log(`${progress.status}: ${progress.successCount}/${progress.totalCount}`);
  if (progress.status !== "Completed" && progress.status !== "Failed") {
    await new Promise(r => setTimeout(r, 2000));
  }
} while (progress.status !== "Completed" && progress.status !== "Failed");

// 4. Check results
const rows = await client.trust.bulkJobs.getRows(job.id, { page: 1 });
const failed = rows.items.filter(r => r.status === "Failed");

// 5. Download error report
const report = await client.trust.bulkJobs.getArtifact(job.id, "error-report");

// 6. Retry failed rows
if (failed.length) await client.trust.bulkJobs.retry(job.id);

Bulk job methods

MethodDescription
create(body)Submit a new bulk job
list(opts?)Paged list of jobs with status filters
listAll(opts?)Async generator — all jobs
get(jobId)Job metadata
getProgress(jobId)Lightweight status poll
getRows(jobId, opts?)Per-row outcomes (paged)
getArtifact(jobId, type)Download error-report or output-manifest
retry(jobId)Retry failed rows
cancel(jobId)Cancel a queued/running job