AR ▾
https://api.unrestrictedaiapi.com/v1uncensored2026-10-06
احصل على مفتاح API

البدء السريع مع Unrestricted AI API: Python وJavaScript وGo وPHP وRuby

لا تحتاج إلى SDK لاستخدام Unrestricted AI API. يتكلم HTTP عادي وJSON، لذا تعمل أي لغة تحتوي على عميل HTTP. توفر لك هذه الصفحة طلباً واحداً مجرباً لكل من Python وJavaScript وGo وPHP وRuby، بالإضافة إلى أكواد الحالة التي يجب التعامل معها وقاعدة إعادة المحاولة التي تمنع توقف السكربتات.

تم التحديث

نقاط رئيسية

  1. نقطة نهاية واحدة، ومعرف نموذج واحد (بدون رقابة)، وBearer token واحد: نفس جسم الطلب يعمل في كل اللغات.
  2. حدد فترات زمنية صريحة. عمليات التوليد الطويلة تتجاوز معظم فترات الانتظار الافتراضية للعميل.
  3. تحقق من رمز الحالة قبل التحليل؛ أجوبة 402 و403 هي JSON صالح بدون مصفوفة choices.
  4. أعد المحاولة فقط مع 429 و503، مع زيادة عكسية قصيرة.

الـ API بالكامل في أمر curl واحد

انسَ الـ SDK للحظة. كل الأمثلة أدناه ترسل نفس الشيء: جسم JSON إلى POST /v1/chat/completions مع رمز Bearer. إذا استطعت إرسال ذلك، فقد أنهيت المهمة. احصل على مفتاح من صفحة التسجيل (لا يتطلب الرصيد التجريبي تفاصيل الدفع)، صدّره كـ API_KEY، وشغّل هذا أولاً.

curl https://api.unrestrictedaiapi.com/v1/chat/completions \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "uncensored",
    "messages": [{"role": "user", "content": "Write a two-line noir opening set in a laundromat."}],
    "max_tokens": 120
  }'

الرد هو كائن بأسلوب OpenAI. النص موجود عند choices[0].message.content، ويخبرك كتلة usage بتكلفة المكالمة بالرموز. يوجد نموذج واحد، uncensored، لذا لا يتغير حقل model أبدًا. يمكنك تأكيد ذلك بـ GET /v1/models.

curl https://api.unrestrictedaiapi.com/v1/models -H "Authorization: Bearer $API_KEY"

حدان يستحقان الحفظ قبل كتابة أي كود: نافذة السياق هي 100,000 رمز مشتركة بين الموجّه والإكمال، وmax_tokens افتراضياً 2048 ما لم ترفعه (حتى 32,000). إذا كان إخراجك يتوقف فجأة، فهذا الافتراضي هو السبب المعتاد.

Python مع httpx

يوفر لك httpx عميلاً متزامناً مع مهلات معقولة ونظيراً غير متزامن عند الحاجة. اضبط المهلة صراحة. يمكن أن تستغرق التوليدات الطويلة وقتاً طويلاً، وسيؤدي الافتراضي لخمس ثوانٍ إلى قطعها.

import os
import httpx

resp = httpx.post(
    "https://api.unrestrictedaiapi.com/v1/chat/completions",
    headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
    json={
        "model": "uncensored",
        "messages": [
            {"role": "system", "content": "You are a blunt, vivid fiction writer."},
            {"role": "user", "content": "Pitch a heist where the vault is a night market."},
        ],
        "temperature": 0.9,
        "max_tokens": 300,
    },
    timeout=60.0,
)
resp.raise_for_status()
print(resp.json()["choices"][0]["message"]["content"])

يحوّل raise_for_status() أي خطأ 4xx أو 5xx إلى استثناء، وهو أمر جيد للسكربتات. لأي شيء طويل الأمد، لف الاستدعاء بحيث تحصل حالتان على فرصة أخرى: 429 (لقد وصلت إلى حد المفتاح البالغ 300 طلب في الدقيقة) و503 (upstream_busy، الذي يزول في بضع ثوانٍ). كل شيء آخر، بما في ذلك 401 و402 و403، لن يصلح نفسه عند إعادة المحاولة.

import os
import time
import httpx

