One endpoint, account-linked credits
Regen API keys authenticate your server as your account. Requests use the same plan permissions, content safeguards, memory, and credit balance as messages sent through Regen chat.
Quickstart
- Create a key in Account Settings under Developer API keys.
- Copy it immediately; the full secret is shown only once.
- Store it in a server environment variable named
REGEN_API_KEY. - Send requests to the production endpoint shown below.
curl https://regengpt.com/api/v1/chat/completions \
-H "Authorization: Bearer $REGEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openrouter/auto",
"messages": [
{"role": "user", "content": "Explain event loops simply."}
]
}'Authentication
Send the key in the HTTP Authorization header. Never place it in a query string, browser bundle, mobile application, public repository, or analytics event.
Authorization: Bearer regen_sk_...You may keep up to 10 active keys. Use separate named keys for development, staging, and production so one can be revoked without disrupting every integration.
Request format
| Field | Required | Description |
|---|---|---|
| model | Yes | A supported model ID, or openrouter/auto. |
| messages | Yes | 1–30 user, assistant, or system messages. |
| chatId | No | A stable ID used to associate compact memory summaries with a conversation. |
Message content may be up to 100,000 characters. The endpoint always returns a text/event-stream response.
Read the SSE stream
Parse Server-Sent Events as they arrive. Normal model chunks contain text in choices[0].delta.content. After a successful stream, Regen sends a final regen_usageevent containing creditsCharged, the requested model, and the model actually used.
const response = await fetch(
"https://regengpt.com/api/v1/chat/completions",
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.REGEN_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "openrouter/auto",
messages: [
{ role: "user", content: "Write a product description." },
],
}),
}
);
if (!response.ok) {
throw new Error(await response.text());
}
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = "";
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const events = buffer.split("\n\n");
buffer = events.pop() ?? "";
for (const event of events) {
for (const line of event.split("\n")) {
if (!line.startsWith("data:")) continue;
const data = line.slice(5).trim();
if (!data || data === "[DONE]") continue;
const chunk = JSON.parse(data);
const text = chunk.choices?.[0]?.delta?.content;
if (typeof text === "string") process.stdout.write(text);
if (chunk.type === "regen_usage") {
console.log("\nCredits used:", chunk.creditsCharged);
}
}
}
}import json
import os
import requests
with requests.post(
"https://regengpt.com/api/v1/chat/completions",
headers={
"Authorization": f"Bearer {os.environ['REGEN_API_KEY']}",
"Content-Type": "application/json",
},
json={
"model": "openrouter/auto",
"messages": [
{"role": "user", "content": "Give me three startup names."}
],
},
stream=True,
timeout=120,
) as response:
response.raise_for_status()
for line in response.iter_lines(decode_unicode=True):
if not line or not line.startswith("data:"):
continue
data = line[5:].strip()
if data == "[DONE]":
continue
chunk = json.loads(data)
text = (
chunk.get("choices", [{}])[0]
.get("delta", {})
.get("content")
)
if text:
print(text, end="", flush=True)
if chunk.get("type") == "regen_usage":
print(f"\nCredits used: {chunk['creditsCharged']}")Only treat the request as complete after the response body ends. If the client disconnects, do not automatically retry unless your operation is safe to repeat.
Vision inputs
User messages can include up to two JPEG, PNG, or WebP images. Use HTTPS URLs or Base64 data URLs. Each Base64 image is limited to 1.25 MB, and the chosen model must support image input.
{
"model": "openrouter/auto",
"messages": [
{
"role": "user",
"content": "What is shown in this image?",
"images": [
{
"url": "https://example.com/photo.jpg",
"name": "photo.jpg",
"mimeType": "image/jpeg"
}
]
}
]
}Image requests add one Regen credit per request, whether one or two images are attached.
Credits, plans, and limits
- Credits are deducted only after a model stream completes successfully.
- The charge uses the greater of the model's advertised Regen credits or its calculated usage cost.
- API traffic shares the account's existing balance and plan access.
- A request without available usage returns HTTP 429.
- A model outside the account's plan returns HTTP 403.
Errors
| 400 | Invalid model, messages, or image attachment. |
| 401 | Missing, invalid, or revoked API key. |
| 403 | Moderation block or model unavailable on the account plan. |
| 404 | Requested model is unavailable. |
| 429 | Usage or credit limit reached. |
| 500 | Unexpected server or provider failure. |
Error responses may be plain text or JSON. Moderation blocks use JSON with the code moderation_blocked, so clients should inspect both the status and response content.
Production best practices
- Call Regen only from your backend; your frontend should call your own authenticated endpoint.
- Use a different key per environment and revoke keys immediately if exposed.
- Do not log Authorization headers or full request payloads containing private user data.
- Set request timeouts, handle streamed errors, and use bounded exponential backoff only for transient 5xx failures.
- Validate and limit user input before forwarding it, even though Regen also applies moderation.
- Monitor each key's last-used time and request count in Settings.