بدء سريع
أرسل أول طلب: احصل على مفتاحك، وأرسل رسالة واحدة، واقرأ الرد. تتحدث API بصيغتي OpenAI وAnthropic، فيعمل SDK الذي تستخدمه أصلاً بعد أن تغيّر base URL والمفتاح.
1. احصل على مفتاحك
لكل حساب مفتاح API واحد. سجّل الدخول وافتح Keys & usage وانسخه. يعمل المفتاح على كل نقطة نهاية وكل نموذج. المفاتيح والاستخدام
2. وجّه عميلك إلى API
كل نقاط النهاية تحت base URL واحد. يقبله OpenAI SDK مع /v1 في آخره؛ ويقبله Anthropic SDK بدونها، لأنه يضيف /v1/messages بنفسه.
| العميل | Base URL |
|---|---|
| OpenAI SDKs والعملاء المتوافقون مع OpenAI | https://api.shannon-ai.com/v1 |
| Anthropic SDKs | https://api.shannon-ai.com |
ثلاث نقاط نهاية تنتج النصوص. وهي تصل إلى النماذج نفسها؛ فاختر التي يستخدم كودك صيغتها أصلاً.
| نقطة النهاية (Endpoint) | الصيغة |
|---|---|
POST /v1/chat/completions | OpenAI Chat Completions |
POST /v1/messages | Anthropic Messages |
POST /v1/responses | OpenAI Responses |
3. أرسل أول طلب
أرسل رسالة user واحدة إلى shannon-3 على نقطة نهاية Chat Completions. واستبدل YOUR_API_KEY بمفتاحك.
POST https://api.shannon-ai.com/v1/chat/completions
from openai import OpenAI
client = OpenAI(
api_key="YOUR_API_KEY",
base_url="https://api.shannon-ai.com/v1"
)
response = client.chat.completions.create(
model="shannon-3",
messages=[
{"role": "user", "content": "Hello, Shannon!"}
],
max_tokens=1024
)
print(response.choices[0].message.content) import OpenAI from 'openai';
const client = new OpenAI({
apiKey: 'YOUR_API_KEY',
baseURL: 'https://api.shannon-ai.com/v1'
});
const response = await client.chat.completions.create({
model: 'shannon-3',
messages: [
{ role: 'user', content: 'Hello, Shannon!' }
],
max_tokens: 1024
});
console.log(response.choices[0].message.content); package main
import (
"context"
"fmt"
openai "github.com/sashabaranov/go-openai"
)
func main() {
config := openai.DefaultConfig("YOUR_API_KEY")
config.BaseURL = "https://api.shannon-ai.com/v1"
client := openai.NewClientWithConfig(config)
resp, err := client.CreateChatCompletion(
context.Background(),
openai.ChatCompletionRequest{
Model: "shannon-3",
Messages: []openai.ChatCompletionMessage{
{Role: "user", Content: "Hello, Shannon!"},
},
MaxTokens: 1024,
},
)
if err != nil {
panic(err)
}
fmt.Println(resp.Choices[0].Message.Content)
} curl -X POST "https://api.shannon-ai.com/v1/chat/completions" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "shannon-3",
"messages": [
{"role": "user", "content": "Hello, Shannon!"}
],
"max_tokens": 1024
}' | الحقل | النوع | الافتراضي | الوصف |
|---|---|---|---|
model | string | معرّف النموذج الذي يجيب. المعرّفات مسرودة في Models & pricing. | |
messages | array | المحادثة حتى الآن: كائنات فيها role وcontent. آخر رسالة user هي المطالبة. مطلوب. | |
max_tokens | integer | 4096 | ميزانية مخرجات الطلب، من 1 إلى 65,536. يحجز الطلب هذا المقدار من رصيدك ويُحاسَب على ما استخدمه فعلاً. |
stream | boolean | false | true يرسل الإجابة قطعة قطعة أثناء كتابتها. |
نص الطلب بصيغة JSON ويحتاج إلى الترويسة Content-Type: application/json. والقائمة الكاملة للحقول في صفحة نقطة النهاية. Chat Completions
الرد
المكالمة بدون stream تعيد كائن JSON واحداً عند اكتمال الإجابة. والنصوص والأرقام أدناه أمثلة.
{
"id": "chatcmpl-9b2f6c1e4a7d4f0f8a3c5d2e1b6a7c90",
"object": "chat.completion",
"created": 1791590400,
"model": "shannon-3",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Hello! What would you like to work on?",
"reasoning_content": "A greeting. A short, friendly reply fits."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 1386,
"completion_tokens": 74,
"total_tokens": 1460
}
} | الحقل | النوع | الوصف |
|---|---|---|
id | string | chatcmpl- متبوعاً بـ 32 رمزاً سداسياً عشرياً. |
object | string | دائماً chat.completion. |
created | integer | وقت الرد بثواني Unix. |
model | string | المعرّف المنشور للنموذج الذي أجاب، حتى عندما ترسل اسماً مستعاراً أو صيغة أخرى. |
choices | array | إدخال واحد دائماً، مع index يساوي 0. |
choices[0].message.role | string | دائماً assistant. |
choices[0].message.content | string | null | الإجابة. وقد تكون null عندما يحمل الرد tool_calls. |
choices[0].message.reasoning_content | string | null | استدلال النموذج قبل إجابته، أو null إن لم يوجد. |
choices[0].message.tool_calls | array | توجد فقط عندما يستدعي النموذج إحدى الأدوات التي أعلنتها. |
choices[0].finish_reason | string | stop للإجابة، وtool_calls عندما يستدعي النموذج أداة. |
usage.prompt_tokens | integer | الـ tokens التي قرأها النموذج لهذه الإجابة. وفي shannon-2-* وعائلة Shannon 3 قد يزيد هذا على النص الذي أرسلته. |
usage.completion_tokens | integer | الـ tokens التي كتبها النموذج. |
usage.total_tokens | integer | المجموع. وتُحسب تكلفة نموذج Shannon من هذا الرقم. |
- يحتوي
usageعلى أعداد tokens، لا على مال. وما أخذته المكالمة من رصيدك يظهر لكل طلب في Keys & usage؛ وطريقة حسابه في صفحة الحدود والرصيد. الحدود والرصيد - يحمل كل رد، ومنه الخطأ والبث، الترويسة
x-request-id. وإذا كان طلبك يحمل ترويسةx-request-idفإن قيمتها تعود؛ وإلا فالقيمة 12 حرفاً سداسياً عشرياً. احتفظ بها في سجلاتك: فهي تسمّي هذا الطلب وحده.
المكالمة نفسها كبث
اضبط stream على true لقراءة الإجابة أثناء كتابتها. وكل ما عدا ذلك في الطلب يبقى كما هو.
from openai import OpenAI
client = OpenAI(
api_key="YOUR_API_KEY",
base_url="https://api.shannon-ai.com/v1"
)
stream = client.chat.completions.create(
model="shannon-3",
messages=[
{"role": "user", "content": "Hello, Shannon!"}
],
max_tokens=1024,
stream=True
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True) import OpenAI from 'openai';
const client = new OpenAI({
apiKey: 'YOUR_API_KEY',
baseURL: 'https://api.shannon-ai.com/v1'
});
const stream = await client.chat.completions.create({
model: 'shannon-3',
messages: [
{ role: 'user', content: 'Hello, Shannon!' }
],
max_tokens: 1024,
stream: true
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
} curl -N -X POST "https://api.shannon-ai.com/v1/chat/completions" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "shannon-3",
"messages": [
{"role": "user", "content": "Hello, Shannon!"}
],
"max_tokens": 1024,
"stream": true
}' كل إطار في البث سطر واحد يبدأ بـ data: ويحتوي على كائن JSON. إطار واحد، مطبوع على عدة أسطر:
{
"id": "chatcmpl-9b2f6c1e4a7d4f0f8a3c5d2e1b6a7c90",
"object": "chat.completion.chunk",
"created": 1791590400,
"model": "shannon-3",
"choices": [
{
"index": 0,
"delta": {
"content": "Hello! "
},
"finish_reason": null
}
]
} | الإطارات، بالترتيب | delta | finish_reason |
|---|---|---|
| أثناء استدلال النموذج. صفر إطار أو أكثر. | {"reasoning_content": "…"} | null |
| الإجابة، قطعة قطعة. صفر إطار أو أكثر. | {"content": "…"} | null |
آخر إطار JSON. وهو يحمل أيضاً usage؛ ولا تحتاج إلى طلبه. | {} | "stop" |
نهاية البث: السطر data: [DONE]. |
- للرد الحالة
200وcontent-type: text/event-stream. وكل إطار سطرdata: <json>يتبعه سطر فارغ. - يصل السطر
: pingكل 15 ثانية. وهو تعليق يُبقي الاتصال مفتوحاً؛ وتتخطاه عملاء SSE. - الفشل بعد أن يُفتح البث يصل كإطار
data: {"error": {…}}. وتبقى الحالة200، فافحص الإطارات.
إذا فشلت المكالمة
الخطأ كائن JSON فيه error يحتوي على type وmessage. وهذه هي الردود التي تواجهها المكالمة الأولى في أغلب الأحيان.
| الحالة | النوع | الرسالة | ماذا تعني |
|---|---|---|---|
401 | authentication_error | Missing authentication | لم يصل أي مفتاح إلى API. أرسل Authorization: Bearer متبوعاً بمفتاحك. |
401 | authentication_error | Invalid API key | المفتاح ليس المفتاح الحالي لأي حساب. انسخه مجدداً من Keys & usage. |
400 | invalid_request_error | unknown model: <id> | model ليس معرّفاً منشوراً. استخدم معرّفاً من Models & pricing. |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type… | نوع JSON لأحد الحقول خاطئ، أو أن messages مفقود. |
429 | rate_limit_error | Quota exceeded. Upgrade your plan at shannon-ai.com/plan | ميزانية مخرجات الطلب لا تتسع في رصيدك. |
إلى أين تذهب بعد ذلك
- النماذج والأسعار — اختر نموذجاً: المعرّفات ونوافذ السياق والأسعار.
- Chat Completions — كل حقل طلب وحقل رد وحدث بث في نقطة النهاية التي استدعيتها.
- البث — إطارات البث وأسطر keep-alive والأخطاء داخل البث.
- استدعاء الدوال — دع النموذج يستدعي دوالك.
- الحدود والرصيد — ما يحجزه الطلب وما يكلّفه، وكم طلباً يمكنك إرساله.
- ساحة لعب API — جرّب الطلبات في المتصفح بمفتاحك.