Amba

Developer Auth

Signup, login, token refresh, logout, and current-developer lookup.

The control plane owns developer credentials (not Supabase). All state — developers and developer_sessions — lives in the control-plane Neon database. Passwords are hashed with pgcrypto bcrypt (crypt(pw, gen_salt('bf', 10))). Refresh tokens are stored as sha256 hashes so a DB dump can't replay them.

Source: apps/api/src/routes/auth/developer.ts.

Rate limits

Per-IP, two-tier (fast + daily):

RoutePer minutePer day
POST /auth/developer/signup550
POST /auth/developer/login10100
POST /auth/developer/refresh30

/logout and /me are not rate-limited beyond the global gateway defaults.

POST /auth/developer/signup

Create a new developer and return an access + refresh token pair.

Request

POST /auth/developer/signup
Content-Type: application/json
FieldTypeRequiredDescription
emailstringyesUnique email address.
passwordstringyesMinimum 8 characters. Bcrypt-hashed server-side.
namestringnoDisplay name.

Response 201

{
  "data": {
    "access_token": "eyJ…",
    "refresh_token": "eyJ…",
    "developer": {
      "id": "…",
      "email": "…",
      "name": "…",
      "oauth_providers": [],
      "created_at": "…",
      "updated_at": "…"
    }
  }
}

Errors

  • 400 INVALID_INPUT — missing email or password.
  • 400 WEAK_PASSWORD — password is shorter than 8 characters.
  • 409 EMAIL_EXISTS — email already registered.
  • 429 — rate limited.
  • 500 CREATE_FAILED — database error. Inspect server logs.

Try it:

POST/auth/developer/signup
public auth
curl -X POST 'https://api.amba.dev/auth/developer/signup'

Curl:

curl -X POST '${BASE_URL}/auth/developer/signup' \
  -H 'Content-Type: application/json' \
  -d '{}'

POST /auth/developer/login

Exchange email + password for tokens.

Request

POST /auth/developer/login
Content-Type: application/json
FieldTypeRequired
emailstringyes
passwordstringyes

Response 200

{
  "data": {
    "access_token": "eyJ…",
    "refresh_token": "eyJ…",
    "developer": {
      "id": "…",
      "email": "…",
      "name": "…",
      "oauth_providers": [],
      "created_at": "…",
      "updated_at": "…"
    }
  }
}

Errors

  • 400 INVALID_INPUT — missing email or password.
  • 401 INVALID_CREDENTIALS — wrong email or password. (Generic on purpose — never leak whether the email exists.)
  • 429 — rate limited.
  • 500 LOGIN_FAILED.

Try it:

POST/auth/developer/login
public auth
curl -X POST 'https://api.amba.dev/auth/developer/login'

Curl:

curl -X POST '${BASE_URL}/auth/developer/login' \
  -H 'Content-Type: application/json' \
  -d '{}'

POST /auth/developer/refresh

Rotate the refresh token. The old session is revoked and a new access + refresh pair are issued. If the same refresh token is presented twice the second call fails — that's how we detect token theft.

Request

POST /auth/developer/refresh
Content-Type: application/json
FieldTypeRequired
refresh_tokenstringyes

Response 200

{ "data": { "access_token": "eyJ…", "refresh_token": "eyJ…" } }

Errors

  • 400 INVALID_INPUT.
  • 401 INVALID_TOKEN — token signature failed, session not found, expired, or already revoked.
  • 429 — rate limited.
  • 500 REFRESH_FAILED.

Try it:

POST/auth/developer/refresh
public auth
curl -X POST 'https://api.amba.dev/auth/developer/refresh'

Curl:

curl -X POST '${BASE_URL}/auth/developer/refresh' \
  -H 'Content-Type: application/json' \
  -d '{}'

POST /auth/developer/logout

Revoke the session referenced by the refresh token. Idempotent — an already-invalid token returns success.

Request

POST /auth/developer/logout
Content-Type: application/json
FieldTypeRequired
refresh_tokenstringyes

Response 200

{ "data": { "success": true } }

Errors

  • 400 INVALID_INPUT.
  • 500 LOGOUT_FAILED.

Try it:

POST/auth/developer/logout
developer auth
curl -X POST 'https://api.amba.dev/auth/developer/logout'
Loading auth… Configure auth in the settings drawer (top-right) to run this request.

Curl:

curl -X POST '${BASE_URL}/auth/developer/logout' \
  -H 'Authorization: Bearer ${DEV_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{}'

GET /auth/developer/me

Return the current developer profile. Requires a valid access token.

Request

GET /auth/developer/me
Authorization: Bearer <developer-access-token>

Response 200

{
  "data": {
    "id": "…",
    "email": "…",
    "name": "…",
    "oauth_providers": [],
    "created_at": "…",
    "updated_at": "…"
  }
}

Errors

  • 401 UNAUTHORIZED — missing or invalid access token.
  • 404 NOT_FOUND — the developer the token references no longer exists.
  • 500 FETCH_FAILED.

Try it:

GET/auth/developer/me
developer auth
curl -X GET 'https://api.amba.dev/auth/developer/me'
Loading auth… Configure auth in the settings drawer (top-right) to run this request.

Curl:

curl -X GET '${BASE_URL}/auth/developer/me' \
  -H 'Authorization: Bearer ${DEV_TOKEN}'

On this page