Features Pricing Blog About
Compare vs Screaming Frog vs Sitebulb vs Slickplan vs Octopus.do vs VisualSitemaps
Use Cases For Agencies Site Migration Content Audit For SEO Pros
Log in Get Started

API Documentation

IATO REST API

Base URL: https://iato.ai/api

✨ API Features

• Visual Sitemap Editor API • AI Sitemap Assistant API • AI Taxonomy Assistant (5-phase wizard) • Taxonomy export (JSON, CSV, SKOS) • Page classification with human review • Navigation AI detection • Content Inventory API • AI Usage Tracking • Role-based permissions

Authentication

Two authentication methods are supported:

# JWT Token (from login)
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

# API Key (recommended for automation)
Authorization: Bearer iato_your_api_key_here

Idempotent Requests

For safe retries on POST/PUT/DELETE, include:

X-Idempotency-Key: unique-request-id-123

Cached responses returned for 24 hours. Check X-Idempotency-Replayed: true header.

TypeScript SDK

Official SDK

The fastest way to integrate with IATO. Zero dependencies, fully typed, with built-in retries and error handling.

npm install iato-sdk

Quick Start

import { IATO } from 'iato-sdk';

const iato = new IATO({
  apiKey: 'iato_your_key_here',
  baseUrl: 'https://iato.ai'
});

// Start a crawl
const job = await iato.crawls.start({
  url: 'https://example.com',
  workspace_id: 'ws_abc123',
  max_pages: 500,
});

// Wait for completion (polls automatically)
const completed = await iato.crawls.waitForCompletion(job.id);

// Get 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);

Available Resources

Resource Description
iato.workspacesCreate, list, update, delete workspaces
iato.crawlsStart crawls, get pages, stats, SEO issues, exports
iato.sitemapsVisual sitemaps, nodes, AI assistant, plans
iato.inventoryContent inventory and statistics
iato.navigationNavigation detection and validation
iato.taxonomyAI taxonomy builder (5-phase wizard)
iato.schedulesRecurring crawl schedules
iato.webhooksWebhook management and signature verification
iato.reportsReport generation and download
iato.authAPI key management
iato.usersQuota and preferences
iato.orgOrganization members and invitations
iato.healthHealth checks and API manifest

Error Handling

import { IATO, NotFoundError, RateLimitError, AuthenticationError } from 'iato-sdk';

try {
  await iato.crawls.get('nonexistent');
} catch (error) {
  if (error instanceof NotFoundError) {
    console.log('Job not found');
  } else if (error instanceof RateLimitError) {
    console.log(`Retry after ${error.retryAfter}s`);
  } else if (error instanceof AuthenticationError) {
    console.log('Invalid API key');
  }
}

Features: Zero dependencies (native fetch), automatic retries with exponential backoff on 5xx/429, full TypeScript types for every endpoint, request cancellation via AbortSignal, and webhook signature verification. Requires Node.js 18+.

Source: npmjs.com/package/iato-sdk

API Discovery

GET /api/manifest

Machine-readable API capabilities. AI orchestrators use this to discover features.

Response includes:

  • All capabilities with inline examples
  • Authentication methods
  • Rate limits and pricing
  • Idempotency configuration
GET /api

API index listing all endpoint categories.

GET /api/user/quota

Check your usage quota before starting crawls.

{
  "pages_remaining": 9500,
  "crawls_remaining": 47,
  "can_start_crawl": true,
  "plan": "pro"
}

Health Check

GET /api/health

Basic health check of all services.

{
  "dashboard": "ok",
  "database": "ok",
  "crawler": "ok",
  "redis": "ok"
}
GET /api/health/detailed

Detailed health with latency and capacity info. Useful for orchestrator decisions.

{
  "status": "healthy",
  "version": "10.1.0",
  "dependencies": {
    "database": {"status": "healthy", "latency_ms": 5},
    "redis": {"status": "healthy", "latency_ms": 2},
    "crawler": {"status": "healthy", "latency_ms": 15}
  },
  "capacity": {
    "active_crawls": 3,
    "max_concurrent_crawls": 10,
    "available_slots": 7
  }
}

Authentication & API Keys

POST /api/auth/login

Login to get JWT token.

{
  "email": "[email protected]",
  "password": "your-password"
}
GET /api/auth/api-keys

List your API keys.

POST /api/auth/api-keys

Create a new scoped API key.

{
  "name": "CI/CD Pipeline",
  "scopes": ["read", "write"],
  "expires_in_days": 90
}

Available Scopes

  • read - View jobs, pages, reports
  • write - Start crawls, create webhooks
  • admin - Manage users, delete resources

⚠️ Important: The API key is only shown once at creation. Save it immediately!

DELETE /api/auth/api-keys/{key_id}

Revoke an API key.

Batch Operations

POST /api/crawl/jobs/batch-delete

Delete multiple jobs at once (max 100).

{
  "job_ids": ["abc123", "def456", "ghi789"]
}
POST /api/crawl/jobs/batch-export

Export multiple jobs at once (max 20).

{
  "job_ids": ["abc123", "def456"],
  "format": "json",
  "scope": "summary"  // or "pages"
}

Webhooks

GET /api/webhooks

List your webhooks.

POST /api/webhooks

Create a webhook to receive event notifications.

{
  "name": "Slack Notification",
  "url": "https://hooks.slack.com/...",
  "events": ["crawl.completed", "crawl.failed"],
  "secret": "optional-hmac-secret"
}

Available Events

crawl.started crawl.progress crawl.completed crawl.failed crawl.cancelled
POST /api/webhooks/{id}/test

Send a test event to verify your webhook endpoint.

DELETE /api/webhooks/{id}

Delete a webhook.

GET /api/webhooks/{webhook_id}

Get webhook details

PUT /api/webhooks/{webhook_id}

Update webhook configuration

GET /api/webhooks/{webhook_id}/history

Get delivery history

WS /api/crawl/jobs/{job_id}/stream

WebSocket endpoint for real-time progress streaming.

// Connect
const ws = new WebSocket('ws://host/api/crawl/jobs/abc123/stream');

// Receive updates
ws.onmessage = (e) => {
  const msg = JSON.parse(e.data);
  // msg.type: "progress" | "complete" | "error"
  // msg.data: { job_id, status, percent_complete, ... }
};

Crawl Jobs

POST /api/crawl/start

Start a new crawl job. All config options default to minimal footprint settings.

