PL ▾
https://api.unrestrictedaiapi.com/v1uncensored2026-10-06
Pobierz klucz API

Szybki start Unrestricted AI API: Python, JavaScript, Go, PHP i Ruby

Nie potrzebujesz SDK do korzystania z Unrestricted AI API. Obsługuje zwykły HTTP i JSON, więc zadziała w każdym języku z klientem HTTP. Ta strona zawiera po jednym przetestowanym zapytaniu dla Pythona, JavaScriptu, Go, PHP i Ruby, a także kody statusu do obsłużenia i regułę ponawiania, która zapobiega awariom skryptów.

Zaktualizowano

Kluczowe punkty

  1. Jeden endpoint, jeden ID modelu (uncensored), jeden token bearer: to samo ciało zapytania zadziała w każdym języku.
  2. Ustaw wyraźne limity czasu. Długie generacje mogą przekraczać domyślne limity klientów.
  3. Sprawdzaj kod statusu przed parsowaniem; ciała 402 i 403 to poprawny JSON bez tablicy choices.
  4. Ponawiaj tylko 429 i 503 z krótkim wykładniczym opóźnieniem.

Całe API w jednym curl

Na chwilę zapomnij o SDK. Każda z poniższych przykładowych operacji wysyła to samo: ciało JSON do POST /v1/chat/completions z tokenem Bearer. Jeśli potrafisz to wysłać, masz wszystko. Pobierz klucz ze strony rejestracji (do kredytu próbnego nie są potrzebne dane do płatności), wyeksportuj go jako API_KEY i uruchom to jako pierwszy krok.

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
  }'

Odpowiedź to obiekt w stylu OpenAI. Tekst znajduje się pod choices[0].message.content, a blok usage informuje Cię, ile kosztowało wywołanie w tokenach. Istnieje jeden model, uncensored, więc pole model się nie zmienia. Możesz to potwierdzić przez GET /v1/models.

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

Dwa limity, które warto zapamiętać przed napisaniem jakiegokolwiek kodu: okno kontekstu wynosi 100 000 tokenów dzielonych między prompt a completion, a max_tokens domyślnie wynosi 2048, chyba że podniesiesz tę wartość (do 32 000). Jeśli Twoja odpowiedź ciągle przerywa się w połowie zdania, to właśnie ten domyślny limit jest zazwyczaj winny.

Python z httpx

httpx daje Ci synchronicznego klienta z rozsądnymi limitami czasu i jego asynchroniczną wersję, gdy jest potrzebna. Ustaw limit czasu wyraźnie. Długie generacje mogą trwać długo, a domyślny limit pięciu sekund je przerywa.

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() zamienia każdy kod 4xx lub 5xx na wyjątek, co jest w porządku dla skryptu. W przypadku procesów długotrwałych opakuj wywołanie tak, aby dwa kody statusu miały szansę na ponowienie: 429 (przekroczyłeś limit 300 zapytań na minutę dla klucza) i 503 (upstream_busy, który ustaje po kilku sekundach). Wszystko inne, w tym 401, 402 i 403, nie naprawi się przy ponownym wysłaniu.

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."}]))

Zamień httpx.post na httpx.AsyncClient().post wewnątrz async def i masz wersję asynchroniczną z tym samym payloadem.

JavaScript z fetch

Node 18 i nowsze wersje zawierają fetch, więc nic nie musisz instalować. Zapisz plik jako .mjs (lub ustaw "type": "module"), aby działał top-level await. Przeglądarki mają ten sam interfejs API, ale nie umieszczaj klucza w kodzie frontendowym. Proxyj zapytanie przez własny backend.

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);

Zwróć uwagę na kolejność sprawdzania. fetch odrzuca tylko przy awarii sieci, więc 402 lub 403 przychodzi jako normalna odpowiedź. Sprawdź res.ok samodzielnie i odczytaj błąd JSON, który zawsze ma strukturę {"error":{"code":...,"message":...}}.

Go z net/http

Go potrzebuje kilku więcej linii, ale nie wymaga zależności. Zdefiniuj tylko pola struktury, których używasz; encoding/json zignoruje resztę. Odczyt ciała do bajtów przed sprawdzeniem statusu pozwala wypisać komunikat błędu serwera, gdy coś pójdzie nie tak.

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)
}

W produkcji zbuduj jeden http.Client{Timeout: 60 * time.Second} i go ponownie używaj. Domyślny klient nie ma ustawionego limitu czasu, co jest przyczyną tego, że utknione zapytanie staje się utknioną goroutiną.

PHP z cURL i Ruby z Net::HTTP

Rozszerzenie cURL PHP jest już na większości hostów. Zbuduj ciało z json_encode, zwróć transfer jako string, a następnie odczytaj status przez curl_getinfo. Pominięcie sprawdzenia statusu to klasyczny błąd: ciało 402 dekoduje się bez problemu jako JSON, a Twój kod zawali się na brakującym kluczu 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";

Na wspólnym hoście z niskim max_execution_time, trzymaj max_tokens na umiarkowanym poziomie lub przenieś wywołanie do workera kolejki.

Standardowa biblioteka wystarczy i tutaj. ENV.fetch rzuca wyjątek natychmiast, jeśli brakuje zmiennej, co jest lepsze niż wysłanie pustego tokena Bearer i debugowanie błędu 401 przez dziesięć minut.

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")

Jeśli później przejdziesz na Rails, to samo ciało zadziała z zadania w tle. Trzymaj wywołanie z cyklu żądania; generacje są wolniejsze niż zapytanie do bazy danych.

