Help & Docs

API Getting Started

Authentication, rate limits, and first API call

API Getting Started

Reading time: 10 minutes

Integrate with Atlas programmatically using the REST API. This guide covers authentication, base URL, rate limits, request/response format, error handling, pagination, and webhooks.


Base URL

All API requests use the following base URL:

https://api.atlas-accounting.com/api/v1

For a local or self-hosted instance, the base URL is your instance host with the same prefix — e.g. http://localhost:8000/api/v1.

The API follows REST conventions with JSON request and response bodies.


Authentication

Atlas uses JWT (JSON Web Token) authentication with refresh tokens.

Field naming: the API uses camelCase for all request and response fields (e.g. accessToken, fullName).

Obtaining Tokens

POST /auth/login
Content-Type: application/json

{
  "email": "your@email.com",
  "password": "your-password"
}

Response:

{
  "user": {
    "id": "uuid",
    "email": "your@email.com",
    "firstName": "Your",
    "lastName": "Name",
    "fullName": "Your Name",
    "isActive": true,
    "isEmailVerified": true,
    "lastLoginAt": "2026-01-15T10:30:00Z",
    "createdAt": "2026-01-01T09:00:00Z"
  },
  "organizations": [
    {
      "id": "uuid",
      "name": "Your Organization",
      "subscriptionTier": "starter"
    }
  ],
  "tokens": {
    "accessToken": "eyJhbG...",
    "refreshToken": "eyJhbG...",
    "tokenType": "bearer",
    "expiresIn": 3600,
    "expiresAt": "2026-01-15T11:30:00Z"
  }
}

Using Tokens

Include the access token in the Authorization header:

Authorization: Bearer eyJhbG...

Refreshing Tokens

When the access token expires (after 1 hour):

POST /auth/refresh
Content-Type: application/json

{
  "refreshToken": "eyJhbG..."
}

Rate Limits

Atlas applies rate limiting to protect the platform — most notably on authentication endpoints such as POST /auth/login. When you exceed a limit, the API returns 429 Too Many Requests; back off and retry after a short delay.

Build clients to handle 429 gracefully (exponential backoff). Limits are subject to change and are not exposed as response headers.


Request Format

Content Type

All requests with a body must use:

Content-Type: application/json

Company Context

Most resource endpoints operate within a single company. Pass the company as a company_id query parameter (required on list endpoints), for example GET /api/v1/invoices/?company_id=....


Response Format

Success Responses

{
  "id": "uuid",
  "created_at": "2026-01-15T10:30:00Z",
  "updated_at": "2026-01-15T10:30:00Z",
  ...
}

List Responses

List endpoints return a paged envelope:

{
  "items": [...],
  "total": 150,
  "limit": 100,
  "offset": 0,
  "hasMore": true
}

Error Handling

Error Response Format

Most errors follow RFC 7807 (application/problem+json):

{
  "type": "https://atlas.elegsys.com/errors/forbidden",
  "title": "Forbidden",
  "status": 403,
  "detail": "Admin or owner role required",
  "instance": "/api/v1/webhook-subscriptions/event-types"
}

Validation errors (422) return a detail array, one entry per invalid field:

{
  "detail": [
    {
      "loc": ["body", "amount"],
      "msg": "Input should be greater than 0",
      "type": "greater_than"
    }
  ]
}

HTTP Status Codes

CodeMeaning
200Success
201Created
204No Content (successful deletion)
400Bad Request — invalid input
401Unauthorized — invalid or expired token
403Forbidden — insufficient permissions
404Not Found
409Conflict — duplicate or state conflict
422Validation Error — check the detail array
429Rate Limited — slow down
500Internal Server Error

Pagination

List endpoints use offset-based pagination:

ParameterTypeDefaultDescription
limitinteger100Items per page (maximum varies by endpoint, e.g. 500)
offsetinteger0Number of items to skip

The response envelope includes total, limit, offset, and hasMore so you can page through results. Most endpoints also accept resource-specific filters (e.g. status, customer_id, start_date/end_date).

