GME AI API
One key, every model. Point any OpenAI SDK at our gateway and start building — then resell access to your own customers with metered billing through the Merchant API.
https://gme-ai.com/v1Overview
There are two APIs, for two audiences:
For your app
OpenAI-compatible chat completions. Authenticate with an inference key (gme-…) and call any available model. Usage bills the key's balance.
https://gme-ai.com/v1
For resellers
Create customers with a balance, mint and manage their keys, move funds, and read usage — all scoped to your merchant account. Authenticate with a management key (gmadm-…).
https://gme-ai.com/api/gme-ai/merchant
Concepts & hierarchy
- Merchant — a reseller tenant with a pooled balance funded by the platform.
- Customer — an end user created by the merchant, with a balance drawn from the pool, and one or more keys.
- Balance — every inference call bills the customer's balance and hard-stops at zero (a
402, never an overage).
gme-…) can call /v1 but not the Merchant API. A management key (gmadm-…) can call the Merchant API but never inference. Using one where the other is expected returns 401.Authentication
All requests use a bearer token in the Authorization header:
Authorization: Bearer gme-xxxxxxxxxxxxxxxxxxxxxxxx # inference Authorization: Bearer gmadm-xxxxxxxxxxxxxxxxxxxxxx # merchant management
Keys are shown once at creation and cannot be retrieved again — save them securely. Treat a key like a password; anyone holding it can spend the balance it draws on.
gme- key in a browser, mobile app, or any client-side code. The gateway allows cross-origin requests, so a key that ships to end users is immediately usable by anyone who extracts it — and it spends a real balance. Keep inference keys on your server and proxy requests, or issue a short-lived, capped per-user key from the Merchant API.Playground
Try a live request against the gateway. Your key is used only in this browser and sent directly to the API — nothing is stored.
Quickstart
The Inference API is a drop-in OpenAI replacement — change the base URL and key:
Python (openai SDK)
from openai import OpenAI client = OpenAI(base_url="https://gme-ai.com/v1", api_key="gme-YOUR_KEY") resp = client.chat.completions.create( model="atg-gpt-5.4", messages=[{"role": "user", "content": "Hello!"}], ) print(resp.choices[0].message.content)
Node (openai SDK)
import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://gme-ai.com/v1", apiKey: "gme-YOUR_KEY" }); const r = await client.chat.completions.create({ model: "atg-gpt-5.4", messages: [{ role: "user", content: "Hello!" }], }); console.log(r.choices[0].message.content);
curl
curl https://gme-ai.com/v1/chat/completions \ -H "Authorization: Bearer gme-YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"model":"atg-gpt-5.4","messages":[{"role":"user","content":"Hello!"}]}'
Chat completions
OpenAI-compatible. Returns a chat.completion object (or an SSE stream when stream: true).
Request body
| Field | Type | Description |
|---|---|---|
model required | string | Model id or alias (see Available models). Unknown names resolve to the default model. |
messages required | array | Chat messages: { role, content } with roles system / user / assistant / tool. |
temperature | number | Sampling temperature. |
top_p | number | Nucleus sampling. |
max_tokens | integer | Max output tokens. Default 2048. |
tools, tool_choice | array / string | Function-calling tools, OpenAI schema. |
response_format | object | { "type": "json_object" } for JSON mode. |
stream | boolean | Stream the response as SSE. Default false. |
Response
{
"id": "chatcmpl-…",
"object": "chat.completion",
"created": 1730000000,
"model": "atg-gpt-5.4",
"choices": [{ "index": 0, "message": { "role": "assistant", "content": "…" }, "finish_reason": "stop" }],
"usage": { "prompt_tokens": 9, "completion_tokens": 12, "total_tokens": 21 }
}
tools and read choices[0].message.tool_calls in the response (finish_reason: "tool_calls").Streaming
Set "stream": true to receive Server-Sent Events. The first event carries delta.role, each following event a partial delta.content, and the stream ends with a finish_reason chunk then data: [DONE]. This is fully compatible with the OpenAI SDK's streaming helpers.
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"role":"assistant"}}]}
data: {"…","choices":[{"index":0,"delta":{"content":"Hel"}}]}
data: {"…","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: [DONE]
List models
Returns the models available to your key, in OpenAI list format:
{ "object": "list", "data": [{ "id": "atg-gpt-5.4", "object": "model", "owned_by": "atg" }, … ] }
If your key has a model allowlist, requests for models outside it return 403 model_not_allowed (even via an alias).
Available models
| Model id | Context | Best for |
|---|---|---|
atg-gpt-5.5 | 400K | Flagship — reasoning, vision, tools, JSON. |
atg-gpt-5.4 | 400K | General-purpose default — vision, tools, JSON. |
atg-gpt-5.4-mini | 400K | Fast + economical (p95 ≈ 1.8s). |
atg-gpt-5.3-codex | 200K | Coding & agentic tool use. |
atg-gpt-5.3-codex-spark | 200K | Faster coding tier. |
atg-gpt-5.2 | 200K | Prior-gen general model. |
gpt-4o, gpt-4o-mini, gpt-4, gpt-5, …) and Claude names (claude-sonnet, claude-opus, …) are accepted and mapped to the equivalent model above. Call GET /v1/models for the live list. Pricing bills your balance per token; track exact spend in your usage report.Merchant API
Base URL https://gme-ai.com/api/gme-ai/merchant. Authenticate every request with your management key:
Authorization: Bearer gmadm-YOUR_MANAGEMENT_KEY
All responses are JSON of the form { "ok": true, … } or { "ok": false, "error": "code", "detail": "…" }. Everything is scoped to your merchant — you can only read and manage your own customers and keys.
Merchant info
{ "ok": true,
"merchant": { "id": 7, "name": "Acme AI", "pool_balance_usd": 420.50, "customer_count": 12 },
"limits": { "maxStartBalance": 5000, "maxRatePerMin": 120, "maxCustomers": 2000 } }
Create customer
Creates (or attaches) a customer, transfers a starting balance from your pool, and mints their first inference key. The raw key is returned once.
| Field | Type | Description |
|---|---|---|
email required | string | Customer's email (their identity). |
display_name | string | Friendly name. |
starting_balance_usd | number | Transferred from your pool. Above maxStartBalance the request is rejected (400 balance_exceeds_limit). |
model_allowlist | string[] | Restrict the key to these models (blank = all). Unknown names are rejected (400 unknown_models). |
daily_cap_usd, monthly_cap_usd | number | Per-key spend caps (USD). Negative values are treated as 0. |
rate_per_min | integer | Requests/minute. Silently clamped to maxRatePerMin (not rejected). |
expires_days | integer | Key auto-expires after N days. |
curl https://gme-ai.com/api/gme-ai/merchant/customers \ -H "Authorization: Bearer gmadm-YOUR_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: signup-8842" \ -d '{"email":"dev@customer.com","starting_balance_usd":10,"daily_cap_usd":5}'
{ "ok": true, "customer_id": 341, "funded_usd": 10,
"api_key": { "id": 88, "token_prefix": "gme-Abc123…", "raw_token_shown_once": "gme-…" },
"base_url": "https://gme-ai.com/v1" }
Idempotency-Key header so a retry never double-charges your pool.List customers
{ "ok": true, "customers": [
{ "id": 341, "email": "dev@customer.com", "display_name": "Dev", "active_keys": 1, "created_at": "…" } ] }
List keys
Returns every inference key under your merchant, with caps, allowlist, last-used and revoked/expiry status. Raw key values are never returned — only the token_prefix hint.
Mint another key
Issues an additional inference key for an existing customer. Body: customer_id or email, plus optional name, daily_cap_usd, monthly_cap_usd, rate_per_min, model_allowlist, expires_days. Returns the raw key once.
Update a key
Change any of daily_cap_usd, monthly_cap_usd, rate_per_min, model_allowlist, expires_days. Pass null to clear a cap. Only fields present in the body are changed.
Revoke & rotate
Revokes a key immediately.
Mints a replacement key (same caps, allowlist and expiry) and sets the old key to expire after a grace window so you can cut over without downtime. Body: grace_hours (default 24, max 168). Returns the new raw key once.
{ "ok": true, "new_key": { "raw_token_shown_once": "gme-…" }, "old_key_expires_in_hours": 24 }
Top-up a customer
Moves amount_usd from your pool to the customer's balance. Send an Idempotency-Key.
{ "ok": true, "customer_id": 341, "amount_usd": 25, "pool_balance": 395.50, "customer_balance": 35 }
Claw back
Moves balance back from the customer to your pool. Body: amount_usd, or { "all": true } to sweep the whole balance. Send an Idempotency-Key.
Usage report
Aggregated spend for your merchant. days = 7, 28, 90 or 365 (default 28). Add &format=csv for a per-customer CSV download.
{ "ok": true, "days": 28,
"totals": { "calls": 1820, "tokens_in": …, "tokens_out": …, "cost_usd": 42.18 },
"by_customer": [{ "member_id": 341, "email": "…", "calls": …, "cost_usd": … }],
"by_model": [{ "model_id": "gpt-5.4", "calls": …, "cost_usd": … }],
"by_day": [{ "d": "2026-07-17", "calls": …, "cost_usd": … }] }
Idempotency
Money-moving Merchant endpoints — create customer, top-up and claw back — accept an Idempotency-Key header. A retry with the same key returns the original response instead of moving funds again, so a network timeout or a client retry can never double-charge.
Idempotency-Key: any-unique-string-per-operation
- A retry after a successful call replays the stored result (funds moved once).
- A retry after a clean failure where no funds moved (e.g.
bad_amount,insufficient_source_balance) is allowed to try again. - A retry after a money-uncertain failure (a
502such astransfer_state_unknown) replays the stored error and is not re-attempted — reconcile the balances before acting. - While the first request is still in flight, a duplicate returns
409 request_in_progress. - A show-once key is never re-exposed on a replay.
Note: Idempotency-Key applies only to the fund-moving endpoints above (create customer, top-up, claw back). Key mint / update / revoke / rotate are naturally safe to repeat and do not use it.
Errors
Inference API (OpenAI error shape)
{ "error": { "message": "…", "type": "insufficient_quota", "code": "insufficient_quota" } }
| Status | Meaning |
|---|---|
400 | Malformed request (e.g. missing messages). |
401 | Missing / invalid / revoked / expired key, or a management key used for inference. |
402 | Insufficient balance, or a daily/monthly spend cap reached. |
403 | Model not permitted by the key's allowlist, or merchant suspended. |
404 | Requested model unavailable. |
429 | Rate limit exceeded — slow down. |
502 | Upstream provider error. |
Merchant API
| Status | error | Meaning |
|---|---|---|
401 | missing_api_key · invalid_management_key · management_key_revoked · management_key_expired | No / invalid / revoked / expired gmadm- key (or a gme- key was used → invalid_management_key). |
402 | insufficient_pool_balance · insufficient_source_balance | The source account (pool for create/top-up, customer for claw-back) can't cover the amount. |
403 | merchant_suspended | Merchant account suspended. |
404 | customer_not_found · key_not_found | Resource not under your merchant. |
400 | valid_email_required · bad_balance · balance_exceeds_limit · customer_limit_reached · unknown_models · bad_amount | Validation error (detail explains which). |
409 | email_unavailable · request_in_progress | Email already belongs to a retail or other-merchant member; or a same-idempotency-key request is still running. |
502 | transfer_state_unknown · debit_unconfirmed · credit_and_rollback_failed | A funds transfer could not be confirmed. Do not blindly retry — check the pool + customer balance first. |
Rate limits & caps
- Rate limit — each inference key has a requests-per-minute limit (default 60). Exceeding it returns
429. - Spend caps — optional per-key daily and monthly USD caps. They are best-effort budgets checked before each call; the hard ceiling is the customer's balance, which stops at zero.
- Balance — the true limit. When it reaches zero, inference returns
402with no overage and no fallback.
GME AI API · OpenAI-compatible gateway · base https://gme-ai.com/v1