def chat(messages, retries=3):
    for attempt in range(retries + 1):
        r = httpx.post(
            "https://api.unrestrictedaiapi.com/v1/chat/completions",
            headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
            json={"model": "uncensored", "messages": messages, "max_tokens": 400},
            timeout=60.0,
        )
        if r.status_code in (429, 503) and attempt < retries:
            time.sleep(2 ** attempt)
            continue
        r.raise_for_status()
        return r.json()["choices"][0]["message"]["content"]

print(chat([{"role": "user", "content": "Name five cursed objects found in a thrift store."}]))

استبدل httpx.post بـ httpx.AsyncClient().post داخل async def وستحصل على النسخة غير المتزامنة بنفس الحمولة.

JavaScript مع fetch

تأتي Node 18 وما بعدها مع fetch، لذا لا يوجد شيء لتثبيته. احفظ الملف باسم .mjs (أو اضبط "type": "module") حتى يعمل await على المستوى الأعلى. المتصفحات لها نفس الواجهة، لكن لا تضع المفتاح في كود الواجهة الأمامية. Proxy الاستدعاء عبر الخادم الخلفي الخاص بك.

const res = await fetch("https://api.unrestrictedaiapi.com/v1/chat/completions", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "uncensored",
    messages: [{ role: "user", content: "Describe a villain's morning routine in four bullets." }],
    max_tokens: 250,
  }),
});

if (!res.ok) {
  const err = await res.json().catch(() => ({}));
  throw new Error(`HTTP ${res.status}: ${err?.error?.message ?? "unknown error"}`);
}

const data = await res.json();
console.log(data.choices[0].message.content);

انتبه لترتيب الفحوصات. fetch يرفض فقط عند فشل الشبكة، لذا يصل 402 أو 403 كاستجابة عادية. اختبر res.ok بنفسك واقرأ JSON الخطأ، الذي له دائمًا الشكل {"error":{"code":...,"message":...}}.

Go مع net/http

Go يحتاج إلى أسطر أكثر قليلاً ولكن بدون تبعيات. عرّف فقط حقول الهيكل التي تقرأها؛ يتجاهل encoding/json الباقي. قراءة الجسم كبايتات قبل التحقق من الحالة يتيح لك طباعة رسالة خطأ الخادم عند حدوث خطأ.

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"
)

type reply struct {
	Choices []struct {
		Message struct {
			Content string `json:"content"`
		} `json:"message"`
	} `json:"choices"`
}

func main() {
	payload, _ := json.Marshal(map[string]any{
		"model": "uncensored",
		"messages": []map[string]string{
			{"role": "user", "content": "Give me a ghost story in exactly three sentences."},
		},
		"max_tokens": 200,
	})

	req, _ := http.NewRequest("POST", "https://api.unrestrictedaiapi.com/v1/chat/completions", bytes.NewReader(payload))
	req.Header.Set("Authorization", "Bearer "+os.Getenv("API_KEY"))
	req.Header.Set("Content-Type", "application/json")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)
	if resp.StatusCode != http.StatusOK {
		panic(fmt.Sprintf("HTTP %d: %s", resp.StatusCode, body))
	}

	var out reply
	if err := json.Unmarshal(body, &out); err != nil {
		panic(err)
	}
	fmt.Println(out.Choices[0].Message.Content)
}

للإنتاج، ابنِ http.Client{Timeout: 60 * time.Second} وأعد استخدامه. العميل الافتراضي ليس لديه فترة انتظار على الإطلاق، وهو ما يجعل الطلب العالق يصبح خيطًا عالقًا.

PHP مع cURL وRuby مع Net::HTTP

امتداد cURL في PHP موجود بالفعل على معظم الخوادم. أنشئ الجسم باستخدام json_encode، أعد النقل كنص، ثم اقرأ الحالة باستخدام curl_getinfo. تخطي فحص الحالة هو الخطأ الكلاسيكي: جسم الاستجابة 402 يُحلّل كـ JSON بنجاح، ثم يفشل الكود الخاص بك عند البحث عن المفتاح choices المفقود.

<?php
$payload = json_encode([
    "model" => "uncensored",
    "messages" => [
        ["role" => "user", "content" => "Write a villanelle opening about a broken vending machine."],
    ],
    "max_tokens" => 200,
]);

$ch = curl_init("https://api.unrestrictedaiapi.com/v1/chat/completions");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 60,
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer " . getenv("API_KEY"),
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => $payload,
]);

