Docs

Developer Docs

noonoo exposes two API surfaces: console management APIs for balance, API Key, group, and usage queries; model gateway APIs compatible with OpenAI, Claude, Gemini, Codex CLI, and Antigravity clients.

Authentication

All protected requests authenticate with the Authorization header, but different API surfaces use different credentials.

Management APIs use console session tokens

Use the access token obtained after sign-in. The frontend reads it from the local auth_token session value and attaches it automatically.

Authorization: Bearer YOUR_LOGIN_ACCESS_TOKEN

Gateway APIs use API Keys

Use an API Key created in the developer console. The key-bound group determines callable platforms, models, rates, and limits.

Authorization: Bearer sk-YOUR_API_KEY

Base URL

Base URL

Console management APIs

/api

Model gateway APIs

The console frontend requests /api by default; OpenAI/Claude/Gemini client base_url values should point to gateway prefixes such as /v1 or /v1beta

Response format

Management APIs use a unified JSON envelope; model gateway APIs preserve upstream protocol response formats for SDK compatibility.

{
  "success": true,
  "message": "",
  "data": {
    "items": [],
    "total": 0,
    "page": 1,
    "page_size": 20,
    "pages": 1
  }
}

Console management APIs

These APIs use the console session and only allow access to the current user’s keys, usage, and group information.

Base: /api
GET /api/user/self
GET
/api/user/self

Get current signed-in user

Response: User

Validates the console session and returns user balance, concurrency, and available groups.

Console session
GET /api/token/
GET
/api/token/

List API Keys

Query: p, page_size

Response: PageInfo<Token>

Only returns tokens owned by the current user; use /api/token/search?keyword= to search.

Console session
GET /api/token/:id
GET
/api/token/:id

Get one API Key

Response: Token

Key ownership is checked; keys owned by other users cannot be accessed.

Console session
POST /api/token/:id/regenerate
POST
/api/token/:id/regenerate

Regenerate an API Key

Response: Token

The previous key is invalidated immediately; only the owner can regenerate it.

Console session
POST /api/token/
POST
/api/token/

Create API Key

Body: name, group, remain_quota, unlimited_quota, expired_time, allow_ips

Response: { success: true }

Quota uses New API quota units; expired_time is Unix seconds and -1 means no expiration.

Console session
PUT /api/token/
PUT
/api/token/

Update API Key

Body: id, name, group, status, remain_quota, unlimited_quota, expired_time, allow_ips

Response: Token

Append ?status_only=true when only toggling the enabled state.

Console session
DELETE /api/token/:id
DELETE
/api/token/:id

Delete API Key

Response: { success: true }

Key ownership is also checked before deletion.

Console session
GET /api/log/self
GET
/api/log/self

Query usage logs

Query: p, page_size, type, model_name, token_name, group, start_timestamp, end_timestamp

Response: PageInfo<Log>

Time ranges use Unix seconds; type=2 queries consumption logs.

Console session
GET /api/log/self/stat
GET
/api/log/self/stat

Query usage statistics

Query: type, model_name, token_name, group, start_timestamp, end_timestamp

Response: { quota, rpm, tpm }

Used by the Noonoo usage overview and live rate statistics.

Console session
GET /api/user/self/groups
GET
/api/user/self/groups

List available groups

Response: Record<string, GroupInfo>

Used when creating a key or switching key groups.

Console session
GET /api/user/models
GET
/api/user/models

List models available to the user

Query: group

Response: string[]

Pass group to get the model list for a specific group.

Console session

Model gateway APIs

These APIs use API Keys and keep protocol compatibility with OpenAI, Anthropic, Gemini, or Antigravity.

Base: /
POST /v1/chat/completions
POST
/v1/chat/completions

OpenAI Chat Completions compatible API

Body: model, messages, stream

Response: OpenAI-compatible response

OpenAI groups connect directly to the OpenAI gateway; other groups go through compatibility conversion.

API Key
POST /v1/responses
POST
/v1/responses

OpenAI Responses compatible API