Request Body

{
  "url": "https://example.com",
  "workspace_id": 1,
  
  // Basic Settings
  "max_pages": 500,                    // Max internal pages (external links don't count)
  "max_external_links": 0,            // Max external links to check (0 = unlimited)
  "max_depth": 3,
  "delay_ms": 100,
  "timeout_seconds": 30,
  "concurrent_requests": 5,
  "max_redirects": 5,
  
  // Scope Settings
  "crawl_subdomains": false,
  "include_external": true,           // Track external link URLs
  "crawl_external": false,            // Check external links (HEAD request)
  "crawl_outside_start_folder": true,
  "respect_robots_txt": true,
  "store_content": false,             // Store HTML (required for word counts)
  
  // Analysis Settings (all default to false for minimal footprint)
  "seo_analysis": false,
  "performance_metrics": false,
  "detect_duplicates": false,
  "track_redirects": false,
  "extract_hreflang": false,
  "extract_structured_data": false,
  
  // Resource Tracking (all default to false)
  // store_* = Track URLs only, crawl_* = HEAD request to check size
  "store_images": false,   "crawl_images": false,
  "store_css": false,      "crawl_css": false,
  "store_js": false,       "crawl_js": false,
  "store_fonts": false,    "crawl_fonts": false,
  "store_media": false,    "crawl_media": false,
  "store_other": false,    "crawl_other": false,
  
  // URL Filtering
  "include_patterns": [],
  "exclude_patterns": [],
  "remove_parameters": ["utm_source", "utm_medium", "fbclid"],
  
  // Authentication (optional)
  "credential_id": null,
  "formauth_id": null,
  
  // JavaScript Rendering (optional)
  "js_rendering": false,
  "js_browser_type": "chromium",       // chromium, firefox, webkit
  "js_device_preset": "desktop_1080p",
  "js_wait_until": "networkidle",
  
  // Screenshots (optional, requires js_rendering)
  "capture_screenshots": false,
  "screenshot_full_page": false,
  "screenshot_format": "png"
}

Note: Default settings create minimal database footprint (~5-10 MB per 5,000 pages). Enable options as needed for your use case.

Device Presets

Available values for js_device_preset:

desktop_1080p desktop_1440p iphone_14 iphone_14_pro_max ipad_pro pixel_7 samsung_galaxy_s23 googlebot_mobile googlebot_desktop custom

Response

{
  "job_id": "abc12345",
  "status": "started"
}
GET /api/crawl/jobs

List all crawl jobs with pagination and filtering.

Query Parameters

workspace_idFilter by workspace ID
limitResults per page (default: 20, max: 100)
offsetPagination offset (default: 0)
statusFilter by status: pending, running, completed, failed
GET /api/crawl/jobs/{job_id}

Get detailed information about a specific job.

DELETE /api/crawl/jobs/{job_id}

Delete a crawl job and all associated data.

PATCH /api/crawl/jobs/{job_id}

Update crawl job metadata

POST /api/crawl/jobs/{job_id}/recrawl

Start recrawl of existing job

POST /api/crawl/jobs/{job_id}/cancel

Cancel a running crawl

GET /api/crawl/jobs/{job_id}/versions

Get crawl version history

GET /api/crawl/jobs/{job_id}/progress

Get real-time crawl progress

GET /api/crawl/jobs/{job_id}/overview

Get crawl overview dashboard data

GET /api/crawl/jobs/{job_id}/logs

Get crawl execution logs

GET /api/crawl/jobs/deletion-status

Check status of job deletions

Pages & Data

GET /api/crawl/jobs/{job_id}/pages

Get all pages from a crawl job.

Query Parameters

limitResults per page (default: 100)
offsetPagination offset
status_codeFilter by HTTP status (e.g., 200, 404)
is_internalFilter: true/false
searchSearch in URL or title
GET /api/crawl/jobs/{job_id}/pages/{page_id}

Get detailed page data including content, headers, and links.

GET /api/crawl/jobs/{job_id}/stats

Get crawl statistics and metrics.

GET /api/crawl/jobs/{job_id}/pages/{page_id}/html

Get full HTML content of page

GET /api/crawl/jobs/{job_id}/pages/{page_id}/screenshot

Get page screenshot

GET /api/crawl/jobs/{job_id}/pages/{page_id}/thumbnail

Get page thumbnail

GET /api/crawl/jobs/{job_id}/screenshots

List all screenshots for crawl

DELETE /api/crawl/jobs/{job_id}/pages/{page_id}/screenshot

Delete page screenshot

DELETE /api/crawl/jobs/{job_id}/screenshots

Delete all screenshots for crawl

Analysis

GET /api/crawl/jobs/{job_id}/broken-links

Get all broken links (4xx, 5xx status codes).

GET /api/crawl/jobs/{job_id}/redirects

Get redirect chains and final destinations.

GET /api/crawl/jobs/{job_id}/duplicates

Find duplicate titles, descriptions, and content.

GET /api/crawl/jobs/{job_id}/seo-issues

Get SEO issues: missing titles, short descriptions, etc.

GET /api/crawl/jobs/{job_id}/performance

Get page performance metrics (load times, sizes).

GET /api/crawl/jobs/{job_id}/resources

Get discovered resources (images, CSS, JS).

GET /api/crawl/jobs/{job_id}/structured-data

Get Schema.org structured data found on pages.

POST /api/compare

Compare two crawl jobs.

Query params: baseline_job_id, compare_job_id

GET /api/crawl/jobs/{job_id}/hreflang

Get hreflang tag analysis

GET /api/crawl/jobs/{job_id}/sitemaps

Get XML sitemaps found during crawl

GET /api/crawl/jobs/{job_id}/sitemap-coverage

Get sitemap URL coverage analysis

GET /api/crawl/jobs/{job_id}/pagination

Get pagination pattern analysis

GET /api/crawl/jobs/{job_id}/overview/stats

Get comprehensive statistics

GET /api/crawl/jobs/{job_id}/content/thin

Get thin content pages

GET /api/crawl/jobs/{job_id}/content/headings

Get heading structure analysis

GET /api/crawl/jobs/{job_id}/links/internal

Get internal link analysis

GET /api/crawl/jobs/{job_id}/links/external

Get external link analysis

GET /api/crawl/jobs/{job_id}/links/orphan

Get orphan pages (no inlinks)