Oba fragmenty wysyłają dokładnie to samo ciało, co fragment Pythona, o to chodzi: jeśli jeden język działa, a inny nie, porównaj JSON, a nie klienta. Wypisz surowe ciało żądania raz i porównaj bajt po bajcie. Dziewięć razy na dziesięć winnym jest brakujący nagłówek Content-Type lub nazwa modelu wpisana z wielkiej litery.

Strumieniowanie bez bibliotek

Strumieniowanie to jedyne miejsce, gdzie zwykły HTTP prosi Cię o nieco więcej. Przy stream: true serwer odpowiada zdarzeniami wysyłanymi przez serwer: każda linia zaczyna się od data: , zawiera fragment JSON, a strumień kończy się data: [DONE]. Ostateczny fragment usage jest dodawany automatycznie, więc otrzymujesz liczbę tokenów nawet przy strumieniowaniu. Ten fragment nie ma wpisów choices, dlatego pętla poniżej sprawdza przed indeksowaniem.

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()

Ten sam wzorzec można przenieść bezpośrednio. W JavaScript odczytaj res.body za pomocą czytnika i podziel go po znakach nowej linii. W Go opakuj resp.Body w bufio.Scanner. W Ruby przekaż blok do http.request i użyj read_body. W PHP ustaw callback CURLOPT_WRITEFUNCTION. Logika się nie zmienia: usuń prefiks, zatrzymaj się na sentinelu, przeanalizuj JSON, wydrukuj deltę.

Pięciominutowy test i kontrola budżetu

Zanim zbudujesz cokolwiek na podstawie tych fragmentów, wykonaj szybki test. Po pierwsze, wywołaj /v1/models ze swoim kluczem; 200 dowodzi, że klucz i ścieżka sieciowa działają. Po drugie, wyślij najmniejsze zapytanie chat, jakie możesz, z max_tokens ustawionym na 20. Po trzecie, celowo coś zepsuj, np. pusty token bearer, i potwierdź, że Twój kod wyraźnie zwraca 401, zamiast się sypać na brakującym polu.

Następnie wykonaj obliczenia raz, aby nic Cię nie zaskoczyło. Ceny wynoszą $0,25 za milion tokenów wejściowych i $1,00 za milion tokenów wyjściowych. Dla celów ilustracyjnych załóżmy, że zapytanie wysyła 600 tokenów promptu i otrzymuje 400 tokenów odpowiedzi. To 600 x $0,25 / 1 000 000 = $0,00015 in, plus 400 x $1,00 / 1 000 000 = $0,0004 out, około $0,00055 na wywołanie. Kredyt próbny w wysokości $0,50 wystarczyłby na około 900 takich wywołań. Twoje rzeczywiste prompty będą inne, więc przeczytaj blok usage w kilku odpowiedziach i pomnóż wyniki na tej podstawie.

Kredyt próbny ważny jest przez siedem dni i nie wymaga podawania danych do płatności, co w zupełności wystarczy do przetestowania wszystkich pięciu języków. Jeśli chcesz znaleźć przypadek użycia, na który możesz się celować, przewodnik po treści NSFW pokazuje kompletny przykład. Pamiętaj, że jeden klucz należy do jednego konta; jeśli go wygenerujesz ponownie, zaktualizuj wszystkie skrypty jednocześnie, ponieważ stary klucz przestaje działać natychmiast.

Błędy wyglądające tak samo w każdym języku

Ponieważ API to zwykłe HTTP, obsługa błędów jest identyczna niezależnie od wybranego języka. Zapamiętaj tę tabelę i możesz przenieść dowolny z powyższych fragmentów kodu.

StatusZnaczenieAkcja
400Błędne zapytanie, np. prompt plus max_tokens przekraczające 100kSkróć prompt lub obniż max_tokens
401Brakujący lub nieprawidłowy kluczSprawdź API_KEY; wygenerowanie nowego klucza natychmiast unieważnia stary
402no_credit: saldo wyczerpane lub kredyt próbny wygasłDoładować saldo przedpłacone
403content_blockedNie powtarzaj zapytania; treści seksualne z udziałem małoletnich są zawsze blokowane
429Powyżej 300 zapytań na minutęZwolnij i powtórz zapytanie
503upstream_busyPonów zapytanie za kilka sekund

Gdy podstawy zadziałają, ustaw stream: true dla wyjścia token po tokenie i czytaj zdarzenia wysyłane przez serwer (SSE) linia po linii. Stwórz lepsze prompty z poradnikiem promptowania lub podłącz to samo wywołanie do platformy czatu, korzystając z przewodnika po botach. Stawki znajdziesz na stronie z cenami.

Pytania i odpowiedzi

Czy potrzebuję SDK OpenAI, aby wywołać to API?

Nie. Przykłady tutaj używają tylko standardowych narzędzi HTTP dla każdego języka. SDK OpenAI również zadziałają, jeśli wskażesz ich bazowy URL na https://api.unrestrictedaiapi.com/v1.

Jaki identyfikator modelu wysyłam?

Zawsze „uncensored”. Dostępny jest tylko jeden model, a GET /v1/models go wylicza.

Dlaczego moja odpowiedź urwała się w połowie zdania?

Domyślny max_tokens to 2048. Zwiększ go w każdym zapytaniu do 32 000, pod warunkiem, że suma promptu i completionu mieści się w oknie kontekstu 100 000 tokenów.

Które błędy powinien powtarzać mój kod?

Powtórz 429 (limit zapytań) i 503 (upstream_busy) po krótkim opóźnieniu. 400, 401, 402 i 403 wymagają zmiany po Twojej stronie, więc ich powtarzanie marnuje zapytania.

Twój klucz jest o jeden formularz stąd

Utwórz konto, skopiuj klucz, zmień bazowy URL. To cała konfiguracja.

Pobierz klucz API