@vertaaux/sdk
v1.0.0
Published
Official VertaaUX SDK for Node.js - UX audit and remediation API client
Readme
@vertaaux/sdk
Official TypeScript/JavaScript SDK for the VertaaUX API - UX and accessibility auditing for the modern web.
Installation
npm install @vertaaux/sdk
# or
yarn add @vertaaux/sdk
# or
pnpm add @vertaaux/sdkQuick Start
import { VertaaUX } from '@vertaaux/sdk';
const vertaa = new VertaaUX({
apiKey: process.env.VERTAAUX_API_KEY!
});
// Create an audit
const audit = await vertaa.audits.create({
url: 'https://example.com',
mode: 'standard' // 'basic' | 'standard' | 'deep'
});
console.log('Audit started:', audit.job_id);
// Poll for completion
let result = await vertaa.audits.retrieve(audit.job_id);
while (result.status === 'queued' || result.status === 'running') {
await new Promise(r => setTimeout(r, 5000));
result = await vertaa.audits.retrieve(audit.job_id);
}
console.log('Overall score:', result.scores?.overall);
console.log('Issues found:', result.issues?.length ?? 0);Configuration
const vertaa = new VertaaUX({
apiKey: 'vux_live_...', // Required - your API key
baseUrl: 'https://vertaaux.ai/api/v1', // Optional, default shown
timeout: 30000, // Optional, request timeout in ms (default: 30000)
maxRetries: 2 // Optional, retry attempts for transient failures (default: 2)
});Error Handling
The SDK throws typed errors you can catch specifically:
import {
VertaaUX,
AuthenticationError,
RateLimitError,
ValidationError,
NotFoundError,
PermissionError,
isVertaaUXError
} from '@vertaaux/sdk';
try {
const audit = await vertaa.audits.create({ url: 'invalid' });
} catch (error) {
if (error instanceof AuthenticationError) {
// 401 - Invalid API key
console.error('Invalid API key');
} else if (error instanceof RateLimitError) {
// 429 - Rate limit exceeded
console.log(`Retry after ${error.retryAfter} seconds`);
} else if (error instanceof ValidationError) {
// 400 - Invalid request parameters
console.error('Invalid request:', error.errors);
} else if (error instanceof NotFoundError) {
// 404 - Resource not found
console.error('Resource not found');
} else if (error instanceof PermissionError) {
// 403 - Insufficient permissions or tier limit
console.error('Permission denied:', error.message);
} else if (isVertaaUXError(error)) {
// Generic SDK error - works across SDK versions
console.error(`Request ${error.requestId}: ${error.message}`);
} else {
throw error; // Re-throw unknown errors
}
}Error Classes
| Error | HTTP Status | Description |
|-------|-------------|-------------|
| AuthenticationError | 401 | Invalid or missing API key |
| PermissionError | 403 | Insufficient permissions or tier limit |
| NotFoundError | 404 | Resource not found |
| ValidationError | 400 | Invalid request parameters |
| RateLimitError | 429 | Rate limit exceeded |
| IdempotencyError | 409 | Idempotency key conflict |
| APIError | 5xx | Server error |
| ConnectionError | - | Network failure or timeout |
Auto-Pagination
List endpoints return paginated responses. Use listAutoPaginate() for automatic pagination:
// Iterate through all audits with for-await
for await (const audit of vertaa.audits.listAutoPaginate()) {
console.log(audit.job_id, audit.url, audit.status);
}
// Collect to array with safety limit (prevents OOM)
const recent = await vertaa.audits
.listAutoPaginate({ status: 'completed' })
.toArray({ maxItems: 100 });
// Get first N items
const firstTen = await vertaa.audits.listAutoPaginate().take(10);
// Find first matching item
const failedAudit = await vertaa.audits
.listAutoPaginate()
.find(audit => audit.status === 'failed');
// Check conditions with early termination
const hasFailures = await vertaa.audits
.listAutoPaginate()
.some(audit => audit.status === 'failed');
const allComplete = await vertaa.audits
.listAutoPaginate()
.every(audit => audit.status === 'completed');Automatic Retries
The SDK automatically retries on:
- Rate limit errors (429) - respects
Retry-Afterheader - Server errors (5xx)
- Network failures
Retries use exponential backoff with jitter to prevent thundering herd. Configure via maxRetries option.
API Reference
Audits
Create and manage UX audits.
// Create an audit
const audit = await vertaa.audits.create({
url: 'https://example.com',
mode: 'standard', // 'basic' | 'standard' | 'deep'
metadata: { project: 'q1-redesign' },
fail_on_score: 70, // Optional: fail if score below threshold
});
// Retrieve audit status and results
const result = await vertaa.audits.retrieve(audit.job_id);
// List audits with pagination
const { data, pagination } = await vertaa.audits.list({
limit: 50,
status: 'completed'
});
// Auto-paginate through all audits
for await (const audit of vertaa.audits.listAutoPaginate()) {
console.log(audit.job_id, audit.scores?.overall);
}
// Create audit with LLM-enhanced analysis
const llmAudit = await vertaa.audits.createWithLLM({
url: 'https://example.com',
mode: 'deep'
});Webhooks
Receive notifications when audits complete.
// Register a webhook
const webhook = await vertaa.webhooks.create({
url: 'https://api.example.com/webhooks/vertaa',
secret: 'whsec_your_secret_here' // For HMAC-SHA256 signature verification
});
// List all webhooks
const { webhooks } = await vertaa.webhooks.list();
// Delete a webhook
await vertaa.webhooks.delete(webhook.id);Schedules
Create recurring automated audits.
// Create a weekly schedule
const { schedule } = await vertaa.schedules.create({
url: 'https://example.com',
name: 'Weekly Production Audit',
cronExpression: '0 9 * * 1', // Every Monday at 9am
mode: 'standard',
alertOnFail: true,
alertOnScoreDrop: true,
scoreThreshold: 70,
});
// List all schedules
const { schedules } = await vertaa.schedules.list();
// Get schedule details with recent runs
const details = await vertaa.schedules.retrieve(schedule.id);
// Update a schedule
await vertaa.schedules.update(schedule.id, { enabled: false });
// Delete a schedule
await vertaa.schedules.delete(schedule.id);Quota
Check your API usage and limits.
const quota = await vertaa.quota.retrieve();
console.log(`Plan: ${quota.plan}`);
console.log(`Used: ${quota.credits_used}/${quota.credits_total}`);
console.log(`Remaining: ${quota.credits_remaining}`);
console.log(`Resets: ${quota.reset_date}`);Engines
List available audit engine versions.
const { engines } = await vertaa.engines.list();
// Find the default engine
const defaultEngine = engines.find(e => e.default);
// Check for deprecated engines
engines.filter(e => e.deprecated).forEach(engine => {
console.warn(`Engine ${engine.version} sunset: ${engine.sunset_at}`);
});Patches (AI Remediation)
Generate code patches to fix accessibility issues.
// Get an issue from a completed audit
const audit = await vertaa.audits.retrieve(jobId);
const issue = audit.issues?.[0];
if (issue) {
// Generate a patch
const result = await vertaa.patches.generate({
job_id: audit.job_id,
issue_id: issue.id,
file_content: '<button>Click me</button>',
file_path: 'components/Button.tsx',
});
if (result.success && result.patch) {
console.log('Original:', result.patch.search);
console.log('Fixed:', result.patch.replace);
console.log('Confidence:', result.patch.confidence.label); // HIGH | MEDIUM | LOW
console.log('Classification:', result.patch.classification); // safe-apply | needs-review | manual-required
console.log('Explanation:', result.patch.explanation);
}
}Verification
Test patches before applying them.
// Verify a patch fixes the issue without regressions
const result = await vertaa.verification.run({
patch: {
search: '<button>Click</button>',
replace: '<button aria-label="Submit form">Click</button>',
issue_id: 'iss_missing_label_001',
},
url: 'https://example.com/contact',
selector: 'button.submit',
});
if (result.success && result.verification) {
const { verification } = result;
console.log('Issue fixed:', verification.issue_fixed);
console.log('Score change:', verification.score_delta.delta);
if (verification.regressions.length > 0) {
console.warn('Regressions found:');
verification.regressions.forEach(r => {
console.warn(` ${r.rule_id}: ${r.description}`);
});
}
}TypeScript Support
All types are exported for TypeScript consumers:
import type {
// Audit types
Audit,
AuditCreateParams,
AuditStatus,
AuditMode,
AuditScores,
Issue,
Finding,
EvidenceBundle,
// Schedule types
Schedule,
ScheduleCreateParams,
// Webhook types
Webhook,
WebhookCreateParams,
// Quota types
Quota,
PlanTier,
// Patch types
Patch,
PatchConfidence,
PatchClassification,
// Verification types
VerificationResult,
VerifyParams,
// Pagination types
PaginatedResponse,
Pagination
} from '@vertaaux/sdk';Requirements
- Node.js 18+ (uses native fetch)
- ESM or CommonJS supported
Idempotency
For safe request retries, use idempotency keys:
const audit = await vertaa.audits.create(
{ url: 'https://example.com' },
{ idempotencyKey: 'audit-jan-2026-homepage' }
);
// Retrying with the same key returns the same audit
// Using the same key with different params throws IdempotencyErrorLinks
License
MIT
