एक ही curl में पूरी API
एक पल के लिए 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 with 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 with fetch
Node 18 और नए संस्करणों में fetch शामिल होता है, इसलिए कुछ इंस्टॉल करने की आवश्यकता नहीं है। फ़ाइल को .mjs के रूप में सहेजें (या "type": "module" सेट करें) ताकि टॉप-लेवल await काम करे। ब्राउज़र में भी वही API है, लेकिन कुंजी को फ्रंट-एंड कोड में न रखें। अपनी खुद की बैकएंड के माध्यम से कॉल प्रॉक्सी करें।
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 with net/http
Go में कुछ और पंक्तियों की आवश्यकता होती है, लेकिन किसी निर्भरता (dependency) की नहीं। केवल उन struct फ़ील्ड्स को परिभाषित करें जिन्हें आप पढ़ते हैं; 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)
}उत्पादन (production) के लिए, एक http.Client{Timeout: 60 * time.Second} बनाएँ और उसे पुन: उपयोग करें। डिफ़ॉल्ट क्लाइंट की कोई टाइमआउट नहीं होती है, जिससे एक अटका हुआ अनुरोध एक अटके हुए goroutine में बदल जाता है।
PHP with cURL and Ruby with Net::HTTP
PHP का cURL एक्सटेंशन अधिकांश होस्ट्स पर पहले से मौजूद है। 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 तुरंत अपवाद फेंकता है यदि चर गायब है, जो एक खाली बियरर टोकन भेजने और दस मिनट तक 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 को diff करें, न कि क्लाइंट को। एक बार में रॉ अनुरोध बॉडी प्रिंट करें और बाइट-फॉर-बाइट तुलना करें। नौ बार में से नौ बार दोष एक गायब Content-Type हेडर या एक बड़े अक्षर के साथ टाइप किया गया मॉडल नाम होता है।
Streaming without a library
स्ट्रीमिंग वह एकमात्र स्थिति है जहाँ साधारण HTTP से आपसे थोड़ा अधिक प्रयास की उम्मीद की जाती है। stream: true के साथ, सर्वर server-sent events के साथ उत्तर देता है: प्रत्येक पंक्ति 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()यही पैटर्न सीधे स्थानांतरित (port) होता है। JavaScript में, res.body को एक reader के साथ पढ़ें और नई पंक्तियों पर विभाजित करें। Go में, resp.Body को bufio.Scanner में लपेटें। Ruby में, http.request में एक ब्लॉक पास करें और read_body का उपयोग करें। PHP में, एक CURLOPT_WRITEFUNCTION कॉलबैक सेट करें। तर्क कभी नहीं बदलता: प्रीफ़िक्स हटाएं, सेन्टिनल पर रुकें, JSON पार्स करें, डेल्टा प्रिंट करें।
A five-minute smoke test and a budget check
इनमें से किसी भी स्निपेट के ऊपर बनाने से पहले, एक त्वरित सत्यापन पास चलाएं। पहले, अपनी कुंजी के साथ /v1/models को कॉल करें; 200 कुंजी और नेटवर्क पथ को साबित करता है। दूसरा, max_tokens को 20 पर सेट करके न्यूनतम चैट अनुरोध भेजें। तीसरा, जानबूझकर कुछ तोड़ें, जैसे एक खाली बियरर टोकन, और पुष्टि करें कि आपका कोड 401 को स्पष्ट रूप से दिखाता है, किसी फ़ील्ड की कमी पर क्रैश होने के बजाय।
फिर एक बार अंकगणित करें ताकि कुछ भी हैरान न करे। कीमतें प्रति मिलियन इनपुट टोकन के लिए $0.25 और प्रति मिलियन आउटपुट टोकन के लिए $1.00 हैं। एक उदाहरण के लिए, मान लें कि एक अनुरोध 600 प्रॉम्प्ट टोकन भेजता है और 400 टोकन प्राप्त करता है। यह 600 x $0.25 / 1,000,000 = $0.00015 इन, प्लस 400 x $1.00 / 1,000,000 = $0.0004 आउट, प्रति कॉल लगभग $0.00055 है। $0.50 का ट्रायल क्रेडिट उस आकार की लगभग 900 कॉल को कवर करेगा। आपके वास्तविक प्रॉम्प्ट अलग होंगे, इसलिए कुछ प्रतिक्रियाओं पर usage ब्लॉक पढ़ें और वहां से गुणा करें।
ट्रायल क्रेडिट सात दिनों तक रहता है और भुगतान विवरण की आवश्यकता नहीं होती है, जिससे यह पाँचों भाषाओं की परीक्षण के लिए पर्याप्त है। यदि आप एक उपयोग-केस तय करना चाहते हैं, तो NSFW सामग्री गाइड एक पूर्ण उदाहरण दिखाता है। याद रखें कि एक कुंजी एक खाते से संबंधित होती है; यदि आप इसे पुनः जनरेट करते हैं, तो सभी स्क्रिप्ट्स को एक साथ अपडेट करें, क्योंकि पुरानी कुंजी तुरंत काम करना बंद कर देती है।
Errors that look the same in every language
चूंकि API सादा HTTP है, विफलता हैंडलिंग उस भाषा से स्वतंत्र है जिसे आप चुनते हैं। इस तालिका को याद रखें और आप ऊपर दिए गए किसी भी स्निपेट को पोर्ट कर सकते हैं।
| स्टेटस | अर्थ | कार्रवाई |
|---|---|---|
| 400 | खराब अनुरोध, जैसे प्रॉम्प्ट के साथ max_tokens 100k से अधिक | प्रॉम्प्ट को ट्राइम करें या max_tokens कम करें |
| 401 | गायब या अमान्य कुंजी | API_KEY की जाँच करें; एक पुनर्जनित कुंजी पुरानी कुंजी को तुरंत निष्क्रिय कर देती है |
| 402 | no_credit: शेष राशि समाप्त हो गई है या ट्रायल समाप्त हो गया है | प्रीपेड बैलेंस में टॉप-अप करें |
| 403 | content_blocked | पुनः प्रयास न करें; किशोरों से संबंधित यौन सामग्री हमेशा ब्लॉक की जाती है |
| 429 | प्रति मिनट 300 से अधिक अनुरोध | बैकऑफ़ करें और पुनः प्रयास करें |
| 503 | upstream_busy | कुछ सेकंड में पुनः प्रयास करें |
Once the basics work, set stream: true for token-by-token output and read the server-sent events line by line. Craft better prompts with the prompting guide, or wire the same call into a chat platform using the bot walkthrough. Rates are on the pricing page.