API Overview

The Underlay API is a JSON REST API served at /api. All request and response bodies are JSON (except file uploads/downloads). A machine-readable reference is available at /.well-known/ai.txt.

Base URL

https://underlay.org/api

Authentication

All GET requests are public — no authentication required to read public data. All write requests (POST, PATCH, PUT, DELETE) require authentication.

There are two authentication methods:

API Keys (recommended for scripts & apps)

Pass your key as a Bearer token:

Authorization: Bearer ul_a1b2c3d4e5...

Keys have three scopes:

  • read — list and download data
  • write — push versions, upload files
  • admin — delete collections, manage keys

Keys can optionally be scoped to a single collection. Create keys in your organization settings or via POST /api/accounts/keys.

Session Cookies (browser)

The web UI authenticates via signed session cookies set by POST /api/accounts/login. Sessions expire after 30 days.

Invalid Credentials

If a Bearer token is provided but does not match any key, the request is immediately rejected with 401 — it will not fall through to anonymous access.


Rate Limits

All requests are rate-limited. Authenticated requests get a significantly higher allowance:

Auth status Limit
Unauthenticated (by IP) 60 requests / minute
Authenticated (by account) 5,000 requests / minute

Every response includes rate limit headers:

  • X-RateLimit-Limit — max requests in the current window
  • X-RateLimit-Remaining — requests remaining
  • X-RateLimit-Reset — seconds until the window resets

When you exceed the limit, you'll receive a 429 Too Many Requests response with a Retry-After header indicating how long to wait.

For any automated or scripted access, always use an API key to get the higher rate limit.


Error Responses

Errors return a JSON body with error and statusCode:

{
  "error": "Authentication required",
  "statusCode": 401
}

Common status codes:

  • 400 — Bad request (invalid input)
  • 401 — Authentication required or invalid credentials
  • 403 — Insufficient permissions (wrong scope)
  • 404 — Resource not found
  • 409 — Version conflict (re-fetch and retry)
  • 422 — Validation error (e.g. missing files)
  • 429 — Rate limited (wait and retry)

Endpoints