iato-sdk
v1.0.2
Published
Official TypeScript SDK for the IATO API — website crawling, content governance, and AI-powered information architecture.
Downloads
122
Maintainers
Readme
iato-sdk
Official TypeScript SDK for the IATO API — website crawling, content governance, and AI-powered information architecture.
- Zero dependencies — uses native
fetch(Node 18+) - Fully typed — every endpoint, param, and response has TypeScript types
- Retries & timeouts — exponential backoff on 5xx and 429, configurable limits
- Tree-shakeable — ESM + CJS dual output
Install
npm install iato-sdkQuick Start
import { IATO } from 'iato-sdk';
const iato = new IATO({ apiKey: process.env.IATO_API_KEY! });
// Start a crawl
const job = await iato.crawls.start({
url: 'https://example.com',
workspace_id: 'ws_abc123',
max_pages: 500,
});
// Wait for completion (polls every 5s)
const completed = await iato.crawls.waitForCompletion(job.id);
// Analyze results
const stats = await iato.crawls.stats(completed.id);
const issues = await iato.crawls.seoIssues(completed.id);
const broken = await iato.crawls.brokenLinks(completed.id);
console.log(`Crawled ${stats.total_pages} pages, found ${issues.issues.length} SEO issues`);Configuration
const iato = new IATO({
apiKey: 'your-api-key', // Required
baseUrl: 'https://iato.ai', // Default
timeout: 30000, // 30s default
maxRetries: 2, // Retries on 5xx/429
retryDelay: 1000, // Base delay (exponential backoff)
});Resources
Workspaces
const { workspaces } = await iato.workspaces.list();
const ws = await iato.workspaces.create({ name: 'My Project' });
await iato.workspaces.update(ws.id, { name: 'Renamed' });
const { members } = await iato.workspaces.members(ws.id);
await iato.workspaces.invite(ws.id, { email: '[email protected]', role: 'editor' });
await iato.workspaces.delete(ws.id);Crawls
// Start with full options
const job = await iato.crawls.start({
url: 'https://example.com',
workspace_id: 'ws_123',
max_pages: 5000,
max_depth: 10,
js_rendering: true,
js_wait_time: 3000,
include_screenshots: true,
respect_robots: true,
custom_headers: { 'Accept-Language': 'en-US' },
excluded_paths: ['/admin/*', '/wp-json/*'],
});
// Monitor
const status = await iato.crawls.get(job.id);
console.log(`${status.pages_crawled}/${status.pages_total} pages`);
// Wait and get results
const done = await iato.crawls.waitForCompletion(job.id, 3000, 300_000);
// Pages with filtering
const { pages } = await iato.crawls.pages(done.id, { limit: 100, status_code: 200 });
// Full analysis suite
const stats = await iato.crawls.stats(done.id);
const broken = await iato.crawls.brokenLinks(done.id);
const redirects = await iato.crawls.redirects(done.id);
const duplicates = await iato.crawls.duplicates(done.id);
const seo = await iato.crawls.seoIssues(done.id);
const perf = await iato.crawls.performance(done.id);
const resources = await iato.crawls.resources(done.id);
const structured = await iato.crawls.structuredData(done.id);
// Compare two crawls
const diff = await iato.crawls.compare('job_old', 'job_new');
console.log(`+${diff.summary.added} -${diff.summary.removed} ~${diff.summary.changed}`);
// Export
const csv = await iato.crawls.exportCsv(done.id);
const xml = await iato.crawls.exportSitemap(done.id);Sitemaps & AI Assistant
// Create from crawl
const sitemap = await iato.sitemaps.create({ job_id: job.id, name: 'Current IA' });
// Manage nodes
const { nodes } = await iato.sitemaps.nodes(sitemap.id);
const node = await iato.sitemaps.createNode(sitemap.id, {
title: 'New Section',
type: 'section',
parent_id: nodes[0].id,
});
await iato.sitemaps.updateNode(sitemap.id, node.id, { title: 'Renamed Section' });
// AI Chat — restructure via natural language
const chat = await iato.sitemaps.chat(sitemap.id, {
message: 'Move all blog posts under a /blog/2025/ section',
});
console.log(chat.response);
// If AI generated a plan, review and execute
if (chat.plan) {
const plan = await iato.sitemaps.plan(sitemap.id, chat.plan.id);
console.log(`Plan: ${plan.description}, ${plan.operations.length} operations`);
await iato.sitemaps.executePlan(sitemap.id, plan.id);
// Or: await iato.sitemaps.rejectPlan(sitemap.id, plan.id);
// Undo if needed: await iato.sitemaps.undoPlan(sitemap.id, plan.id);
}
// Quick AI actions
const analysis = await iato.sitemaps.analyze(sitemap.id);
const suggestions = await iato.sitemaps.suggestStructure(sitemap.id);Content Inventory
const { items, total } = await iato.inventory.list(job.id, { limit: 50 });
const invStats = await iato.inventory.stats(job.id);
console.log(`${invStats.total_pages} pages, avg ${invStats.avg_word_count} words`);Navigation
const navStats = await iato.navigation.stats(job.id);
const { menus } = await iato.navigation.detect(job.id);
const validation = await iato.navigation.validate(job.id);Taxonomy Builder
The 5-phase AI taxonomy workflow:
// Phase 1: Extract terms from content
const extracted = await iato.taxonomy.extractTerms(job.id);
await iato.taxonomy.importExtracted(job.id, { terms: extracted.terms });
// Phase 2: AI suggests hierarchy
const { hierarchy } = await iato.taxonomy.suggestHierarchy(job.id);
// Adjust if needed
await iato.taxonomy.setParent(job.id, { term_id: 't1', parent_id: 't2' });
// Phase 3: Auto-classify pages
const { classifications } = await iato.taxonomy.autoClassify(job.id);
// Phase 4: Review
const pending = await iato.taxonomy.pendingClassifications(job.id);
await iato.taxonomy.bulkReview(job.id, {
reviews: pending.classifications.map(c => ({
page_url: c.page_url,
term_id: c.term_id,
action: c.confidence > 0.8 ? 'approve' : 'reject',
})),
});
// Phase 5: Export
const json = await iato.taxonomy.exportJson(job.id);
const csv = await iato.taxonomy.exportCsv(job.id);
const skos = await iato.taxonomy.exportSkos(job.id);Schedules
const schedule = await iato.schedules.create({
name: 'Weekly audit',
url: 'https://example.com',
frequency: 'weekly',
schedule_time: '06:00',
workspace_id: 'ws_123',
});
// Trigger manually
const { job_id } = await iato.schedules.run(schedule.id);Webhooks
const hook = await iato.webhooks.create({
url: 'https://hooks.slack.com/services/xxx',
events: ['crawl.completed', 'crawl.failed', 'changes.detected'],
secret: 'whsec_my_secret',
});
await iato.webhooks.test(hook.id);
// In your webhook handler:
const isValid = await iato.webhooks.verifySignature(
rawBody,
req.headers['x-iato-signature'],
'whsec_my_secret'
);Reports
const report = await iato.reports.generate({ job_id: job.id, type: 'full' });
const pdf = await iato.reports.download(report.id);Authentication & User
const { user } = await iato.auth.me();
const quota = await iato.users.quota();
// Manage API keys
const newKey = await iato.auth.createApiKey({ name: 'CI Pipeline' });
console.log(`Key: ${newKey.key}`); // Only shown onceOrganization
const { users } = await iato.org.members();
await iato.org.invite({ email: '[email protected]', role: 'member' });
const { invitations } = await iato.org.invitations();Health
const status = await iato.health.check();
const detailed = await iato.health.detailed();
const manifest = await iato.health.manifest();Error Handling
All errors extend IATOError with typed subclasses:
import { IATO, AuthenticationError, NotFoundError, RateLimitError, ValidationError } from 'iato-sdk';
try {
await iato.crawls.get('nonexistent');
} catch (error) {
if (error instanceof NotFoundError) {
console.log('Job not found');
} else if (error instanceof AuthenticationError) {
console.log('Bad API key');
} else if (error instanceof RateLimitError) {
console.log(`Rate limited. Retry after ${error.retryAfter}s`);
} else if (error instanceof ValidationError) {
console.log('Invalid params:', error.details);
}
}The SDK automatically retries on 5xx errors and 429s with exponential backoff. Configure via maxRetries and retryDelay.
Advanced
Request Options
Every method accepts an optional RequestOptions parameter:
const controller = new AbortController();
setTimeout(() => controller.abort(), 5000);
const stats = await iato.crawls.stats(jobId, {
timeout: 10000,
signal: controller.signal,
headers: { 'X-Request-Id': 'req_123' },
});Custom HTTP Client
For testing or advanced use, compose resources with a custom HttpClient:
import { HttpClient, Crawls } from 'iato-sdk';
const http = new HttpClient({ apiKey: 'test', baseUrl: 'http://localhost:8000' });
const crawls = new Crawls(http);Binary Downloads
Export methods that return files give you an ArrayBuffer:
import { writeFile } from 'fs/promises';
const csv = await iato.crawls.exportCsv(jobId);
await writeFile('export.csv', Buffer.from(csv));
const skos = await iato.taxonomy.exportSkos(jobId);
await writeFile('taxonomy.rdf', Buffer.from(skos));Requirements
- Node.js 18+ (uses native
fetch) - An IATO API key (get one free)
License
MIT