GET /api/crawl/jobs/{job_id}/technical/indexability

Get indexability report

GET /api/crawl/jobs/{job_id}/technical/robots

Get robots.txt analysis

GET /api/crawl/jobs/{job_id}/technical/canonicals

Get canonical tag analysis

GET /api/crawl/jobs/{job_id}/technical/performance

Get performance metrics

GET /api/crawl/jobs/{job_id}/onpage/titles

Get title tag analysis

GET /api/crawl/jobs/{job_id}/onpage/descriptions

Get meta description analysis

GET /api/crawl/jobs/{job_id}/onpage/images

Get image alt text analysis

GET /api/crawl/jobs/{job_id}/structured-data/summary

Get structured data overview

GET /api/crawl/jobs/{job_id}/structured-data/errors

Get structured data validation errors

GET /api/crawl/jobs/{job_id}/international/hreflang

Get international hreflang report

GET /api/crawl/jobs/{job_id}/issues/all

Get all SEO issues with filtering

Export

GET /api/crawl/jobs/{job_id}/export/csv

Export as CSV.

Query param: scope (all, internal, external, errors)

GET /api/crawl/jobs/{job_id}/export/json

Export as JSON.

Query param: scope (all, internal, external, errors)

GET /api/crawl/jobs/{job_id}/export/sitemap

Export as XML Sitemap.

Audit & Content Review

Content audit workflow with page-level decisions and task assignments.

GET /api/crawl/jobs/{job_id}/audit/stats

Get audit statistics

GET /api/crawl/jobs/{job_id}/audit/pages

Get auditable pages

GET /api/crawl/jobs/{job_id}/audit/page/{page_id}

Get audit details for page

POST /api/crawl/jobs/{job_id}/audit/decision

Submit audit decision

GET /api/crawl/jobs/{job_id}/audit/decisions

Get all audit decisions

GET /api/crawl/jobs/{job_id}/audit/task/{page_id}

Get audit task for page

POST /api/crawl/jobs/{job_id}/audit/task/{page_id}

Update audit task

GET /api/crawl/jobs/{job_id}/audit/export

Export audit results

GET /api/node-task/{node_id}

Get task for sitemap node

POST /api/node-task/{node_id}

Update sitemap node task

POST /api/node-task/bulk

Bulk update node tasks

Suggestions

GET /api/crawl/jobs/{job_id}/suggestions

Get improvement suggestions

POST /api/crawl/jobs/{job_id}/suggestions/generate

Generate new suggestions

POST /api/crawl/jobs/{job_id}/suggestions/{suggestion_id}/apply

Apply suggestion

POST /api/crawl/jobs/{job_id}/suggestions/{suggestion_id}/dismiss

Dismiss suggestion

Sharing

POST /api/shared

Create shared crawl link

GET /api/shared/{share_token}

Access shared crawl data

Visual Sitemaps

Manage visual sitemaps for planning and organizing website structure.

GET /api/sitemaps

List all visual sitemaps in a workspace.

POST /api/sitemaps

Create a new visual sitemap. Body: { name, workspace_id }

GET /api/sitemaps/{sitemap_id}

Get sitemap details including all nodes and hierarchy.

PUT /api/sitemaps/{sitemap_id}

Update sitemap properties.

POST /api/sitemaps/{sitemap_id}/nodes

Create a new node. Body: { title, url, parent_node_id, node_type, status }

PUT /api/sitemaps/{sitemap_id}/nodes/{node_id}

Update node properties. Body fields: title, url, path, status, action (keep, update, review, remove, redirect, merge), redirect_to (destination URL when action is redirect), page_type, assigned_to, category_id, tags, menu_ids, meta_description, target_keywords, notes

DELETE /api/sitemaps/{sitemap_id}/nodes/{node_id}

Delete a node (children become orphans).

PUT /api/sitemaps/{sitemap_id}/nodes/bulk-position

Update positions of multiple nodes. Body: { positions: [{ id, x, y }] }

GET /api/sitemaps/{sitemap_id}/export

Export sitemap as JSON, CSV, standalone HTML, or redirect map.

Query params: format (json, csv, html, redirects, redirects_json), theme (light, dark — HTML only), color (blue, purple, green, red, orange, teal, indigo, pink, cyan, amber, lime, slate — HTML only), redirect_code (301 or 302 — redirects formats only, default: 301)

Redirect Map CSV (format=redirects): Downloads a CSV with columns: Source URL, Destination URL, Status Code, Redirect Type, Chain Length, Notes. Aggregates crawl-detected 3xx chains, content audit redirect decisions, sitemap URL changes, and sitemap nodes marked as redirect.

Redirect Map JSON (format=redirects_json): Returns { redirects: [...], summary: { total, crawl_detected, user_decision, url_changed, node_redirect } }

DELETE /api/sitemaps/{sitemap_id}

Delete sitemap

POST /api/sitemaps/{sitemap_id}/nodes/{node_id}/duplicate

Duplicate sitemap node

POST /api/sitemaps/import

Import sitemap from URL

POST /api/sitemaps/{sitemap_id}/import

Import nodes into sitemap

GET /api/sitemaps/{sitemap_id}/changes

List detected changes

POST /api/sitemaps/{sitemap_id}/detect-changes

Detect changes since last crawl

POST /api/sitemaps/{sitemap_id}/changes/{change_id}/acknowledge

Acknowledge a change

POST /api/sitemaps/{sitemap_id}/changes/bulk-acknowledge

Bulk acknowledge changes

GET /api/sitemaps/{sitemap_id}/users

Get available users for assignment

GET /api/sitemaps/{sitemap_id}/nodes/{node_id}/found-on

Get pages where node URL was found

GET /api/sitemaps/{sitemap_id}/nodes/{node_id}/content

Get node content

GET /api/sitemaps/{sitemap_id}/nodes/{node_id}/seo-data

Get node SEO data

GET /api/sitemaps/{sitemap_id}/nodes/{node_id}/comments

Get node comments

POST /api/sitemaps/{sitemap_id}/nodes/{node_id}/comments

Add comment to node

PUT /api/sitemaps/{sitemap_id}/nodes/{node_id}/comments/{comment_id}

Update comment

DELETE /api/sitemaps/{sitemap_id}/nodes/{node_id}/comments/{comment_id}

Delete comment

GET /api/sitemaps/{sitemap_id}/activity

Get sitemap activity log

