alawadi.cloudDocs

Quickstart

Create an API key in the portal and make your first chat completion with curl, Python, or JavaScript, including streaming.

1. Create an API key

Open AI in the portal (/dashboard/ai) and click New API key.

Name the key after the app or environment that will use it (for example production-backend), optionally set an expiry (1-365 days), and click Create key.

Copy the full sk-alwd-… key now: it is shown exactly once. We store only its hash; if you lose it, revoke it and mint a new one.

Store the key in an environment variable, never in code:

export ALAWADI_AI_KEY="sk-alwd-..."

2. Make your first request

The API is OpenAI-compatible: keep your existing code and SDK, swap only the base URL and the key.

curl https://ai.alawadi.cloud/v1/chat/completions \
  -H "Authorization: Bearer $ALAWADI_AI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen2.5-7b-instruct",
    "messages": [
      {"role": "user", "content": "مرحبا! عرّف عن نفسك بجملة واحدة."}
    ]
  }'
# pip install openai
import os

from openai import OpenAI

client = OpenAI(
    base_url="https://ai.alawadi.cloud/v1",
    api_key=os.environ["ALAWADI_AI_KEY"],
)

resp = client.chat.completions.create(
    model="qwen2.5-7b-instruct",
    messages=[
        {"role": "user", "content": "مرحبا! عرّف عن نفسك بجملة واحدة."}
    ],
)
print(resp.choices[0].message.content)
// npm install openai
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://ai.alawadi.cloud/v1",
  apiKey: process.env.ALAWADI_AI_KEY,
});

const resp = await client.chat.completions.create({
  model: "qwen2.5-7b-instruct",
  messages: [
    { role: "user", content: "مرحبا! عرّف عن نفسك بجملة واحدة." },
  ],
});
console.log(resp.choices[0].message.content);

Every response carries a usage object with exact server-side token counts, which is what you are billed on:

"usage": {
  "prompt_tokens": 21,
  "completion_tokens": 38,
  "total_tokens": 59
}

3. Stream the response

Set "stream": true to receive tokens as they are generated. Streaming is the recommended mode for anything user-facing, because non-streaming requests have a 90-second server-side timeout. The final stream chunk always includes the usage object (the gateway forces this on), so you still get exact counts.

curl -N https://ai.alawadi.cloud/v1/chat/completions \
  -H "Authorization: Bearer $ALAWADI_AI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen2.5-7b-instruct",
    "stream": true,
    "messages": [
      {"role": "user", "content": "مرحبا! عرّف عن نفسك بجملة واحدة."}
    ]
  }'
stream = client.chat.completions.create(
    model="qwen2.5-7b-instruct",
    stream=True,
    messages=[
        {"role": "user", "content": "مرحبا! عرّف عن نفسك بجملة واحدة."}
    ],
)
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)
    if chunk.usage:  # final chunk, exact token counts
        print(f"\n-- {chunk.usage.total_tokens} tokens")
const stream = await client.chat.completions.create({
  model: "qwen2.5-7b-instruct",
  stream: true,
  messages: [
    { role: "user", content: "مرحبا! عرّف عن نفسك بجملة واحدة." },
  ],
});
for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
  if (chunk.usage) console.log(`\n-- ${chunk.usage.total_tokens} tokens`);
}

Prefer streaming for long generations

Non-streaming requests time out server-side after 90 seconds. For long prompts or long answers, always set "stream": true.

Call a tool

The model supports OpenAI-style tool (function) calling: pass a tools array and, when the model decides to use one, the response comes back with tool_calls for your code to execute. Use it non-streaming ("stream": false) — that is the supported, reliable path.

curl https://ai.alawadi.cloud/v1/chat/completions \
  -H "Authorization: Bearer $ALAWADI_AI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen2.5-7b-instruct",
    "stream": false,
    "messages": [
      {"role": "user", "content": "ما حالة الطقس في دمشق؟"}
    ],
    "tools": [{
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "Get the current weather for a city",
        "parameters": {
          "type": "object",
          "properties": {"city": {"type": "string"}},
          "required": ["city"]
        }
      }
    }]
  }'
tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "Get the current weather for a city",
        "parameters": {
            "type": "object",
            "properties": {"city": {"type": "string"}},
            "required": ["city"],
        },
    },
}]

resp = client.chat.completions.create(
    model="qwen2.5-7b-instruct",
    stream=False,
    messages=[{"role": "user", "content": "ما حالة الطقس في دمشق؟"}],
    tools=tools,
)

call = resp.choices[0].message.tool_calls[0]
print(call.function.name)       # get_weather
print(call.function.arguments)  # {"city": "Damascus"}
# Run the function yourself, then send the result back as a
# {"role": "tool", "tool_call_id": call.id, "content": "..."} message.

Use non-streaming for tools

Tool calling is supported and tested in non-streaming mode. Stream normal chat for user-facing text, but set "stream": false when you pass tools so you reliably get structured tool_calls back.

Next: models and pricing · billing and usage · limits and errors.

On this page