$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($body === false || $status !== 200) {
    fwrite(STDERR, "HTTP $status: $body\n");
    exit(1);
}

$data = json_decode($body, true);
echo $data["choices"][0]["message"]["content"], "\n";

على مضيف مشترك ذي max_execution_time منخفض، حافظ على max_tokens متواضعًا أو انقل المكالمة إلى عامل قائمة انتظار.

المكتبة القياسية كافية هنا أيضاً. يرفع ENV.fetch فوراً إذا كان المتغير مفقوداً، وهو أفضل من إرسال رمز Bearer فارغ وتصحيح خطأ 401 لمدة عشر دقائق.

require "net/http"
require "json"
require "uri"

uri = URI("https://api.unrestrictedaiapi.com/v1/chat/completions")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV.fetch('API_KEY')}"
req["Content-Type"] = "application/json"
req.body = JSON.generate(
  model: "uncensored",
  messages: [{ role: "user", content: "Invent a tavern rumor that sounds too specific to be fake." }],
  max_tokens: 200
)

res = Net::HTTP.start(uri.host, uri.port, use_ssl: true, read_timeout: 60) { |http| http.request(req) }
abort("HTTP #{res.code}: #{res.body}") unless res.is_a?(Net::HTTPSuccess)

puts JSON.parse(res.body).dig("choices", 0, "message", "content")

إذا انتقلت لاحقًا إلى Rails، يعمل نفس الجسم من وظيفة خلفية. أبقي المكالمة خارج دورة الطلب؛ عمليات التوليد أبطأ من استعلام قاعدة البيانات.

ترسل كلا القطعتين نفس الجسم الذي ترسله نسخة Python، وهو الهدف: إذا نجحت لغة وفشلت أخرى، قارن الـ JSON، وليس العميل. اطبع جسم الطلب الخام مرة واحدة وقارن بايتًا لبايت. في تسع حالات من أصل عشر، يكون السبب هو رأس Content-Type المفقود أو اسم النموذج المكتوب بحرف كبير.

البث المتدفق بدون مكتبة

البث المتدفق هو المكان الوحيد حيث يطلب HTTP العادي منك المزيد. مع stream: true، يجيب الخادم بأحداث مرسلة من الخادم: كل سطر يبدأ بـ data: ، يحمل قطعة JSON، وينتهي البث بـ data: [DONE]. تضاف قطعة استخدام نهائية تلقائياً، لذا تحصل على عدد الرموز حتى عند البث. هذه القطعة لا تحتوي على مدخلات choices، وهو السبب في فحص الحلقة أدناه قبل الفهرسة.

import json
import os
import httpx

body = {
    "model": "uncensored",
    "messages": [{"role": "user", "content": "Tell a campfire story about a lighthouse keeper."}],
    "stream": True,
    "max_tokens": 400,
}
headers = {"Authorization": f"Bearer {os.environ['API_KEY']}"}

with httpx.stream("POST", "https://api.unrestrictedaiapi.com/v1/chat/completions",
                  headers=headers, json=body, timeout=60.0) as r:
    r.raise_for_status()
    for line in r.iter_lines():
        if not line.startswith("data: "):
            continue
        data = line[6:]
        if data == "[DONE]":
            break
        chunk = json.loads(data)
        if chunk.get("choices"):
            print(chunk["choices"][0]["delta"].get("content") or "", end="", flush=True)
print()

نفس النمط ينقل مباشرة. في JavaScript، اقرأ res.body باستخدام قارئ وقسم على الأسطر الجديدة. في Go، لف resp.Body في bufio.Scanner. في Ruby، مرر كتلة إلى http.request واستخدم read_body. في PHP، اضبط استدعاء CURLOPT_WRITEFUNCTION. المنطق لا يتغير أبداً: احذف السبق، توقف عند العلامة، قم بتحليل JSON، اطبع التغيير.

اختبار دخاني لمدة خمس دقائق وفحص الميزانية

قبل أن تبني على أي من هذه القطع، قم بجولة تحقق سريعة. أولاً، استدعِ /v1/models بمفتاحك؛ يثبت 200 صحة المفتاح ومسار الشبكة. ثانيًا، أرسل أصغر طلب دردشة ممكنًا مع تعيين max_tokens إلى 20. ثالثًا، أفسد شيئًا عمدًا، مثل Bearer token فارغ، وتأكد من أن كودك يعرض خطأ 401 بوضوح بدلاً من الانهيار بسبب حقل مفقود.