GET /api/sitemaps/{sitemap_id}/shares

List sitemap shares

POST /api/sitemaps/{sitemap_id}/shares

Create sitemap share link

PUT /api/sitemaps/{sitemap_id}/shares/{share_id}

Update share settings

DELETE /api/sitemaps/{sitemap_id}/shares/{share_id}

Delete share

GET /api/sitemaps/shared/{share_token}

Access shared sitemap

POST /api/sitemaps/{sitemap_id}/nodes/{node_id}/capture-screenshot

Capture screenshot for node

GET /api/sitemaps/{sitemap_id}/taxonomy

Get sitemap taxonomy

GET /api/sitemaps/{sitemap_id}/menus

Get sitemap navigation menus

POST /api/sitemaps/{sitemap_id}/taxonomy/categories

Create category

PUT /api/sitemaps/{sitemap_id}/taxonomy/categories/{term_id}

Update category

DELETE /api/sitemaps/{sitemap_id}/taxonomy/categories/{term_id}

Delete category

POST /api/sitemaps/{sitemap_id}/taxonomy/tags

Create tag

PUT /api/sitemaps/{sitemap_id}/taxonomy/tags/{tag_id}

Update tag

DELETE /api/sitemaps/{sitemap_id}/taxonomy/tags/{tag_id}

Delete tag

Content Editor

In-browser content editing with version history and AI assistance.

GET /api/sitemaps/{sitemap_id}/content-editor/pages

Get pages for content editing

GET /api/sitemaps/{sitemap_id}/content-editor/{node_id}

Get content for editing

POST /api/sitemaps/{sitemap_id}/content-editor/{node_id}/save

Save content version

GET /api/sitemaps/{sitemap_id}/content-editor/{node_id}/versions

Get content version history

POST /api/sitemaps/{sitemap_id}/content-editor/{node_id}/restore/{version_id}

Restore content version

POST /api/sitemaps/{sitemap_id}/content-editor/bulk-update

Bulk update content

GET /api/sitemaps/{sitemap_id}/content-brief

Get content brief

PUT /api/sitemaps/{sitemap_id}/content-brief

Update content brief

GET /api/sitemaps/{sitemap_id}/content-brief/page/{node_id}

Get page brief override

PUT /api/sitemaps/{sitemap_id}/content-brief/page/{node_id}

Update page brief

DELETE /api/sitemaps/{sitemap_id}/content-brief/page/{node_id}

Delete page brief

AI Sitemap Assistant

Conversational AI for sitemap organization with human-in-the-loop approval.

Note: Requires AI provider configured in Admin → AI Usage & Costs. The main chat endpoint uses Server-Sent Events (SSE) for streaming responses.

Chat

POST /api/sitemaps/{sitemap_id}/ai-assistant

Main chat endpoint (SSE stream). Body: { message, conversation_id? }

Events: thinking, text, plan, done, error

GET /api/sitemaps/{sitemap_id}/ai-assistant/context

Get the context data sent to AI (useful for debugging).

Conversations

GET /api/sitemaps/{sitemap_id}/ai-assistant/conversations

List all conversations for this sitemap.

GET /api/sitemaps/{sitemap_id}/ai-assistant/conversations/{id}

Get a specific conversation with full message history.

DELETE /api/sitemaps/{sitemap_id}/ai-assistant/conversations/{id}

Delete a conversation.

Plans

GET /api/sitemaps/{sitemap_id}/ai-assistant/plans

List all plans for this sitemap.

GET /api/sitemaps/{sitemap_id}/ai-assistant/plans/{plan_id}

Get plan details with operations list.

POST /api/sitemaps/{sitemap_id}/ai-assistant/plans/{plan_id}/execute

Execute a pending plan. Body: { selected_operations?: [0, 1, 2] }

Omit selected_operations to execute all, or pass indices to cherry-pick.

POST /api/sitemaps/{sitemap_id}/ai-assistant/plans/{plan_id}/reject

Reject a pending plan.

POST /api/sitemaps/{sitemap_id}/ai-assistant/plans/{plan_id}/undo

Undo an executed plan (if operations are reversible).

PATCH /api/sitemaps/{sitemap_id}/ai-assistant/plans/{plan_id}

Modify a pending plan (add/remove/update operations).

Quick Actions

POST /api/sitemaps/{sitemap_id}/ai-assistant/quick-actions/analyze

Get AI analysis of sitemap structure and suggestions.

POST /api/sitemaps/{sitemap_id}/ai-assistant/quick-actions/suggest-structure

Get AI suggestions for improving site structure.

GET /api/sitemaps/{sitemap_id}/ai-assistant/plans/scheduled

Get scheduled plans

POST /api/sitemaps/{sitemap_id}/ai-assistant/plans/{plan_id}/schedule

Schedule plan execution

DELETE /api/sitemaps/{sitemap_id}/ai-assistant/plans/{plan_id}/schedule

Cancel scheduled plan

GET /api/sitemaps/{sitemap_id}/ai-assistant/notifications

Get AI notifications

POST /api/sitemaps/{sitemap_id}/ai-assistant/notifications/{notification_id}/read

Mark notification as read

POST /api/sitemaps/{sitemap_id}/ai-assistant/notifications/mark-all-read

Mark all notifications as read

GET /api/sitemaps/{sitemap_id}/ai-assistant/activity

Get AI activity log

POST /api/sitemaps/{sitemap_id}/ai-assistant/seo-audit

Run AI-powered SEO audit

GET /api/sitemaps/{sitemap_id}/ai-assistant/seo-audit/history

Get SEO audit history

GET /api/sitemaps/{sitemap_id}/ai-assistant/templates

List content templates

GET /api/sitemaps/{sitemap_id}/ai-assistant/templates/{template_id}

Get template details

POST /api/sitemaps/{sitemap_id}/ai-assistant/templates

Create content template

POST /api/sitemaps/{sitemap_id}/ai-assistant/templates/{template_id}/apply

Apply template to nodes

GET /api/sitemaps/{sitemap_id}/ai-assistant/analytics/config

Get analytics integration config

GET /api/sitemaps/{sitemap_id}/ai-assistant/analytics/low-performing

Get low-performing pages

POST /api/sitemaps/{sitemap_id}/ai-assistant/analytics/pages

Get page analytics data

GET /api/sitemaps/{sitemap_id}/ai-assistant/suggestions

Get AI improvement suggestions

