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
🌐 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
📦 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
🦀 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
🧩 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-sdkfor building workers - Direct invocation —
POST /api/actions/:namefor callable actions
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.
# 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
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 # buildAuthentication
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.
# 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:
// REST error (e.g. 401, 403, 404, 409, 500)
{ "error": "authentication required" }
{ "error": "not found" }
{ "error": "lease lost" }GraphQL errors carry codes in extensions:
{ "errors": [{ "message": "...", "extensions": { "code": "NOT_FOUND" } }] }Extension codes: NOT_FOUND, UNAUTHORIZED, FORBIDDEN, VALIDATION_ERROR, INTERNAL_ERROR.
TypeScript SDK example:
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 (default100)RATE_LIMIT_WINDOW_SECS— window length in seconds (default60)
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:
{ "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
- 📖 Guides - Step-by-step tutorials
- 🐛 GitHub Issues - Bug reports
- 💬 GitHub Discussions - Questions and discussion