Example

GET /api/v1/invoices/?company_id=YOUR_COMPANY_ID&limit=25&offset=50

First API Call

Let's fetch the current user's profile:

curl -X GET https://api.atlas-accounting.com/api/v1/auth/me \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response:

{
  "user": {
    "id": "uuid",
    "email": "your@email.com",
    "firstName": "Your",
    "lastName": "Name",
    "fullName": "Your Name",
    "isActive": true,
    "isEmailVerified": true
  },
  "role": "accountant",
  "organization": {
    "id": "uuid",
    "name": "Your Organization",
    "subscriptionTier": "starter"
  },
  "hasPortalAccess": true,
  "resolvedPermissions": ["view_reports", "manage_invoices", "..."],
  "companyAccess": [],
  "departmentAccess": [],
  "locationAccess": []
}

The role is one of owner, admin, accountant, bookkeeper, viewer, or employee, and resolvedPermissions lists the effective permission keys for the current user.


Common Endpoints

EndpointMethodDescription
/auth/meGETCurrent user profile
/companies/GET, POSTList and create companies
/invoices/GET, POSTList and create invoices
/bills/GET, POSTList and create bills
/journal-entries/GET, POSTList and create journal entries
/customers/GET, POSTList and create customers
/vendors/GET, POSTList and create vendors
/accounts/GET, POSTChart of accounts
/reports/profit-lossGETProfit & Loss report
/reports/balance-sheetGETBalance Sheet report

Migrating from QuickBooks? The API also exposes import endpoints under /import/quickbooks/... (customers, vendors, invoices, bills).


Webhooks

Receive real-time notifications when events occur in Atlas.

Setting Up Webhooks

Manage webhooks in the app under Settings > Webhooks (Admin or Owner role required), or via the API at /webhook-subscriptions. To create one:

  1. Go to Settings > Webhooks
  2. Create a subscription and enter:
    • URL — your endpoint that receives webhook events
    • Events — select which events to subscribe to (see GET /webhook-subscriptions/event-types for the live list)
    • Secret — used to verify webhook signatures

Delivery history is available at GET /webhook-subscriptions/{id}/deliveries.

Available Events

EventTriggered When
invoice.createdA new invoice is created
invoice.sentAn invoice is sent to a customer
invoice.approvedAn invoice is approved
invoice.paidAn invoice is fully paid
invoice.overdueAn invoice becomes overdue
invoice.voidedAn invoice is voided
bill.createdA new bill is created
bill.approvedA bill is approved
bill.paidA bill is paid
bill.voidedA bill is voided
payment.receivedA customer payment is recorded
payment.madeA vendor payment is recorded
journal_entry.postedA journal entry is posted
journal_entry.voidedA journal entry is voided
period.closedAn accounting period is closed
period.reopenedAn accounting period is reopened

Webhook Payload

{
  "event": "invoice.paid",
  "timestamp": "2026-01-15T10:30:00Z",
  "data": {
    "id": "uuid",
    "invoiceNumber": "INV-001",
    "amount": 1500.0,
    "currency": "USD",
    "customerId": "uuid"
  }
}

Verifying Signatures

Each webhook delivery includes these headers:

HeaderPurpose
X-Webhook-SignatureHMAC-SHA256 of the payload, signed with your secret
X-Webhook-IdUnique delivery ID
X-Webhook-TimestampWhen the event was sent

Verify a delivery by computing the HMAC-SHA256 of the raw request body using your webhook secret and comparing it to X-Webhook-Signature.


SDKs and Libraries

Official client libraries are planned but not yet published. In the meantime, the API is plain REST/JSON — use any HTTP client (requests, httpx, fetch, axios). The interactive OpenAPI documentation is served at /docs (Swagger UI) on your Atlas instance, with the full machine-readable spec at /openapi.json.


What's Next

  • Get your API tokens by logging in via the API
  • Explore the endpoints in the interactive OpenAPI docs at /docs on your Atlas instance
  • Set up webhooks for real-time event notifications