Developers
The MajeedAI API
One OpenAI-compatible address for every model you use. MajeedAI picks a low-cost or a strong model for each request, falls back to your other keys when a provider fails, and keeps every call inside the caps you set. Your providers bill you directly.
Base address
https://api.majeedai.com/v1- 1Add your provider keysKeep your DeepSeek, OpenAI and other provider keys in your MajeedAI vault.
- 2Create a MajeedAI keyOne mai_live_ key with its own caps, scopes and expiry.
- 3Change two settingsPoint any OpenAI library at the address above and use your key.
1. The address and the key
Base address: https://api.majeedai.com/v1
Send your key in the Authorization header as Bearer mai_live_…. Create a key on API keys and keep it in your app's secret settings, never in code you share.
MajeedAI answers with your own provider keys, kept in your cloud vault on AI connections & privacy. Your providers bill you directly.
curl https://api.majeedai.com/v1/models -H "Authorization: Bearer $MAJEEDAI_API_KEY"2. Choose a model
Send one of these as the model name.
| Model | What it does |
|---|---|
majeed/auto | The recommended choice: a low-cost model for simple asks, a stronger one for hard ones. |
majeed/cheap | The lowest-cost model among your provider keys. |
majeed/best | The strongest model among your provider keys. |
provider/model | One exact model, passed straight through, for example deepseek/deepseek-chat or openai/gpt-5. |
Exact models are offered for the providers you keep a key for.
3. Ask
curl https://api.majeedai.com/v1/chat/completions \
-H "Authorization: Bearer $MAJEEDAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "majeed/auto",
"messages": [{ "role": "user", "content": "Write a haiku about the sea." }]
}'curl -N https://api.majeedai.com/v1/chat/completions \
-H "Authorization: Bearer $MAJEEDAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "majeed/cheap",
"stream": true,
"messages": [{ "role": "user", "content": "Count to five." }]
}'With "stream": true the answer arrives as OpenAI-style server-sent chunks, ending with data: [DONE].
4. With the OpenAI libraries
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.majeedai.com/v1",
api_key=os.environ["MAJEEDAI_API_KEY"],
)
reply = client.chat.completions.create(
model="majeed/auto",
messages=[{"role": "user", "content": "Summarise this in one line: ..."}],
)
print(reply.choices[0].message.content)
# Streaming
for chunk in client.chat.completions.create(
model="majeed/best",
messages=[{"role": "user", "content": "Explain recursion simply."}],
stream=True,
):
print(chunk.choices[0].delta.content or "", end="")import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.majeedai.com/v1",
apiKey: process.env.MAJEEDAI_API_KEY,
});
const reply = await client.chat.completions.create({
model: "majeed/auto",
messages: [{ role: "user", content: "Suggest three names for a cat." }],
});
console.log(reply.choices[0].message.content);
// Streaming
const stream = await client.chat.completions.create({
model: "deepseek/deepseek-chat",
messages: [{ role: "user", content: "Tell me a short story." }],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}When a provider fails
If a provider fails, MajeedAI tries your other provider keys, unless the key has fallback turned off or the request asks it not to.
curl https://api.majeedai.com/v1/chat/completions \
-H "Authorization: Bearer $MAJEEDAI_API_KEY" \
-H "X-MajeedAI-Fallback: off" \
-H "Content-Type: application/json" \
-d '{ "model": "openai/gpt-5", "messages": [{ "role": "user", "content": "Hi" }] }'What comes back
Every answer carries these headers.
| Header | What it says |
|---|---|
x-majeedai-provider | The provider that answered. |
x-majeedai-model | The exact model that answered. |
x-majeedai-fallbacks | How many other keys were tried first (0 when the first one answered). |
x-majeedai-cost-usd | What the call cost, in US dollars, billed by your provider. |
x-majeedai-cache | hit when an earlier answer was reused, miss when not, off when reuse is off. |
x-majeedai-route | How the request was routed, for example auto:simple. |
Errors
Errors use the OpenAI shape: an error object with a message, a type and a code.
| Status and code | What to do |
|---|---|
401 invalid_api_key | The key is wrong, revoked or expired. Check it, or create a new one. |
403 ip_not_allowed | The call came from an address the key does not allow. |
403 scope_not_allowed | The key may not call this (for example it may only list models). |
403 public_api_disabled | The MajeedAI API is turned off for this account right now. |
424 no_provider_key | You keep no provider key for that model. Add one on AI connections & privacy. |
429 rate_limit_exceeded | Too many requests in a minute. Wait a moment and retry. |
429 spending_cap_reached | A key, account or organization cap was reached. Raise it or wait. |
429 request_limit_reached | Your plan's requests for this month are used up. |
502 / 504 | The provider failed or took too long, and no other key could answer. |
Caps and rate limits
- Each key has a monthly cap, and can have a daily cap and its own requests per minute.
- Caps over all your keys together, and an unusual-spend email, are on API keys.
- Your plan sets the requests per month, the requests per minute and how many keys you can have.
- An organization key also counts against the organization's caps.
- When a limit is reached the call is refused with status 429; nothing is charged.
Privacy
MajeedAI never stores your prompts or the answers. For each call it keeps only counts, cost, the model and timing, which you can see on Usage. Reusing answers is off unless you turn it on for a key, and then an answer is held in memory only for the time you choose.