01 · Start here
Quickstart
- Sign in and open Manage API key.
- Select a chat model, choose an optional expiry, and create the key. The secret is shown once.
- Copy it immediately into a password manager or secret store. Do not put it in source code, screenshots, chat, logs, or browser URLs.
- Call the API with the returned base URL and selected model.
- Revoke the key from the same page when finished.
Python with the OpenAI SDK
python -m pip install openai
export NEODYM_API_KEY="your-key-from-the-portal"
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["NEODYM_API_KEY"],
base_url="https://compute.neodym.ai/v1",
)
response = client.chat.completions.create(
model="qwen2.5:7b",
messages=[
{"role": "system", "content": "Be concise."},
{"role": "user", "content": "Explain shared model inference."},
],
max_tokens=256,
)
print(response.choices[0].message.content)
cURL
export NEODYM_API_KEY="your-key-from-the-portal"
curl --fail-with-body https://compute.neodym.ai/v1/chat/completions \
-H "Authorization: Bearer $NEODYM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen2.5:7b",
"messages": [{"role": "user", "content": "Reply with: hello"}],
"max_tokens": 64,
"stream": false
}'
Independent ordinary users can create same-model keys concurrently, run synchronized inference, revoke independently, and receive isolated usage and job results.
02 · Access
Authentication and API keys
Send the key on every API request:
Authorization: Bearer your-api-key
- Each ordinary account can have one active key.
- The key is scoped to the model selected during creation.
- The raw secret is shown once; later page loads show only safe metadata and a short prefix.
- Key expiry and shared model-runtime expiry are separate. A key can expire while a shared deployment remains available to other valid keys.
- Revocation takes effect immediately for new API calls and returns
401 api_key_revoked. - Creating and revoking keys is done through the signed-in portal. Bearer keys are for inference, jobs, models, and usage—not portal administration.
Never send a key in a query string, commit it to Git, embed it in frontend JavaScript, or include it in retained QA artifacts. If exposure is possible, revoke it and create a new one.
03 · Discovery
Models
/v1/modelsList the models visible to this key.curl https://compute.neodym.ai/v1/models \
-H "Authorization: Bearer $NEODYM_API_KEY"
A normal model-scoped key returns only its approved model aliases. Use one of the returned IDs in chat or job requests. Model names are exact and case-sensitive.
Two users requesting the same model can share one warm model deployment. A key-creation response is returned only after that model is ready, so the first creation can take longer than later attachments.
04 · Synchronous inference
Chat completions
/v1/chat/completionsGenerate one assistant response.Request
{
"model": "qwen2.5:7b",
"messages": [
{"role": "system", "content": "Be concise."},
{"role": "user", "content": "What is a shared deployment?"}
],
"max_tokens": 256,
"n": 1,
"stream": false
}
Supported message roles are system, developer, user, assistant, and tool. The current implementation generates one choice, so n must be 1. You may use max_tokens or max_completion_tokens.
Response
{
"id": "chatcmpl-…",
"object": "chat.completion",
"created": 1760000000,
"model": "qwen2.5:7b",
"choices": [{
"index": 0,
"message": {"role": "assistant", "content": "…"},
"finish_reason": "stop"
}],
"usage": {
"prompt_tokens": 12,
"completion_tokens": 20,
"total_tokens": 32
}
}
Non-streaming responses include an X-DGX-Request-ID. Keep that identifier when contacting support; it helps correlate a request without sharing your key or prompt.
05 · SSE
Streaming chat
Set "stream": true on /v1/chat/completions. The response uses Server-Sent Events with OpenAI-compatible chat.completion.chunk objects and ends with:
data: [DONE]
from openai import OpenAI
import os
client = OpenAI(
api_key=os.environ["NEODYM_API_KEY"],
base_url="https://compute.neodym.ai/v1",
)
stream = client.chat.completions.create(
model="qwen2.5:7b",
messages=[{"role": "user", "content": "Write a short explanation."}],
stream=True,
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")
The gateway currently waits for the model result and then emits OpenAI-compatible text chunks. The SSE shape is compatible, but it does not yet provide upstream token-by-token time-to-first-token streaming.
06 · Queued inference
Asynchronous jobs
Use jobs when the caller should receive a job ID quickly, poll independently, and retrieve the result later.
/v1/jobsSubmit a job; returns 202./v1/jobs/{job_id}Poll status and timing./v1/jobs/{job_id}/resultRetrieve completed output./v1/jobs/{job_id}Cancel a nonterminal job.Submit
curl --fail-with-body https://compute.neodym.ai/v1/jobs \
-H "Authorization: Bearer $NEODYM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen2.5:7b",
"input": {
"messages": [{"role": "user", "content": "Write a short summary."}]
},
"max_tokens": 256,
"priority": "normal",
"timeout_seconds": 300
}'
The response includes job_id, state, status_url, result_url, poll_after_ms, Location, and Retry-After. Poll at the suggested interval instead of tight-looping.
States
queued → loading_model → running → completed. Terminal alternatives are failed, cancelled, and timed_out.
Poll and retrieve
curl https://compute.neodym.ai/v1/jobs/JOB_ID \
-H "Authorization: Bearer $NEODYM_API_KEY"
curl https://compute.neodym.ai/v1/jobs/JOB_ID/result \
-H "Authorization: Bearer $NEODYM_API_KEY"
Result retrieval before completion returns 409 job_result_not_ready. A completed result includes output text, token usage, queue dwell time, inference time, and total duration.
Cancel
curl -X DELETE https://compute.neodym.ai/v1/jobs/JOB_ID \
-H "Authorization: Bearer YOUR_API_KEY"
Cancellation succeeds only while the job is nonterminal. Cancelling a completed, failed, timed-out, or already-cancelled job returns 409 job_already_terminal.
Only the exact key that submitted a job can read, retrieve, or cancel it. Revoking that key removes access. Completed asynchronous output is retained for job result retrieval; do not submit data that your organization does not permit the service to retain.
07 · Accounting
Usage and status
/v1/usageCurrent limits, totals, active requests, and recent usage.curl https://compute.neodym.ai/v1/usage \
-H "Authorization: Bearer $NEODYM_API_KEY"
The response reports requests-per-minute, tokens-per-minute, concurrency, total request/token ceilings, consumed totals, active_requests, and up to the latest 100 usage rows. Rows include endpoint, model, approximate input/output tokens, queue and inference duration, status, error code, and timestamp.
The API Keys page is the authoritative ordinary-user view for key and shared-deployment state. Internal host IDs are intentionally omitted.
08 · Fair use
Limits, queueing, and capacity
Your current limits are displayed on the API Keys page and returned by /v1/usage. Administrators can configure them per account, so clients should read the live values instead of assuming defaults.
| Limit | What happens at the boundary |
|---|---|
| Requests per minute | 429 requests_per_minute_exceeded |
| Tokens per minute | 429 tokens_per_minute_exceeded |
| Concurrent requests/jobs | 429 concurrent_limit_exceeded |
| Total requests or tokens | 429 total_requests_exceeded or total_tokens_exceeded |
| Context/output size | 400 context_length_exceeded or max_tokens_exceeded |
| Shared backend pressure | The request may queue; a full queue returns a structured 503. |
Synchronous requests can wait in a bounded queue and then return a normal completion. Async jobs expose queue state and timing. Same-model users share a warm deployment but retain separate keys, quotas, usage, and job ownership.
09 · Recovery
Errors and retries
Errors use an OpenAI-style JSON envelope:
{
"error": {
"message": "Human-readable explanation",
"type": "invalid_request_error",
"param": null,
"code": "machine_readable_code"
}
}
| Status | Common codes | Client action |
|---|---|---|
| 400 | invalid_json, invalid_model, invalid_messages, invalid_max_tokens | Correct the request; do not retry unchanged. |
| 401 | missing_api_key, invalid_api_key, api_key_revoked, api_key_expired | Fix or replace the credential. |
| 403 | endpoint_not_allowed, model_not_allowed, forbidden | Use the key's approved model and endpoints. |
| 409 | job_result_not_ready, job_already_terminal | Poll later or stop changing a terminal job. |
| 413 | request_too_large, job_input_too_large | Reduce request/input size. |
| 429 | Rate, token, concurrency, total-quota, or capacity codes | Honor Retry-After; back off. |
| 503 | deployment_not_ready, backend_saturated, deployment_saturated, backend_unavailable | Retry with exponential backoff and jitter. |
Recommended retry policy
- Never automatically retry most
400,401, or403responses. - For
409 job_result_not_ready, use the job'spoll_after_msorRetry-After. - For
429and temporary503, honorRetry-After, then use exponential backoff with jitter and a bounded attempt count. - Record
X-DGX-Request-ID, HTTP status, and error code for support—but never the bearer key or private prompt.
10 · Runtime behavior
Key, deployment, and idle lifecycle
- Key creation reserves capacity and attaches to or warms a shared model deployment.
- The key becomes active only after the deployment is ready.
- Successful inference refreshes deployment activity.
- Revoking one user's key does not interrupt other valid users sharing that model.
- When no active inference or nonterminal jobs remain, the deployment becomes eligible for idle cleanup.
The current server idle interval is 900 seconds. Cleanup runs on a reaper cadence, so the public deployment row may clear shortly after the nominal deadline rather than at exactly 900.000 seconds.
The public lifecycle status proves the account-scoped API deployment-expiry contract. It does not prove direct physical GPU or VRAM unload; hardware-level verification requires separate privileged telemetry.
Key expiration, key revocation, and model idle cleanup are different events. Do not force-stop a shared model merely because one key was revoked.
11 · Data boundaries
Privacy and tenant isolation
- Raw API keys are not shown again after creation and are not stored as plaintext.
- Ordinary users see only their own key metadata.
- One user's revocation does not revoke another user's key.
- Async job status, result, and cancellation require the exact submitting key.
- Public API and deployment responses omit internal host identifiers, private infrastructure addresses, credentials, and storage paths.
- Synchronous prompt and completion text is not included in usage rows. Completed async job output is retained so the submitting key can retrieve it later.
Applications should minimize sensitive input, apply their organization's data policy, avoid logging bearer headers, and redact prompts/results from diagnostic bundles unless explicitly required and protected.
12 · OpenAI surface
Compatibility and current boundaries
| Feature | Status |
|---|---|
POST /v1/chat/completions | Supported for model-scoped ordinary-user keys. |
| Chat SSE | OpenAI-compatible framing; currently chunked after backend completion. |
POST /v1/jobs | Supported async queue with status, result, timing, and cancellation. |
Legacy /v1/completions | Implemented only for keys explicitly provisioned for that endpoint; ordinary chat keys should use chat completions. |
POST /v1/embeddings | Supported for BAAI/bge-small-en-v1.5 using a key scoped to /v1/embeddings. Send {"model":"BAAI/bge-small-en-v1.5","input":["First document","Second document"]}. Returns 384-dimensional float vectors. Up to 32 texts; each text has a 512-token model context. Other models return 400 endpoint_not_supported. |
| Multiple choices | n must be 1. |
| Multimodal input, tool/function calling, structured output, logprobs | Not currently supported as OpenAI-equivalent features. |
Only depend on fields documented here. Backend/model behavior can differ from OpenAI even when request and response envelopes are compatible.
13 · Diagnose safely
Troubleshooting checklist
- Check health:
GET https://compute.neodym.ai/api/health. - Check the key: open Manage API key and confirm it is active, not pending, expired, or revoked.
- Check model scope: call
GET /v1/modelsand use the returned model ID exactly. - Check usage: call
GET /v1/usagefor current totals, limits, and active requests. - For jobs: poll the provided
status_url; do not guess routes or poll faster than instructed. - For 429/503: honor
Retry-Afterand back off. - For support: provide UTC time, endpoint, status, error code, and
X-DGX-Request-ID. Never provide the raw key, cookies, passwords, or private data.
Revoke temporary keys when finished, let accepted jobs reach a terminal state or cancel them, and verify active_requests returns to zero.