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 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
| Method | Description |
|---|---|
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).
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
| Field | Type | Required | Description |
|---|---|---|---|
templateId | string | Yes | Template to issue against |
recipientName | string | Yes | Recipient display name |
recipientEmail | string | Yes | Delivery email address |
fields | array | No | Template field key/value pairs |
adhocFields | array | No | Extra fields not in schema |
validityType | string | No | Days, Months, Years, or Never |
validityValue | number | No | Duration (paired with validityType) |
pdf | PdfInput | No | Source PDF (Buffer, base64, Blob, File) |
scheduledFor | string | No | ISO 8601 timestamp for delayed issuance |
List & search
// 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:
// 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");| Action | Effect |
|---|---|
suspend | Temporarily suspend — shows as suspended on verification |
revoke | Permanently revoke — irreversible |
reinstate | Restore a suspended document to active |
expire | Mark as expired |
Download 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 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.
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.
// 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.
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
| Method | Description |
|---|---|
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 |