Skip to content

API Reference ​

Welcome to the Atomo API documentation. This section provides comprehensive reference material for all Atomo APIs and interfaces.

Overview ​

Atomo provides multiple API layers to suit different development needs:

🖥️ CLI Commands ​

The atomo command-line interface is your primary development tool:

  • Project management - Initialize, build, and deploy projects
  • Development workflow - Hot reload, code generation, and testing
  • Database operations - Migrations, seeding, and schema management

→ CLI Reference

🌐 GraphQL API ​

Auto-generated GraphQL APIs from your TypeScript schemas:

  • Type-safe queries - Fully typed operations
  • Real-time subscriptions - Live data updates
  • Automatic CRUD - Generated operations for all models
  • Custom resolvers - Business logic hooks

→ GraphQL Schema

📦 TypeScript SDK ​

Type-safe client library for frontend applications:

  • React hooks - scaffolding for React applications
  • Caching - query caching and invalidation
  • Offline queue - experimental, not yet integration-tested

→ TypeScript SDK

🦀 Rust APIs ​

Core platform APIs for advanced customization:

  • Event sourcing - Event store and stream management
  • Authentication - User management and authorization
  • Actions & workers — event-triggered automation and external worker SDK
  • Content management - Rich content and block APIs

→ Rust APIs

🧩 Actions & Workers ​

Event-triggered automation and external worker interfaces:

  • Actions — event handlers with conditions, enqueue durable jobs
  • Workers — external TypeScript processes that lease jobs via HTTP
  • Typed SDK — @atomo-cc/worker-sdk for building workers
  • Direct invocation — POST /api/actions/:name for callable actions

→ Workers Guide

Storage lifecycle diagnostics ​

Administrators can inspect cache metrics, model-history coverage and audit usage through the read-only GET /storage/diagnostics. Saving/retention policies are deployment configuration; this endpoint cannot delete data or reset history.

Quick Reference ​

The service API is model-generic: operations take a model argument plus JSON data/where/orderBy payloads (there is no per-model typed client today). Send these as GraphQL operations to /graphql.

graphql
# Create a contact
mutation { create(model: "Contact", data: { firstName: "John", lastName: "Doe", email: "john@example.com" }) }

# Query with a filter (records/paginatedRecords exclude soft-deleted rows)
query {
  records(model: "Contact", where: { email: { contains: "@example.com" } }, orderBy: { createdAt: "DESC" })
}

# Subscribe to model changes (WebSocket at /graphql/ws)
subscription { modelChanges(model: "Contact") { eventType modelName eventId } }

See GraphQL API for the full operation set, where operators, and the soft-delete lifecycle.

For the ephemeral real-time tier — presence, live fan-out, "who's-typing" — connect a WebSocket to /realtime/ws?token=<jwt> and exchange JSON frames ({"op":"subscribe","channel":"deal:42"}, {"op":"publish",…}). This traffic is never event-sourced; see Realtime Channels & Presence for the protocol and boundary. Durable data changes stay on GraphQL Subscriptions above.

CLI Quick Commands ​

bash
atomo dev                              # dev runtime (codegen + server + hot reload)
atomo migrate                          # apply migrations
atomo migrate --generate --name <name> # generate a migration from schema changes
atomo build                            # build

Authentication ​

The GraphQL API is protected: obtain a JWT via POST /auth/login, then send it as Authorization: Bearer <token> on each request. RBAC is enforced per model from the schema's access rules.

bash
# Log in to get a token
curl -s -X POST http://localhost:3000/auth/login \
  -H 'content-type: application/json' \
  -d '{"email":"admin@example.com","password":"..."}'   # -> { "token": "<jwt>" }

# Use it on GraphQL requests
curl -s -X POST http://localhost:3000/graphql \
  -H "authorization: Bearer <jwt>" -H 'content-type: application/json' \
  -d '{"query":"{ records(model: \"Contact\") }"}'

An admin user is seeded on first boot from ADMIN_EMAIL/ADMIN_PASSWORD (see Configuration). For multi-tenant scoping, also send X-Tenant-ID: <id>.

Error Handling ​

All REST and GraphQL error responses return a JSON body with an error field:

json
// REST error (e.g. 401, 403, 404, 409, 500)
{ "error": "authentication required" }
{ "error": "not found" }
{ "error": "lease lost" }

GraphQL errors carry codes in extensions:

json
{ "errors": [{ "message": "...", "extensions": { "code": "NOT_FOUND" } }] }

Extension codes: NOT_FOUND, UNAUTHORIZED, FORBIDDEN, VALIDATION_ERROR, INTERNAL_ERROR.

TypeScript SDK example:

typescript
try {
  const contact = await atomo.contacts.create(data)
} catch (error) {
  if (error.code === 'VALIDATION_ERROR') {
    console.log('Validation errors:', error.details)
  } else if (error.code === 'PERMISSION_DENIED') {
    console.log('Access denied:', error.message)
  } else {
    console.log('Unexpected error:', error)
  }
}

Rate Limiting ​

The server applies a per-IP token-bucket rate limiter (in-memory). It is configurable via environment variables:

  • RATE_LIMIT_RPS — max requests per window (default 100)
  • RATE_LIMIT_WINDOW_SECS — window length in seconds (default 60)

Client identity: the X-Forwarded-For header (first hop) when present, else the real peer address. A spoofed X-Forwarded-For can mint fresh buckets on a directly-exposed server — set ATOMO_TRUST_X_FORWARDED_FOR=false when not behind a trusted proxy to rate-limit on the peer address instead.

Requests over the limit receive 429 Too Many Requests with a Retry-After header and a JSON body:

json
{ "error": "rate_limited", "retryAfter": 42 }

Exempted paths: /auth/*, /health, and /ready are never rate-limited.

Versioning ​

Atomo is pre-1.0; APIs may change between releases. There is no hosted API service yet — you run atomo-server yourself (see Getting Started).

Support ​

Released under the AGPL-3.0 License.