Loading...
Loading...
The @drd/sdk package provides a TypeScript-first client for integrating DRD governance into your AI agents.
Install the @drd/sdk package from npm, yarn, or pnpm.
npm install @drd/sdk
# or
yarn add @drd/sdk
# or
pnpm add @drd/sdkCreate a DRD client instance with your API key. The SDK handles token exchange, batching, and retries automatically.
import { DRD } from '@drd/sdk';
const drd = new DRD({
apiKey: process.env.DRD_API_KEY,
// Optional: override base URL
// baseUrl: 'https://api.drd.io/api/v1',
});Before performing any action, call guard() to check if the action is allowed by your policies.
const result = await drd.guard('send_email', {
to: 'user@example.com',
subject: 'Weekly digest',
});
if (result.allowed) {
// Action is permitted — proceed
await sendEmail(result.context);
} else {
// Action denied — check result.reason
console.log('Denied:', result.reason);
console.log('Policy:', result.policyId);
}
// If approval is required
if (result.requiresApproval) {
const approval = await drd.waitForApproval(result.approvalId);
if (approval.decision === 'approved') {
await sendEmail(result.context);
}
}After performing an action, report it to build your agent's reputation and maintain the audit trail.
// Report a single event
await drd.report('email.sent', {
to: 'user@example.com',
subject: 'Weekly digest',
});
// Events are batched automatically
// Flush happens every 5 seconds or when batch reaches 50 events
// Call shutdown() to flush remaining events
await drd.shutdown();Retrieve your agent's current trust score, component breakdown, and badge tier.
const score = await drd.getTrustScore();
console.log(score.overall); // 0-100
console.log(score.components); // { reliability, compliance, efficiency, consistency, tenure }
console.log(score.badge); // 'bronze' | 'silver' | 'gold' | 'government' | nullThe SDK provides typed error classes for common failure modes.
import { DRDDeniedError, DRDTimeoutError, DRDNetworkError } from '@drd/sdk';
try {
await drd.guard('transfer_funds', { amount: 10000 });
} catch (error) {
if (error instanceof DRDDeniedError) {
// Policy explicitly denied this action
console.log('Denied by policy:', error.policyId);
} else if (error instanceof DRDTimeoutError) {
// Request timed out
} else if (error instanceof DRDNetworkError) {
// Network connectivity issue
}
}Always call shutdown() when your agent is done to flush any remaining batched events and clean up resources.
process.on('SIGTERM', async () => {
await drd.shutdown();
process.exit(0);
});The SDK is organized into modules that map to the platform's core capabilities. Access each module via the client instance.
drd.agentsAgent registration and management
drd.policiesPolicy CRUD and evaluation
drd.eventsAudit trail ingestion
drd.contentContent protection
drd.trustTrust scores and badges
drd.webhooksWebhook configuration
const { data: agents, meta } = await drd.agents.list({
status: "active",
limit: 25,
cursor: undefined, // pass meta.cursor for next page
});
for (const agent of agents) {
console.log(agent.id, agent.name, agent.trustScore);
}const agent = await drd.agents.create({
name: "Content Scanner v2",
description: "Scans uploaded content for policy compliance",
metadata: {
provider: "anthropic",
model: "claude-opus-4-6",
version: "2.1.0",
},
capabilities: ["content-analysis", "image-classification"],
tags: ["production"],
});
// agent.id -> "01956abc-def0-..."
// agent.did -> "did:drd:01956abc-..."
// agent.apiKey -> "drd_ag_sk_..." (returned once)const agent = await drd.agents.get("01956abc-def0-...");
console.log(agent.name); // "Content Scanner v2"
console.log(agent.trustScore); // 87
console.log(agent.trustBreakdown); // { compliance: 92, reliability: 85, transparency: 84 }The primary SDK method for governance. Call this before your agent performs any action.
const decision = await drd.policies.evaluate({
agentId: "01956abc-...",
action: "send_email",
context: {
target: "user@example.com",
emailCount: 12,
amount: 500,
},
});
if (decision.allowed) {
console.log("Allowed:", decision.reason);
console.log("Evaluation time:", decision.decisionTrace.evaluationTimeMs, "ms");
} else {
console.log("Denied:", decision.reason);
}const policy = await drd.policies.create({
name: "Email Rate Limiter",
description: "Prevents agents from sending excessive emails",
enabled: true,
rules: [
{
action: "deny",
condition: "context.emailCount > 50",
resourceType: "communication",
priority: 10,
},
{
action: "require_approval",
condition: "context.amount > 10000",
resourceType: "financial",
priority: 20,
},
],
});Batch ingest up to 100 events per call. Events are hash-chained for tamper-evidence.
const result = await drd.events.ingest([
{
type: "email.sent",
agentId: "01956abc-...",
data: {
to: "user@example.com",
subject: "Order Confirmation",
templateId: "tmpl-order-confirm",
},
timestamp: new Date().toISOString(),
},
{
type: "content.scanned",
agentId: "01956abc-...",
data: {
contentId: "019content-...",
result: "clean",
scanDurationMs: 142,
},
timestamp: new Date().toISOString(),
},
]);
console.log("Ingested:", result.ingested);
console.log("Chain hash:", result.events[0].chainHash);const content = await drd.content.register({
title: "Product Photo - Summer 2026",
contentType: "image",
contentUrl: "https://cdn.example.com/photos/summer-2026.jpg",
contentHash: "sha256:a1b2c3d4e5f6...",
options: {
generateFingerprint: true,
applyWatermark: true,
createC2PA: true,
},
});
console.log("Content ID:", content.id);
console.log("Fingerprint:", content.fingerprint.phash);
console.log("C2PA Status:", content.c2pa.status); // "signed"const scan = await drd.content.scan({
contentUrl: "https://example.com/suspect-image.png",
contentType: "image",
threshold: 0.85,
});
for (const match of scan.matches) {
console.log(`Match: ${match.title} (similarity: ${match.similarity})`);
console.log(`Owner: ${match.owner}`);
}const trust = await drd.trust.getScore("01956abc-...");
console.log("Score:", trust.trustScore); // 87
console.log("Tier:", trust.tier); // "gold"
console.log("Breakdown:");
console.log(" Compliance:", trust.breakdown.compliance.score); // 92
console.log(" Reliability:", trust.breakdown.reliability.score); // 85
console.log(" Transparency:", trust.breakdown.transparency.score); // 84
for (const point of trust.history) {
console.log(` ${point.date}: ${point.score}`);
}The SDK exports all request and response types for full type safety.
import type {
Agent,
AgentCreateInput,
Policy,
PolicyCreateInput,
PolicyEvaluateInput,
PolicyDecision,
Event,
EventIngestInput,
Content,
ContentRegisterInput,
ContentScanResult,
TrustScore,
TrustBreakdown,
DRDClientConfig,
PaginatedResponse,
} from "@drd/sdk";
function handleDecision(decision: PolicyDecision): void {
if (decision.allowed) {
// TypeScript knows decision.reason is string
// and decision.decisionTrace is available
}
}Configure webhooks to receive real-time notifications for platform events. Webhook payloads are signed with HMAC-SHA256 for verification.
// Create a webhook
const webhook = await drd.webhooks.create({
url: "https://your-app.com/api/drd-webhook",
events: [
"agent.registered",
"policy.violated",
"enforcement.issued",
"trust.score.changed",
],
secret: "whsec_your_signing_secret",
});
// Verify incoming webhooks in your handler
import { verifyWebhookSignature } from "@drd/sdk";
export async function POST(req: Request) {
const body = await req.text();
const signature = req.headers.get("X-DRD-Signature")!;
const timestamp = req.headers.get("X-DRD-Timestamp")!;
const valid = verifyWebhookSignature({
body,
signature,
timestamp,
secret: process.env.DRD_WEBHOOK_SECRET!,
});
if (!valid) {
return new Response("Invalid signature", { status: 401 });
}
const event = JSON.parse(body);
console.log("Webhook event:", event.type, event.data);
return new Response("OK", { status: 200 });
}