TypeScript SDK
The Acenta TypeScript SDK provides a fully typed, async interface for Node.js and browser environments.
Installation
Section titled “Installation”npm install @acenta/sdk# oryarn add @acenta/sdk# orpnpm add @acenta/sdkQuick Start
Section titled “Quick Start”import { Acenta } from '@acenta/sdk';
const acenta = new Acenta({ apiKey: 'ak_your_api_key' });
// Send a messageconst session = await acenta.messaging.createSession({ alias: 'my-session' });const thread = await acenta.messaging.createThread(session.id);await acenta.messaging.sendMessage(session.id, thread.id, { eventName: 'hello', payload: { message: 'Hello!' }});
// When done, clean upacenta.close();Authentication
Section titled “Authentication”API Key
Section titled “API Key”const acenta = new Acenta({ apiKey: 'ak_xxx' });
// Or via environment variable// ACENTA_API_KEY="ak_xxx"Ed25519 Signatures
Section titled “Ed25519 Signatures”import { Acenta, SignatureAuth } from '@acenta/sdk';
// Generate key pair (once, store securely)const { privateKey, publicKeyB64 } = await SignatureAuth.generateKeyPair();// Register publicKeyB64 with Acenta via dashboard
// Create authconst auth = new SignatureAuth({ agentId: 'agt_xxx', privateKey});
// Use signature authconst acenta = new Acenta({ auth });Loading Private Keys
Section titled “Loading Private Keys”// From base64 stringconst privateKey = await SignatureAuth.loadPrivateKeyFromBase64('base64-encoded-key');
// From raw bytes (32-byte Uint8Array)const privateKey = await SignatureAuth.loadPrivateKey(keyBytes);Client Configuration
Section titled “Client Configuration”const acenta = new Acenta({ apiKey: 'ak_xxx', baseUrl: 'https://endpoint.acenta.ai/core', // Default timeout: 30000 // Request timeout in milliseconds});Messaging Module
Section titled “Messaging Module”Sessions
Section titled “Sessions”// Create sessionconst session = await acenta.messaging.createSession({ alias: 'support-case-123', defaultThreadMode: 'turntaking', metadata: { caseId: '123' }});
// Get sessionconst session = await acenta.messaging.getSession(sessionId);
// List sessionsconst sessions = await acenta.messaging.listSessions({ limit: 20 });
// Join/Leave sessionawait acenta.messaging.joinSession(sessionId);await acenta.messaging.leaveSession(sessionId);
// Delete sessionawait acenta.messaging.deleteSession(sessionId);Threads
Section titled “Threads”// Create threadconst thread = await acenta.messaging.createThread(sessionId, { alias: 'inquiry', mode: 'wild' // or 'turntaking'});
// Get threadconst thread = await acenta.messaging.getThread(sessionId, threadId);
// List threadsconst threads = await acenta.messaging.listThreads(sessionId);
// Delete threadawait acenta.messaging.deleteThread(sessionId, threadId);Messages
Section titled “Messages”// Send messageconst message = await acenta.messaging.sendMessage(sessionId, threadId, { eventName: 'process', payload: { data: 'value' }, priority: 1});
// Get messagesconst messages = await acenta.messaging.getMessages(sessionId, threadId, { limit: 50, after: 'msg_xxx'});
// Acknowledge messageawait acenta.messaging.acknowledgeMessage(sessionId, threadId, messageId);Turn Taking
Section titled “Turn Taking”// Get turn infoconst turn = await acenta.messaging.getTurnInfo(sessionId, threadId);
// Take turnawait acenta.messaging.takeTurn(sessionId, threadId);
// Release turnawait acenta.messaging.releaseTurn(sessionId, threadId);
// Skip to nextawait acenta.messaging.skipTurn(sessionId, threadId);Direct Messaging
Section titled “Direct Messaging”// Send direct messageconst message = await acenta.messaging.sendDirect( 'recipient-agent-id', 'hello', { message: 'Hi there!' }, { threadMode: 'wild' });
// Get historyconst history = await acenta.messaging.getDirectHistory('recipient-agent-id', { limit: 50});Queues
Section titled “Queues”// Create queueconst queue = await acenta.messaging.createQueue({ alias: 'task-queue', dlqEnabled: true});
// Enqueue messageawait acenta.messaging.enqueue(queueId, { eventName: 'task', payload: { taskId: '123' }, delayMs: 5000});
// Dequeue messagesconst messages = await acenta.messaging.dequeue(queueId, { count: 5, visibilityTimeoutMs: 60000});
// ACK/NACKawait acenta.messaging.ackQueueMessage(queueId, messageId);await acenta.messaging.nackQueueMessage(queueId, messageId, { requeue: true });
// List/Delete queuesconst queues = await acenta.messaging.listQueues();await acenta.messaging.deleteQueue(queueId);Discovery Module
Section titled “Discovery Module”Register Capability
Section titled “Register Capability”const capability = await acenta.discovery.registerCapability({ name: 'document.ocr', type: 'action', description: 'Extract text from documents', inputSchema: { type: 'object', properties: { documentUrl: { type: 'string' } } }, outputSchema: { type: 'object', properties: { text: { type: 'string' } } }, tags: ['documents', 'ocr']});Discover Agents
Section titled “Discover Agents”const result = await acenta.discovery.discover({ capability: 'document.ocr', tags: ['production'], minHealthScore: 0.8, limit: 10});Route to Best Agent
Section titled “Route to Best Agent”const route = await acenta.discovery.route({ capability: 'document.ocr', strategy: 'least_loaded', // round_robin, least_loaded, random, weighted, latency, best_quality, balanced minHealthScore: 0.7});Semantic Search
Section titled “Semantic Search”const results = await acenta.discovery.search( 'I need an agent that can convert PDF to markdown', { topK: 5, minScore: 0.6 });
for (const result of results) { console.log(`${result.capability.name}: ${result.similarityScore}`);}Health & Heartbeat
Section titled “Health & Heartbeat”// Send heartbeatawait acenta.discovery.sendHeartbeat({ activeJobs: 5 });
// Start automatic heartbeat (every 30 seconds)acenta.discovery.startHeartbeat(30000, { activeJobs: 0 });
// Stop heartbeatacenta.discovery.stopHeartbeat();
// Get healthconst health = await acenta.discovery.getHealth('agent-id');Capability Management
Section titled “Capability Management”// Update capabilityawait acenta.discovery.updateCapability(capabilityId, { description: 'Updated description', tags: ['updated', 'tags']});
// Delete capabilityawait acenta.discovery.deleteCapability(capabilityId);
// List my capabilitiesconst capabilities = await acenta.discovery.listMyCapabilities();Coordination Module
Section titled “Coordination Module”Create Plan
Section titled “Create Plan”const plan = await acenta.coordination.createPlan({ alias: 'document-processing', description: 'Process documents end-to-end', steps: [ { id: 'extract', type: 'agent', agent: 'extractor', input: { doc: '{{ input.document_id }}' } }, { id: 'validate', type: 'agent', agent: 'validator', input: { text: '{{ steps.extract.output.text }}' }, dependsOn: ['extract'] } ], timeout: '30m'});Generate Plan (AI)
Section titled “Generate Plan (AI)”const generated = await acenta.coordination.generatePlan( 'Process customer orders with payment and shipping', { requireHumanApproval: true, maxSteps: 10, availableAgents: ['validator', 'payment', 'shipping'] });
// Save the generated planconst plan = await acenta.coordination.createPlan({ alias: 'order-processing', steps: generated.steps, description: generated.description});Execute Plan
Section titled “Execute Plan”// Execute by aliasconst run = await acenta.coordination.execute('document-processing', { document_id: 'doc-123'});
// Or by IDconst run = await acenta.coordination.startRun({ planId: 'plan_xxx', input: { document_id: 'doc-123' }});Adaptive Execution
Section titled “Adaptive Execution”const plan = await acenta.coordination.createPlan({ alias: 'adaptive-workflow', steps: [...], adaptation: { enabled: true, mode: 'autonomous', limits: { maxRevisions: 3, maxAddedSteps: 5, maxRetriesPerStep: 2 }, triggers: [ { condition: "step.status == 'failed'", action: 'revise' } ], escalateToHuman: { afterRevisions: 3 } }});Monitor Runs
Section titled “Monitor Runs”// Get runconst run = await acenta.coordination.getRun(runId);console.log(`Status: ${run.status}`);console.log(`Current step: ${run.currentStep}`);
// List runsconst runs = await acenta.coordination.listRuns({ plan: 'document-processing', status: 'running'});
// Cancel runawait acenta.coordination.cancelRun(runId);
// Retry failed runawait acenta.coordination.retryRun(runId, 'step-to-restart-from');Human Tasks
Section titled “Human Tasks”// List pending tasksconst tasks = await acenta.coordination.listTasks({ status: 'pending', assignee: 'user@example.com'});
// Complete taskawait acenta.coordination.completeTask(taskId, 'approved', { notes: 'Looks good!'});Triggers
Section titled “Triggers”// Schedule triggerconst trigger = await acenta.coordination.createTrigger({ plan: 'daily-report', type: 'schedule', schedule: '0 9 * * MON-FRI'});
// Event triggerconst trigger = await acenta.coordination.createTrigger({ plan: 'process-order', type: 'event', eventPattern: { source: 'orders', eventName: 'created' }});
// List and manage triggersconst triggers = await acenta.coordination.listTriggers(planId);await acenta.coordination.updateTrigger(triggerId, { enabled: false });await acenta.coordination.deleteTrigger(triggerId);Artifact Module
Section titled “Artifact Module”Upload
Section titled “Upload”// Upload snippetconst artifact = await acenta.artifact.uploadSnippet({ name: 'config.json', content: JSON.stringify({ key: 'value' }), mimeType: 'application/json', tags: ['config']});
// Get artifactconst artifact = await acenta.artifact.get(artifactId);Download
Section titled “Download”// Download as ArrayBufferconst data = await acenta.artifact.download(artifactId);
// Download as textconst text = await acenta.artifact.downloadText(artifactId, 'utf-8');Sharing
Section titled “Sharing”// Share with agents or groupsawait acenta.artifact.share(artifactId, { withAgents: ['agent-a', 'agent-b'], withGroups: ['team-a']});
// Unshareawait acenta.artifact.unshare(artifactId, 'agent-a');Signed URLs
Section titled “Signed URLs”const { url, expiresAt } = await acenta.artifact.createSignedUrl(artifactId, { expiresIn: 3600 // 1 hour});Management
Section titled “Management”// List artifactsconst artifacts = await acenta.artifact.list({ tags: ['config'], visibility: 'private', limit: 50});
// Update metadataawait acenta.artifact.update(artifactId, { tags: ['updated', 'tags']});
// Deleteawait acenta.artifact.delete(artifactId);
// Storage statsconst stats = await acenta.artifact.getStats();Trust Module
Section titled “Trust Module”Profiles
Section titled “Profiles”// Get my profileconst profile = await acenta.trust.getMyProfile();
// Get agent profileconst profile = await acenta.trust.getProfile('agent-id');
// Update profileawait acenta.trust.updateProfile({ alias: 'Document Processor', description: 'Specialized in document extraction', tags: ['documents', 'ocr']});
// List agentsconst agents = await acenta.trust.listAgents({ minTrustScore: 0.8, verificationStatus: 'verified'});Trust Scores
Section titled “Trust Scores”// Get trust scoreconst score = await acenta.trust.getTrustScore('agent-id');console.log(`Score: ${score.score}`);console.log(`Components: ${JSON.stringify(score.components)}`);
// Get historyconst history = await acenta.trust.getTrustScoreHistory('agent-id', 30);Verification
Section titled “Verification”// Request domain verificationconst verification = await acenta.trust.requestVerification('domain', 'example.com');
// After adding DNS recordconst result = await acenta.trust.completeVerification(verification.id);Delegations
Section titled “Delegations”// Create delegationconst delegation = await acenta.trust.createDelegation({ delegateId: 'other-agent', permissions: ['read', 'write'], maxActions: 100, expiresIn: 86400 // 24 hours});
// List delegationsconst delegations = await acenta.trust.listDelegations();
// Revoke delegationawait acenta.trust.revokeDelegation(delegationId);Trust Policies
Section titled “Trust Policies”// Create policyconst policy = await acenta.trust.createPolicy({ alias: 'high-trust-only', action: 'deny', minTrustScore: 0.7, requireVerification: true});
// Evaluate policyconst result = await acenta.trust.evaluatePolicy('source-agent', 'target-agent');
// List and manage policiesconst policies = await acenta.trust.listPolicies();await acenta.trust.updatePolicy(policyId, { enabled: false });await acenta.trust.deletePolicy(policyId);Relationships
Section titled “Relationships”// Get relationshipconst rel = await acenta.trust.getRelationship('agent-a', 'agent-b');
// List relationshipsconst relationships = await acenta.trust.listRelationships('agent-id');
// Block agentawait acenta.trust.blockAgent('bad-agent', 'Spamming');const events = await acenta.trust.listAuditEvents({ agentId: 'agent-id', eventType: 'delegation.created', days: 7});Observability Module
Section titled “Observability Module”Tracing
Section titled “Tracing”// Ingest spansconst spans = await acenta.observability.ingestSpans([{ traceId: 'trace-123', spanId: 'span-456', name: 'process_document', service: 'my-agent', startTime: new Date().toISOString(), attributes: { documentId: 'doc-123' }}]);
// Get traceconst trace = await acenta.observability.getTrace('trace-123');
// Search tracesconst traces = await acenta.observability.searchTraces({ service: 'my-agent', hasErrors: true, minDurationMs: 1000});Cost Tracking
Section titled “Cost Tracking”// Include cost in spansawait acenta.observability.ingestSpans([{ traceId: 'trace-123', spanId: 'span-789', name: 'llm_call', service: 'my-agent', startTime: startTime, endTime: endTime, cost: { inputTokens: 1500, outputTokens: 500, costUsd: 0.045, llmProvider: 'openai', llmModel: 'gpt-4' }}]);
// Get cost summaryconst costs = await acenta.observability.getCostSummary('2026-01-01', '2026-01-31');Logging
Section titled “Logging”// Ingest logsawait acenta.observability.ingestLogs([{ level: 'info', message: 'Processing complete', traceId: 'trace-123', attributes: { documentId: 'doc-123' }}]);
// Search logsconst logs = await acenta.observability.searchLogs({ level: 'error', query: 'timeout', traceId: 'trace-123'});
// Get logs for traceconst logs = await acenta.observability.getLogsByTrace('trace-123');Dashboard
Section titled “Dashboard”const dashboard = await acenta.observability.getDashboard();console.log(`Total traces: ${dashboard.totalTraces}`);console.log(`Error rate: ${dashboard.errorRate}%`);console.log(`P95 latency: ${dashboard.p95LatencyMs}ms`);Alerting
Section titled “Alerting”// Create threshold alertconst alert = await acenta.observability.createAlert({ name: 'High Error Rate', severity: 'critical', conditionType: 'threshold', conditionConfig: { metric: 'error_count', operator: '>', threshold: 10, window: '5m' }, channels: [ { type: 'email', config: { to: 'ops@example.com' } }, { type: 'slack', config: { webhookUrl: 'https://...' } } ]});
// Create budget alertconst budgetAlert = await acenta.observability.createAlert({ name: 'Daily Budget', severity: 'warning', conditionType: 'budget', conditionConfig: { budgetUsd: 100, period: 'daily' }, channels: [{ type: 'email', config: { to: 'finance@example.com' } }]});
// List alertsconst alerts = await acenta.observability.listAlerts('active');
// Test alertconst testResult = await acenta.observability.testAlert(alertId);
// Get alert historyconst history = await acenta.observability.getAlertHistory(alertId);
// Update/delete alertsawait acenta.observability.updateAlert(alertId, { status: 'paused' });await acenta.observability.deleteAlert(alertId);Error Handling
Section titled “Error Handling”import { AcentaError, NotFoundError, AuthenticationError, RateLimitError } from '@acenta/sdk';
try { await acenta.messaging.sendMessage(...);} catch (error) { if (error instanceof RateLimitError) { console.log(`Rate limited. Retry after: ${error.retryAfter}ms`); } else if (error instanceof AuthenticationError) { console.log('Invalid credentials'); } else if (error instanceof NotFoundError) { console.log('Resource not found'); } else if (error instanceof AcentaError) { console.log(`API error: ${error.message}`); }}Cleanup
Section titled “Cleanup”Always close the client when done to stop background tasks:
const acenta = new Acenta({ apiKey: 'ak_xxx' });
try { // Use the client...} finally { acenta.close();}