Right-size the model
Route simple intents to Flash. Reserve Max-class models for tasks where a wrong answer costs more than the tokens.
Our gateway is a drop-in replacement for the OpenAI API. Keep your SDK, your prompt templates and your evaluation suite — change two lines and you are running.
Three steps: create a key in your console, set it as an environment variable, call the model.
In your console, open API keys → New key. Give it a name, a rate limit, an IP whitelist and a spending cap.
Never hard-code a key in source control. Use an environment variable.
# Any OpenAI-compatible SDK works. Two values change.
export IAALGERIE_API_KEY="iaa_live_xxxxxxxxxxxxxxxxxxxx"
export OPENAI_BASE_URL="https://api.iaalgerie.com/v1"
# default model
export DEFAULT_MODEL="qwen3.7-plus"
Point the OpenAI SDK at our base URL and pick a model ID from the catalog.
# pip install openai
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.iaalgerie.com/v1",
api_key=os.environ["IAALGERIE_API_KEY"],
)
response = client.chat.completions.create(
model="qwen3.7-plus",
messages=[
{"role": "system", "content": "Reponds toujours en francais."},
{"role": "user", "content": "Resume ce contrat en 5 points."},
],
temperature=0.3,
)
print(response.choices[0].message.content)
print("tokens:", response.usage.total_tokens)
// npm install openai
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.iaalgerie.com/v1",
apiKey: process.env.IAALGERIE_API_KEY,
});
const response = await client.chat.completions.create({
model: "qwen3.7-plus",
messages: [
{ role: "system", content: "Reponds toujours en francais." },
{ role: "user", content: "Resume ce contrat en 5 points." },
],
});
console.log(response.choices[0].message.content);
curl https://api.iaalgerie.com/v1/chat/completions \
-H "Authorization: Bearer $IAALGERIE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3.7-plus",
"messages": [
{"role": "system", "content": "Reponds toujours en francais."},
{"role": "user", "content": "Resume ce contrat en 5 points."}
],
"temperature": 0.3
}'
One URL for every model. Our gateway picks the upstream region based on the model you ask for.
OpenAI-compatible https://api.iaalgerie.com/v1
Anthropic format https://api.iaalgerie.com/anthropic
Native DashScope https://api.iaalgerie.com/api/v1
One URL for every model. Our gateway selects the upstream region
for you (Singapore, US Virginia or Beijing) — nothing to configure
on your side.
Nothing to configure on the region side: that is our job. If you need a specific region for compliance reasons, tell us.
Send your key in the Authorization header, exactly like OpenAI.
Authorization: Bearer iaa_live_xxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
Rotate keys from your console at any time. The old key stops working immediately.
The standard OpenAI chat payload works untouched.
curl https://api.iaalgerie.com/v1/chat/completions \
-H "Authorization: Bearer $IAALGERIE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3.7-plus",
"messages": [
{"role": "system", "content": "Reponds toujours en francais."},
{"role": "user", "content": "Resume ce contrat en 5 points."}
],
"temperature": 0.3
}'
Use qwen3.8-flash for drafts and classification, qwen3.7-plus for user-facing answers, qwen3.8-max only when the task genuinely needs it.
Set stream to true and consume server-sent events: the user sees the first word in a few hundred milliseconds.
stream = client.chat.completions.create(
model="qwen3.7-plus",
messages=[{"role": "user", "content": "Ecris un devis pour 3 sites web."}],
stream=True,
)
for chunk in stream:
delta = chunk.choices[0].delta.content
if delta:
print(delta, end="", flush=True)
Declare your tools the usual way and let the model decide when to call them.
tools = [{
"type": "function",
"function": {
"name": "get_order_status",
"description": "Retourne le statut d'une commande algerienne.",
"parameters": {
"type": "object",
"properties": {
"order_id": {"type": "string"},
"wilaya": {"type": "string"}
},
"required": ["order_id"]
}
}
}]
messages = [{"role": "user", "content": "Ou est ma commande CMD-4821 ?"}]
while True:
reply = client.chat.completions.create(
model="qwen3.7-plus", messages=messages, tools=tools
).choices[0].message
if not reply.tool_calls:
print(reply.content)
break
messages.append(reply)
for call in reply.tool_calls:
args = json.loads(call.function.arguments)
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": json.dumps({"status": "en livraison", "wilaya": "Bejaia"}),
})
Ask for JSON and validate it against a schema. Ideal for extracting fields from invoices or forms.
from pydantic import BaseModel
class Invoice(BaseModel):
supplier: str
nif: str | None
total_da: float
currency: str
due_date: str | None
raw = "FACTURE SARL Exemple, NIF 0998...1620, total 145 000,00 DA, echeance 30/11/2026"
parsed = client.beta.chat.completions.parse(
model="qwen3.8-flash",
messages=[
{"role": "system", "content": "Extract the invoice fields."},
{"role": "user", "content": raw},
],
response_format=Invoice,
)
invoice = parsed.choices[0].message.parsed
print(invoice.total_da, invoice.currency) # 145000.0 DA
Media models are asynchronous: you submit a task, then poll it. Billing happens once the task completes successfully.
# Images — synchronous, billed per image
curl -X POST https://api.iaalgerie.com/v1/images/generations \
-H "Authorization: Bearer $IAALGERIE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "qwen-image-3.0-pro",
"prompt": "Photo produit d une bouteille d huile d olive",
"size": "1024x1024", "n": 2}'
# Video — asynchronous: submit, then poll the task
curl -X POST https://api.iaalgerie.com/v1/services/aigc/video-generation/video-synthesis \
-H "Authorization: Bearer $IAALGERIE_API_KEY" \
-H "X-DashScope-Async: enable" \
-H "Content-Type: application/json" \
-d '{"model": "wan3.0-video",
"input": {"prompt": "Tramway d Alger au coucher du soleil"},
"parameters": {"duration": 5, "size": "1280*720"}}'
# -> {"output": {"task_id": "..."}} then:
curl https://api.iaalgerie.com/v1/tasks/<task_id> \
-H "Authorization: Bearer $IAALGERIE_API_KEY"
# Speech to text
curl -X POST https://api.iaalgerie.com/v1/audio/transcriptions \
-H "Authorization: Bearer $IAALGERIE_API_KEY" \
-F model="qwen-audio-3.1-asr-flash-filetrans" \
-F file="@reunion.m4a"
Media prices are per image, per second of video or per minute of audio — see the pricing page.
Build a retrieval pipeline for Arabic, French and English documents.
# Embeddings: turn your knowledge base into vectors
emb = client.embeddings.create(
model="text-embedding-v4",
input=["Politique de retour sous 7 jours", "Frais de livraison Yalidine"],
)
vectors = [d.embedding for d in emb.data]
# Rerank: best candidates first, before the chat call
import dashscope # pip install dashscope
ranked = dashscope.TextReRank.call(
model="qwen3-rerank",
query="Quel est le delai de retour ?",
documents=["Politique de retour sous 7 jours",
"Nos horaires d ouverture",
"Frais de livraison Yalidine"],
top_n=2,
return_documents=True,
api_key=os.environ["IAALGERIE_API_KEY"],
)
print(ranked.output.results[0].document.text)
| Status | Meaning | What to do |
|---|---|---|
| 400 | Malformed request | Check the model ID against the catalog. |
| 401 | Invalid or revoked key | Regenerate the key in your console. |
| 402 | Insufficient balance | Top up, or lower the key cap. |
| 429 | Rate limit reached | Retry with exponential backoff. |
| 500 | Upstream error | Retry once, then contact support with the request ID. |
| 503 | Model temporarily unavailable | Fail over to a sibling model in the same family. |
Every response carries your remaining quota and the request ID. Log the request ID — support cannot investigate without it.
import time
from openai import APIStatusError
def ask(messages, model="qwen3.7-plus"):
for attempt in range(5):
try:
r = client.chat.completions.create(model=model, messages=messages)
print("request_id:", r._request_id, "tokens:", r.usage.total_tokens)
return r
except APIStatusError as e:
if e.status_code == 429: # rate limit
time.sleep(2 ** attempt)
continue
if e.status_code == 402: # insufficient balance
raise SystemExit("Top up your IA Algerie balance.")
if e.status_code >= 500: # upstream hiccup
time.sleep(1)
continue
raise
raise RuntimeError("rate limited after 5 attempts")
Five habits that reliably cut an AI bill by half or more.
Route simple intents to Flash. Reserve Max-class models for tasks where a wrong answer costs more than the tokens.
A monthly cap per key turns a runaway loop into a harmless error.
Output tokens usually cost four times input tokens.
Context caching bills repeated prefixes at a reduced rate.
Nightly classification, summarising or embedding jobs do not need real-time responses.
Yes. Set base_url to our endpoint and api_key to your IA Algérie key. Nothing else changes.
Yes, on a separate path. Useful for Claude Code-style tools.
Pin an exact version ID rather than a moving alias so an upstream update never changes your output silently.
Every new account receives a small trial balance so you can validate the integration before paying.
Send the request ID plus the model ID to support. We can replay the call and escalate.
Early accounts get the trial balance, the onboarding call and a direct Telegram line.
Launch phase — spots left for the 100-user beta