POST /api/sitemaps/{sitemap_id}/ai-assistant/suggestions/{suggestion_id}/dismiss

Dismiss suggestion

POST /api/sitemaps/{sitemap_id}/ai-assistant/suggestions/{suggestion_id}/accept

Accept and apply suggestion

Content Inventory

GET /api/crawl/jobs/{job_id}/inventory

Get content inventory for a crawl job.

Query params: page, per_page, content_type, status_code, search

GET /api/crawl/jobs/{job_id}/inventory/stats

Get inventory statistics (counts by type, status).

POST /api/crawl/jobs/{job_id}/inventory/sync

Sync inventory from crawl data (rebuilds inventory table).

Navigation

Analyze and manage website navigation structure.

GET /api/crawl/jobs/{job_id}/navigation/stats

Get navigation overview statistics (menus, items, unmapped pages).

POST /api/crawl/jobs/{job_id}/navigation/detect

Run AI detection to identify navigation menus from page content.

GET /api/crawl/jobs/{job_id}/navigation/menus

Get all detected navigation menus with items.

GET /api/crawl/jobs/{job_id}/navigation/validation

Get navigation issues (orphan pages, broken links, duplicates).

POST /api/crawl/jobs/{job_id}/navigation/menus

Create navigation menu

PUT /api/crawl/jobs/{job_id}/navigation/menus/{menu_id}

Update menu

DELETE /api/crawl/jobs/{job_id}/navigation/menus/{menu_id}

Delete menu

GET /api/crawl/jobs/{job_id}/navigation/menus/{menu_id}

Get specific menu

GET /api/crawl/jobs/{job_id}/navigation/items

List navigation items

GET /api/crawl/jobs/{job_id}/navigation/pages

Get pages for navigation assignment

POST /api/crawl/jobs/{job_id}/navigation/items

Create navigation item

PUT /api/crawl/jobs/{job_id}/navigation/items/{item_id}

Update navigation item

DELETE /api/crawl/jobs/{job_id}/navigation/items/{item_id}

Delete navigation item

POST /api/crawl/jobs/{job_id}/navigation/items/reorder

Reorder navigation items

POST /api/crawl/jobs/{job_id}/navigation/items/{item_id}/reorder

Reorder single item

GET /api/crawl/jobs/{job_id}/navigation/page/{page_url}

Get page navigation info

GET /api/crawl/jobs/{job_id}/navigation/labels

Get navigation labels

PUT /api/crawl/jobs/{job_id}/navigation/labels/{item_id}

Update navigation label

GET /api/crawl/jobs/{job_id}/navigation/breadcrumbs

Get breadcrumb trails

GET /api/crawl/jobs/{job_id}/navigation/breadcrumbs/page

Get page breadcrumb

PUT /api/crawl/jobs/{job_id}/navigation/breadcrumbs/page

Update page breadcrumb

GET /api/crawl/jobs/{job_id}/navigation/assigned-pages

Get pages assigned to menus

POST /api/crawl/jobs/{job_id}/navigation/unassign-items

Bulk unassign menu items

POST /api/crawl/jobs/{job_id}/navigation/ai/analyze

AI: Analyze navigation

POST /api/crawl/jobs/{job_id}/navigation/ai/create

AI: Auto-create navigation

GET /api/crawl/jobs/{job_id}/navigation/ai/pages

AI: Get pages for selection

Taxonomy

Build and manage content taxonomies with AI assistance.

Term Management

GET /api/crawl/jobs/{job_id}/taxonomy/terms

Get all taxonomy terms. Query: status, search, page, limit.

POST /api/crawl/jobs/{job_id}/taxonomy/terms

Create a new term. Body: preferred_label, definition, status.

GET /api/crawl/jobs/{job_id}/taxonomy/validate

Validate taxonomy and return issues (missing definitions, duplicates, etc.).

AI Taxonomy Assistant

POST /api/crawl/jobs/{job_id}/taxonomy/ai/extract-terms

Extract terms from crawled content (titles, headings, navigation, URLs).

POST /api/crawl/jobs/{job_id}/taxonomy/ai/import-extracted

Import selected extracted terms into taxonomy.

GET /api/crawl/jobs/{job_id}/taxonomy/ai/hierarchy-tree

Get taxonomy as a nested tree structure.

POST /api/crawl/jobs/{job_id}/taxonomy/ai/suggest-hierarchy

Get AI-suggested parent-child relationships based on term similarity.

POST /api/crawl/jobs/{job_id}/taxonomy/ai/set-parent

Set or remove parent-child relationship. Body: child_term_id, parent_term_id.

Page Classification

POST /api/crawl/jobs/{job_id}/taxonomy/ai/auto-classify

Auto-classify pages by matching content against terms. Body: max_pages, min_confidence.

GET /api/crawl/jobs/{job_id}/taxonomy/ai/pending-classifications

Get classifications pending human review.

POST /api/crawl/jobs/{job_id}/taxonomy/ai/review-classification

Approve, reject, or delete a classification. Body: id, action (approve/reject/delete).

POST /api/crawl/jobs/{job_id}/taxonomy/ai/bulk-review

Bulk approve or reject classifications. Body: ids[], action (approve_all/reject_all).

Export

GET /api/crawl/jobs/{job_id}/taxonomy/ai/export/json

Export taxonomy as JSON. Query: include_drafts (true/false).

GET /api/crawl/jobs/{job_id}/taxonomy/ai/export/csv

Export taxonomy as CSV (spreadsheet format).

GET /api/crawl/jobs/{job_id}/taxonomy/ai/export/skos

Export taxonomy as SKOS RDF/XML (W3C standard).

GET /api/crawl/jobs/{job_id}/taxonomy/stats

Get taxonomy statistics

GET /api/crawl/jobs/{job_id}/taxonomy/tree

Get full taxonomy tree

PUT /api/crawl/jobs/{job_id}/taxonomy/term/{term_id}

Update taxonomy term

DELETE /api/crawl/jobs/{job_id}/taxonomy/term/{term_id}

Delete taxonomy term

POST /api/crawl/jobs/{job_id}/taxonomy/move

Move term to new parent

GET /api/crawl/jobs/{job_id}/taxonomy/export

Export taxonomy (JSON/CSV)

POST /api/crawl/jobs/{job_id}/taxonomy/import

Import taxonomy from file

POST /api/crawl/jobs/{job_id}/taxonomy/import-skos

