Installation
npm install @engineeringid/sdk
Quick start
import { CredoClient } from '@engineeringid/sdk';
const client = new CredoClient({ apiKey: 'credo_your_api_key' });
// Verify a sealed document
const seal = await client.verification.verify('abc123def456');
console.log(seal.document.name, seal.credential.holderName);
// Generate a stamp image (no auth required)
const png = await client.stamps.generate({
name: 'Jane Smith, PE',
license: 'PE-12345',
state: 'california',
format: 'png'
});
Authentication
Authenticated endpoints require an API key passed as a Bearer token. Public endpoints (verification, stamps) work without authentication.
read
(verification, audit logs, downloads), seal
(read + credential verification triggers), or full
(everything including API key management and compliance).
// API key auth (all authenticated endpoints)
const client = new CredoClient({ apiKey: 'credo_abc123...' });
// Custom base URL (self-hosted or staging)
const staging = new CredoClient({
apiKey: 'credo_abc123...',
baseUrl: 'https://staging-api.example.com/v1',
timeout: 60_000 // 60 seconds
});
// Public endpoints work without an API key
const publicClient = new CredoClient({});
Verification
Look up seals by verification code, match document hashes, and verify PDFs. All verification endpoints are public and do not require authentication.
// Look up a seal by verification code
const seal = await client.verification.verify('abc123def456');
// seal.valid, seal.document, seal.credential, seal.seal
// Match a document hash against a seal
const match = await client.verification.matchHash(
'abc123def456',
'e3b0c44298fc1c149afbf4c8996fb924...'
);
// match.match (boolean), match.message
// Get verification statistics
const stats = await client.verification.stats('abc123def456');
// stats.verificationCount, stats.sealedAt
// Verify a PDF (used by browser extensions)
const result = await client.verification.verifyPdf({
code: 'abc123def456',
hash: 'e3b0c44298fc1c149afbf4c8996fb924...'
});
// result.status: "valid" | "tampered" | "not_found"
Stamps
Generate professional stamp images in SVG, PNG, or PDF format. No authentication required. Supports engineers, architects, land surveyors, and landscape architects across all 50 US states.
// Generate a stamp image (returns ArrayBuffer)
const png = await client.stamps.generate({
name: 'Jane Smith, PE',
license: 'PE-12345',
state: 'california',
profession: 'engineer', // optional, defaults to "engineer"
format: 'png', // "svg" | "png" | "pdf"
discipline: 'CIVIL', // optional
city: 'Los Angeles', // optional
date: '2026-05-08' // optional
});
// Save to file (Node.js)
import { writeFileSync } from 'node:fs';
writeFileSync('stamp.png', Buffer.from(png));
// Display in browser
const blob = new Blob([png], { type: 'image/png' });
img.src = URL.createObjectURL(blob);
Audit logs
Query audit logs, verify chain integrity, export data, and generate compliance reports.
Requires authentication with read
scope (or full
for write operations).
const orgId = 'org-uuid-here';
// List audit logs with filters
const logs = await client.audit.listLogs(orgId, {
limit: 50,
action: 'seal.created',
startDate: '2026-01-01T00:00:00Z'
});
// logs.auditLogs, logs.meta.limit, logs.meta.offset
// Verify audit chain integrity
const chain = await client.audit.verifyChain(orgId);
// chain.status: "passed" | "failed"
// Export as CSV
const csv = await client.audit.export(orgId, { format: 'csv' });
// Create a compliance report
const report = await client.audit.createReport(orgId, {
reportType: 'security',
periodStart: '2026-01-01T00:00:00Z',
periodEnd: '2026-03-31T23:59:59Z'
});
Error handling
All SDKs use typed errors mapped from HTTP status codes. Rate limit errors (429) are automatically retried up to 3 times with exponential backoff.
| Status | Error type | Description |
|---|---|---|
| 401 | AuthenticationError |
Invalid or expired API key |
| 403 | ForbiddenError |
Insufficient API key scope |
| 404 | NotFoundError |
Resource not found |
| 400 / 422 | ValidationError |
Invalid request parameters (includes field-level errors) |
| 429 | RateLimitError |
Rate limit exceeded (auto-retried 3x) |
| 500 | ServerError |
Internal server error |
import {
ApiError,
AuthenticationError,
NotFoundError,
RateLimitError,
ValidationError
} from '@engineeringid/sdk';
try {
const seal = await client.verification.verify('invalid');
} catch (err) {
if (err instanceof NotFoundError) {
console.log('Seal not found');
} else if (err instanceof AuthenticationError) {
console.log('Invalid API key');
} else if (err instanceof RateLimitError) {
console.log(`Rate limited. Retry after ${err.retryAfter}s`);
} else if (err instanceof ValidationError) {
console.log('Validation errors:', err.errors);
} else if (err instanceof ApiError) {
console.log(`API error ${err.statusCode}: ${err.message}`);
}
}
Download
Download the SDK source code as a zip archive. Each package includes typed clients, tests, and build configuration.
Need help integrating?
Tell us about your use case and our developer team will respond with implementation details.