Body: model, input, stream

Response: OpenAI Responses-compatible response

Also supports /responses and /backend-api/codex/responses aliases for Codex CLI.

API Key
GET /v1/responses
GET
/v1/responses

Responses WebSocket

Response: WebSocket stream

Supports OpenAI Responses WebSocket mode.

API Key
POST /v1/messages
POST
/v1/messages

Claude Messages compatible API

Body: model, max_tokens, messages, stream

Response: Anthropic-compatible response

Anthropic groups use Claude API; OpenAI groups route through OpenAI message compatibility handling.

API Key
POST /v1/messages/count_tokens
POST
/v1/messages/count_tokens

Claude token counting

Body: model, messages

Response: Anthropic-compatible count response

OpenAI groups do not support this endpoint and return 404.

API Key
GET /v1/models
GET
/v1/models

Model list

Response: Model list

Returns the model list according to the API Key-bound group.

API Key
GET /v1/usage
GET
/v1/usage

Gateway usage query

Response: Gateway usage

Used for model gateway compatible usage queries.

API Key
POST /v1/images/generations
POST
/v1/images/generations

OpenAI Images generation

Body: model, prompt, size

Response: OpenAI image response

Only OpenAI groups support this endpoint; other platforms return 404.

API Key
POST /v1/images/edits
POST
/v1/images/edits

OpenAI Images editing

Body: model, image, prompt

Response: OpenAI image response

Only OpenAI groups are supported.

API Key
GET /v1beta/models
GET
/v1beta/models

Gemini model list

Response: Gemini-compatible model list

Direct entrypoint for Gemini SDK/CLI.

API Key
GET /v1beta/models/:model
GET
/v1beta/models/:model

Gemini model details

Response: Gemini-compatible model

:model in the path is the actual model ID.

API Key
POST /v1beta/models/:model:generateContent
POST
/v1beta/models/:model:generateContent

Gemini Generate Content

Body: contents, generationConfig, safetySettings

Response: Gemini-compatible response

The backend uses wildcard routing for actions such as :generateContent and :streamGenerateContent.

API Key
GET /antigravity/models
GET
/antigravity/models

Antigravity model list

Response: Model list

Dedicated Antigravity model list entrypoint.

API Key
POST /antigravity/v1/messages
POST
/antigravity/v1/messages

Antigravity Claude compatible API

Body: model, max_tokens, messages

Response: Anthropic-compatible response

Forces scheduling through antigravity platform accounts.

API Key
POST /antigravity/v1beta/models/:model:generateContent
POST
/antigravity/v1beta/models/:model:generateContent

Antigravity Gemini compatible API

Body: contents

Response: Gemini-compatible response

Gemini-style entrypoint for Antigravity.

API Key

Error handling

Non-2xx responses or business errors from management APIs return a unified error shape. Common statuses include 400 parameter errors, 401 unauthenticated, 403 forbidden, 404 not found, and 500 server errors. Model gateway APIs preserve the corresponding protocol error format where possible.

{
  "success": false,
  "code": "AUTH_UNAUTHORIZED",
  "message": "User not authenticated"
}

Quickstart

1. Query keys with a console session

curl /api/token/?p=1&page_size=20 \
  -H "Authorization: Bearer YOUR_LOGIN_ACCESS_TOKEN"

2. Create an API Key

curl /api/token/ \
  -X POST \
  -H "Authorization: Bearer YOUR_LOGIN_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "production",
    "group": "default",
    "remain_quota": 25000000,
    "unlimited_quota": false,
    "expired_time": -1
  }'

3. Call the OpenAI-compatible API

curl /v1/chat/completions \
  -H "Authorization: Bearer sk-YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.5",
    "messages": [
      { "role": "user", "content": "Hello" }
    ]
  }'

4. Call the Claude-compatible API

curl /v1/messages \
  -H "Authorization: Bearer sk-YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4-5",
    "max_tokens": 1024,
    "messages": [
      { "role": "user", "content": "Hello" }
    ]
  }'