Import SKOS taxonomy

GET /api/crawl/jobs/{job_id}/taxonomy/changelog

Get taxonomy changelog

GET /api/crawl/jobs/{job_id}/taxonomy/versions

List taxonomy versions

POST /api/crawl/jobs/{job_id}/taxonomy/versions

Create taxonomy version snapshot

DELETE /api/crawl/jobs/{job_id}/taxonomy/versions/{version_id}

Delete taxonomy version

GET /api/crawl/jobs/{job_id}/taxonomy/term/{term_id}/history

Get term change history

GET /api/crawl/jobs/{job_id}/taxonomy/changelog/export

Export changelog

GET /api/crawl/jobs/{job_id}/taxonomy/governance/stats

Get governance statistics

POST /api/crawl/jobs/{job_id}/taxonomy/governance/bulk-status

Bulk change term status

POST /api/crawl/jobs/{job_id}/taxonomy/term/{term_id}/status

Change individual term status

GET /api/crawl/jobs/{job_id}/taxonomy/tags

List taxonomy tags

POST /api/crawl/jobs/{job_id}/taxonomy/tag

Create taxonomy tag

PUT /api/crawl/jobs/{job_id}/taxonomy/tag/{tag_id}

Update taxonomy tag

DELETE /api/crawl/jobs/{job_id}/taxonomy/tag/{tag_id}

Delete taxonomy tag

POST /api/crawl/jobs/{job_id}/taxonomy/term/{term_id}/tags

Assign tags to term

GET /api/crawl/jobs/{job_id}/taxonomy/term/{term_id}/tags

Get tags for term

GET /api/crawl/jobs/{job_id}/taxonomy/term/{term_id}/relationships

Get term relationships

POST /api/crawl/jobs/{job_id}/taxonomy/term/{term_id}/synonym

Add term synonym

POST /api/crawl/jobs/{job_id}/taxonomy/term/{term_id}/related

Add related term

POST /api/crawl/jobs/{job_id}/taxonomy/term/{term_id}/use-for

Add use-for relationship

DELETE /api/crawl/jobs/{job_id}/taxonomy/relationship/{relationship_id}

Delete relationship

GET /api/crawl/jobs/{job_id}/taxonomy/thesaurus

Get taxonomy thesaurus view

GET /api/crawl/jobs/{job_id}/taxonomy/ai/detect-industry

AI: Detect site industry

GET /api/crawl/jobs/{job_id}/taxonomy/ai/bartoc/search

AI: Search BARTOC vocabularies

GET /api/crawl/jobs/{job_id}/taxonomy/ai/bartoc/preview

AI: Preview BARTOC vocabulary

POST /api/crawl/jobs/{job_id}/taxonomy/ai/bartoc/import

AI: Import BARTOC vocabulary

GET /api/crawl/jobs/{job_id}/taxonomy/ai/starter-taxonomies

AI: List starter taxonomies

POST /api/crawl/jobs/{job_id}/taxonomy/ai/import-starter

AI: Import starter taxonomy

GET /api/crawl/jobs/{job_id}/taxonomy/ai/standard-vocabularies

AI: List standard vocabularies

GET /api/crawl/jobs/{job_id}/taxonomy/ai/vocab-types

AI: Get vocabulary types

POST /api/crawl/jobs/{job_id}/taxonomy/ai/import-standard

AI: Import standard vocabulary

POST /api/crawl/jobs/{job_id}/taxonomy/ai/import-skos

AI: Import SKOS file

GET /api/crawl/jobs/{job_id}/taxonomy/ai/classification-stats

AI: Get classification statistics

GET /api/crawl/jobs/{job_id}/taxonomy/ai/page-classifications

AI: Get page classifications

GET /api/crawl/jobs/{job_id}/taxonomy/ai/export/stats

AI: Get export statistics

Workspaces

GET /api/workspaces

List all workspaces for the current user.

POST /api/workspaces

Create a new workspace.

{
  "name": "My Workspace",
  "description": "Optional description",
  "visibility": "private"
}
GET /api/workspaces/{workspace_id}

Get workspace details.

PUT /api/workspaces/{workspace_id}

Update workspace name, description, or visibility.

DELETE /api/workspaces/{workspace_id}

Delete a workspace (owner only).

GET /api/workspaces/{workspace_id}/members

List workspace members and their roles.

POST /api/workspaces/{workspace_id}/invite

Invite a user to the workspace.

{
  "email": "[email protected]",
  "role": "member"
}

Schedules

GET /api/schedules

List all scheduled jobs.

POST /api/schedules

Create a new schedule.

{
  "name": "Daily Crawl",
  "url": "https://example.com",
  "cron_expression": "0 2 * * *",
  "timezone": "UTC",
  "config": {"max_pages": 100}
}
PUT /api/schedules/{schedule_id}

Update schedule (pause/resume with is_active param).

POST /api/schedules/{schedule_id}/run

Trigger schedule to run immediately.

DELETE /api/schedules/{schedule_id}

Delete a schedule.

GET /api/schedules/{schedule_id}

Get schedule details

POST /api/schedules/{schedule_id}/toggle

Toggle schedule active/inactive

GET /api/schedules/{schedule_id}/history

Get schedule run history

POST /api/schedules/cleanup-orphans

Clean up orphaned schedule jobs

Reports

GET /api/reports

List generated reports.

POST /api/reports/generate

Generate a new report.

{
  "job_id": 1,
  "report_type": "summary",  // summary, detailed, audit
  "output_format": "html"    // html, pdf, csv, json, xlsx
}
GET /api/reports/{report_id}/download

Download a generated report as HTML or PDF file.

Returns: Streaming file download with Content-Disposition header

Authentication

POST /api/auth/register

Register a new user and organization.

{
  "email": "[email protected]",
  "password": "securepassword",
  "org_name": "My Company",
  "name": "John Doe"
}
POST /api/auth/login

Login and receive JWT token.

{
  "email": "[email protected]",
  "password": "securepassword"
}

Response

{
  "access_token": "eyJhbG...",
  "user": {"id": 1, "email": "...", "name": "..."}
}
GET /api/auth/me

Get current user info. Requires Authorization header with JWT token.

Header: Authorization: Bearer <token>

User Preferences

GET /api/user/preferences

Get current user's theme preferences.

Response

{
  "theme_color": "blue",
  "text_size": 100,
  "theme_mode": "light"
}
POST /api/user/preferences