ثم قم بالحساب مرة واحدة حتى لا تفاجئك أي شيء. الأسعار هي $0.25 لكل مليون رمز إدخال و$1.00 لكل مليون رمز إخراج. بافتراض للتوضيح، لنفترض أن الطلب يرسل 600 رمز موجّه ويستقبل 400 رمز. هذا يعني 600 × $0.25 / 1,000,000 = $0.00015 للدخل، زائد 400 × $1.00 / 1,000,000 = $0.0004 للخروج، أي حوالي $0.00055 لكل استدعاء. رصيد التجربة بقيمة $0.50 سيغطي حوالي 900 استدعاء بهذا الحجم. ستختلف مطالباتك الحقيقية، لذا اقرأ كتلة usage في بعض الاستجابات واضرب من هناك.

يدوم الرصيد التجريبي لمدة سبعة أيام ولا يتطلب تفاصيل الدفع، مما يجعله كافياً لاختبار اللغات الخمس. إذا كنت تريد حالة استخدام لتهدف إليها، فإن دليل محتوى NSFW يظهر مثالاً كاملاً. تذكر أن المفتاح الواحد ينتمي إلى حساب واحد؛ إذا جددته، قم بتحديث كل السكربتات في وقت واحد، لأن المفتاح القديم يتوقف عن العمل فوراً.

الأخطاء التي تبدو متشابهة في كل اللغات

نظرًا لأن الـ API هو HTTP عادي، فإن معالجة الفشل متطابقة بغض النظر عن اللغة التي تختارها. احفظ هذا الجدول ويمكنك نقل أي قطعة أعلاه.

الحالةالمعنىالإجراء
400طلب غير صالح، مثل مجموع الـ prompt وmax_tokens يتجاوز 100kاختصر الـ prompt أو اخفض max_tokens
401مفتاح مفقود أو غير صالحتحقق من API_KEY؛ يؤدي مفتاح مُعاد توليده إلى إلغاء المفتاح القديم فوراً
402no_credit: الرصيد مستنفد أو انتهت صلاحية التجربةقم بشحن رصيد مسبق الدفع
403content_blockedلا تعيد المحاولة؛ محتوى الجنس الذي ينطوي على قاصرين يتم حظره دائماً
429أكثر من 300 طلب في الدقيقةتراجع وأعد المحاولة
503upstream_busyأعد المحاولة بعد بضع ثوانٍ

بمجرد عمل الأساسيات، اضبط stream: true للإخراج رمزاً تلو الآخر واقرأ أحداث مرسلة من الخادم سطراً بسطر. صيغ الموجّهات بشكل أفضل مع دليل الموجّه، أو قم بتوصيل نفس الاستدعاء إلى منصة دردشة باستخدام دليل البوت. الأسعار موجودة في صفحة الأسعار.

أسئلة وأجوبة

هل أحتاج إلى SDK الخاص بـ OpenAI لاستدعاء هذه الـ API؟

لا. تستخدم الأمثلة هنا فقط أدوات HTTP القياسية لكل لغة. تعمل أيضاً SDKs الخاصة بـ OpenAI إذا وجهت عنوان URL الأساسي الخاص بها إلى https://api.unrestrictedaiapi.com/v1.

أي معرف نموذج أرسله؟

دائماً "uncensored". يوجد نموذج واحد فقط، وقائمة GET /v1/models تعرضه.

لماذا توقفت استجابتي في منتصف جملة؟

القيمة الافتراضية لـ max_tokens هي 2048. ارفعها لكل طلب، حتى 32,000، طالما أن مجموع الموجّه والإكمال يبقى داخل نافذة السياق ذات الـ 100,000 رمز.

أي الأخطاء يجب أن يعيد كودي المحاولة؟

أعد المحاولة مع 429 (حدّ المعدل) و 503 (upstream_busy) بعد تأخير قصير. الأخطاء 400، 401، 402 و 403 تحتاج إلى تغيير من جانبك، لذا فإن إعادة المحاولة فيها تضييع للمكالمات.

مفتاحك على بُعد نموذج واحد

أنشئ حساباً، انسخ المفتاح، غيّر عنوان URL الأساسي. هذا هو الإعداد الكامل.

احصل على مفتاح API