Save user's theme preferences.

{
  "theme_color": "purple",   // blue, purple, green, red, orange, teal, indigo, pink, cyan, amber, lime, slate
  "text_size": 110,          // 80-120
  "theme_mode": "dark"       // light, dark, system
}

Settings & Configuration

Credentials (HTTP Basic Auth)

GET /api/credentials

List saved credentials.

POST /api/credentials
{
  "name": "Staging Server",
  "domain_pattern": "staging.example.com",
  "username": "admin",
  "password": "secret"
}
GET /api/credentials/{cred_id}

Get a specific credential by ID.

DELETE /api/credentials/{cred_id}

Delete a saved credential.

Form Authentication

GET /api/form-auth

List form authentication configs.

POST /api/form-auth
{
  "name": "Admin Login",
  "login_url": "https://example.com/login",
  "username_field": "email",
  "password_field": "password",
  "username": "[email protected]",
  "password": "secret"
}
DELETE /api/form-auth/{config_id}

Delete a form authentication configuration.

Extraction Rules

Create CSS, XPath, or regex rules to extract structured data from crawled pages. Attach rules to crawls via extraction_rule_ids in the crawl config.

GET /api/extraction-rules

List all extraction rules. Returns { rules: [...], count }.

GET /api/extraction-rules/{rule_id}

Get a single extraction rule by ID.

POST /api/extraction-rules

Create an extraction rule.

{
  "name": "Product Prices",
  "rule_type": "css",              // css, xpath, regex
  "selector": ".product-price",
  "target": "text",                // text, html, attribute, count
  "target_attribute": null,        // required when target = "attribute"
  "description": "Extract prices from product pages",
  "required": false,               // fail page if extraction fails?
  "default_value": null,           // fallback if extraction fails
  "match_all": false,              // all matches or first only
  "regex_group": 0                 // capture group for regex rules
}
PUT /api/extraction-rules/{rule_id}

Update an extraction rule. Send only the fields you want to change.

DELETE /api/extraction-rules/{rule_id}

Delete an extraction rule.

POST /api/extraction-rules/test

Test an extraction rule against a live URL without saving it.

{
  "url": "https://example.com/product/123",
  "rule": {
    "rule_type": "css",
    "selector": ".product-price",
    "target": "text"
  }
}

Extracted Data (per crawl)

GET /api/crawl/jobs/{job_id}/extracted-data

Retrieve data extracted by custom rules during a crawl. Returns results grouped by field name with success/failure counts.

Query Parameters:

  • field_name — Filter by specific field (optional)
  • limit — Max results, default 100, max 500
  • offset — Pagination offset, default 0
// Response
{
  "data": [
    {
      "page_url": "https://example.com/product/1",
      "rule_name": "Product Prices",
      "field_name": "price",
      "extracted_value": "$29.99",
      "extraction_success": true
    }
  ],
  "count": 42,
  "by_field": {
    "price": { "count": 42, "success": 40 },
    "title": { "count": 42, "success": 42 }
  }
}

Organization & Team

GET /api/org/users

List users in organization.

POST /api/org/users/invite
{
  "email": "[email protected]",
  "role": "member"  // owner, admin, member, viewer
}
GET /api/org/invitations

List pending invitations.

DELETE /api/org/users/{user_id}

Remove user from organization.

PUT /api/org/users/{user_id}/roles

Update user roles.

DELETE /api/org/invitations/{invite_id}

Revoke invitation.

POST /api/org/invitations/{invite_id}/resend

Resend invitation email.

POST /api/org/leave

Leave organization.

GET /api/org/seats

Get seat usage and limits.

POST /api/org/seats/add

Add paid seats.

POST /api/org/seats/remove

Remove paid seats.

GET /api/invitations/{token}/info

Get invitation details.

GET /api/invitations/pending

Get pending invitations for user.

POST /api/invitations/{token}/accept

Accept invitation.

POST /api/invitations/{token}/decline

Decline invitation.

Error Handling

Standard Response Format

All responses use a consistent format:

{
  "success": true | false,
  "data": { ... } | null,
  "error": null | {
    "code": "ERROR_CODE",
    "message": "Human-readable message",
    "details": { ... },
    "suggestions": ["Try this", "Or this"],
    "retryable": true | false,
    "retry_strategy": {
      "retry_after_seconds": 30,
      "max_retries": 3,
      "backoff_multiplier": 2.0,
      "retry_schedule": [30, 60, 120]
    }
  },
  "meta": {
    "request_id": "uuid",
    "timestamp": "2026-01-14T00:00:00Z",
    "api_version": "10.1.0"
  },
  "_actions": {
    "next_action": {"method": "POST", "href": "/api/..."}
  }
}

HTTP Status Codes

Code Error Code Description
200-Success
201-Created
400BAD_REQUESTInvalid parameters
401UNAUTHORIZEDMissing or invalid token
403FORBIDDENInsufficient permissions
404NOT_FOUNDResource doesn't exist
422VALIDATION_ERRORRequest validation failed
429RATE_LIMITEDToo many requests (retryable)
500INTERNAL_ERRORUnexpected server error

Rate Limit Headers

Header Description
X-RateLimit-LimitMaximum requests per minute (60)
X-RateLimit-RemainingRequests remaining in window
X-RateLimit-ResetUnix timestamp when window resets
Retry-AfterSeconds to wait (on 429 response)

Retry Strategy

When error.retryable is true, use the provided retry strategy:

"retry_strategy": {
  "retry_after_seconds": 30,     // Initial wait
  "max_retries": 3,              // Don't retry more than this
  "backoff_multiplier": 2.0,     // Double wait each retry
  "retry_schedule": [30, 60, 120] // Pre-calculated waits
}

Advanced Authentication

Advanced authentication including MFA, OAuth, and account management.

POST /api/auth/register

Register new user account.

POST /api/auth/logout

Logout and invalidate session.

GET /api/auth/verify-email

Verify email address via token.

POST /api/auth/forgot-password

Request password reset email.

POST /api/auth/reset-password

Reset password with token.

GET /api/auth/oauth/{provider}

Redirect to OAuth provider (google, github).

GET /api/auth/oauth/google/callback

Google OAuth callback.

GET /api/auth/oauth/github/callback

GitHub OAuth callback.

PUT /api/auth/profile

Update user profile.

PUT /api/auth/password

Change current password.

POST /api/auth/api-key

Create new API key.

GET /api/auth/notifications

Get notification preferences.

PUT /api/auth/notifications

Update notification preferences.

GET /api/auth/mfa/status

Get MFA enrollment status.

POST /api/auth/mfa/setup

Start MFA setup (generates QR code).

POST /api/auth/mfa/verify-setup

Complete MFA setup with TOTP code.

DELETE /api/auth/mfa

Disable MFA.

POST /api/auth/mfa/verify

Verify MFA code during login.

POST /api/auth/mfa/email-code

Send MFA verification code via email.

POST /api/auth/mfa/backup-codes/regenerate

Regenerate backup codes.

PUT /api/auth/mfa/org-enforcement

Set organization MFA enforcement policy.

GET /api/auth/mfa/trusted-devices

List trusted devices.

DELETE /api/auth/mfa/trusted-devices/{device_id}

Remove trusted device.

DELETE /api/auth/account

Delete user account.

SSO / SAML

Single Sign-On configuration for team and enterprise plans.

GET /api/sso/providers

List available SSO providers.

GET /api/sso/connections

List SSO connections for organization.

POST /api/sso/connections

Create new SSO connection.

GET /api/sso/connections/{connection_id}

Get SSO connection details.

PUT /api/sso/connections/{connection_id}

Update SSO connection.

DELETE /api/sso/connections/{connection_id}

Delete SSO connection.

POST /api/sso/connections/{connection_id}/test

Test SSO configuration.

GET /api/sso/connections/{connection_id}/metadata

Get SAML service provider metadata.

Autopilot & Governance

Automated content governance policies, change queue management, and activity logging.

GET /api/autopilot/{workspace_id}/policy

Get governance policy for workspace.

PUT /api/autopilot/{workspace_id}/policy

Create or update governance policy.

GET /api/autopilot/{workspace_id}/queue

List queued governance changes.

POST /api/autopilot/queue/{change_id}/approve

Approve a queued change.

POST /api/autopilot/queue/{change_id}/reject

Reject a queued change.

POST /api/autopilot/queue/{change_id}/mark-fixed

Mark change as manually fixed.

POST /api/autopilot/queue/{change_id}/rollback

Rollback an applied change.

POST /api/autopilot/batch/{batch_id}/approve

Bulk approve entire batch.

POST /api/autopilot/batch/{batch_id}/reject

Bulk reject entire batch.

POST /api/autopilot/batch/{batch_id}/mark-fixed

Bulk mark batch as fixed.

POST /api/autopilot/batch/{batch_id}/rollback

Rollback entire batch.

GET /api/autopilot/{workspace_id}/activity

Query governance activity log.

GET /api/autopilot/activity/batch/{batch_id}

Get activity for specific batch.

WordPress Integration

Connect WordPress sites for bidirectional content sync, SEO fixes, and governance.

GET /api/wordpress/{workspace_id}/connections

List WordPress connections.

POST /api/wordpress/{workspace_id}/connect

Register new WordPress site.

PUT /api/wordpress/{workspace_id}/connections/{connection_id}

Update connection settings.

DELETE /api/wordpress/{workspace_id}/connections/{connection_id}

Disconnect WordPress site.

POST /api/wordpress/{workspace_id}/connections/{connection_id}/test

Test connectivity.

POST /api/wordpress/{workspace_id}/test-connection

Test connection before saving.

GET /api/wordpress/{workspace_id}/connections/{connection_id}/sync-history

Get sync history.

POST /api/wordpress/sync/pages

Push pages/posts from WordPress.

POST /api/wordpress/sync/menus

Push navigation menus from WordPress.

POST /api/wordpress/sync/taxonomy

Push categories/tags from WordPress.

POST /api/wordpress/{workspace_id}/connections/{connection_id}/pull

Pull content from WordPress.

POST /api/wordpress/{workspace_id}/connections/{connection_id}/push-navigation

Push navigation to WordPress.

POST /api/wordpress/{workspace_id}/connections/{connection_id}/push-taxonomy

Push taxonomy to WordPress.

POST /api/wordpress/{workspace_id}/connections/{connection_id}/push-pages

Push pages to WordPress.

POST /api/wordpress/{workspace_id}/connections/{connection_id}/test-mcp-tool

Test MCP tool on WordPress.

Billing & Subscriptions

Subscription management, usage tracking, spending caps, and prepaid credits.

GET /api/billing/pricing

Get available pricing plans.

GET /api/subscription/status

Get current subscription details.

POST /api/subscription/checkout

Create Stripe Checkout session.

POST /api/subscription/change

Change subscription plan (upgrade/downgrade).

POST /api/subscription/cancel

Cancel subscription at end of period.

POST /api/subscription/reactivate

Undo pending cancellation.

GET /api/billing/invoices

Get Stripe invoices.

POST /api/billing/portal-session

Open Stripe Customer Portal.

GET /api/billing/usage

Get current billing period usage.

GET /api/billing/usage/history

Get usage history across periods.

GET /api/billing/spending-cap

Get spending cap status.

PUT /api/billing/spending-cap

Set or update spending cap.

GET /api/billing/credits/bundles

List available credit bundles.

GET /api/billing/credits/balance

Get credit balance.

POST /api/billing/credits/purchase

Purchase credits via Stripe.

GET /api/billing/credits/history

Get credit purchase history.

GET /api/billing/cost-estimate

Estimate costs for current period.

GET /api/user/tier

Get current subscription tier.

GET /api/user/quota

Get usage quota and limits.

GET /api/user/downgrade-eligibility

Check downgrade eligibility.

Integrations

Connect Google Analytics and Google Search Console for enriched crawl data.

GET /api/integrations/{workspace_id}

List integration status.

GET /api/integrations/{workspace_id}/oauth/url

Generate Google OAuth consent URL.

GET /api/integrations/oauth/callback

OAuth callback (token exchange).

POST /api/integrations/{workspace_id}/connect

Save OAuth tokens.

DELETE /api/integrations/{workspace_id}/{provider}

Disconnect integration.

GET /api/integrations/{workspace_id}/analytics

Fetch GA + GSC data for URLs.

GET /api/integrations/{workspace_id}/google/properties

List GA4 properties.

GET /api/integrations/{workspace_id}/google/sites

List Search Console sites.

POST /api/integrations/{workspace_id}/select-property

Save selected GA/GSC property.