# Otwarte API

> Zgodny z OpenAI punkt końcowy dla twoich postaci.

Source: https://reverie.im/pl/docs/integrations/open-api
Language: pl

Reverie udostępnia punkt końcowy Chat Completions zgodny z OpenAI. Skieruj na niego dowolnego klienta OpenAI, przekaż klucz API Reverie i w polu `model` podaj **postać albo scenariusz** zamiast modelu językowego. Rozmowę, wspomnienia i streszczenia Reverie trzyma po swojej stronie, więc każde żądanie potrzebuje tylko twojej nowej wiadomości.

Może z niego korzystać każde zalogowane konto. Nie ma progu subskrypcji ani listy oczekujących — potrzebujesz klucza API i tyle. [Utwórz klucz →](https://reverie.im/pl/docs/integrations/api-keys)

## Adres bazowy i uwierzytelnianie \[#base-url-and-auth]

```
https://reverie.im/api/device/v1
Authorization: Bearer rk_...
```

**Ustawienia → Więcej → Klucze API** pokazują dokładny adres bazowy na karcie **API Endpoint**, razem z przyciskiem kopiowania.

> **To jest API po stronie serwera.** Żądania z przeglądarki z innego źródła są blokowane, więc fetch z twojej własnej strony internetowej nie powiedzie się bez względu na klucz. Wywołuj je z backendu, a klucz trzymaj poza kodem klienta.

## Szybki start \[#quick-start]

**cURL**

```bash
curl --no-buffer https://reverie.im/api/device/v1/chat/completions \
  -H "Authorization: Bearer $REVERIE_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary '{
  "model": "Luna [abc12345]",
  "messages": [
    {
      "role": "user",
      "content": "Hi"
    }
  ],
  "stream": true,
  "temperature": 0.8
}'
```

**Python**

```python
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["REVERIE_API_KEY"],
    base_url="https://reverie.im/api/device/v1",
)

stream = client.chat.completions.create(
    model="Luna [abc12345]",   # an id from GET /models, a full character or scenario ID, or omit entirely
    messages=[{"role": "user", "content": "Hi"}],
    stream=True,
    temperature=0.8,
)

for chunk in stream:
    print(chunk.choices[0].delta.content or "", end="")
```

**TypeScript**

```ts
import OpenAI from "openai";

const client = new OpenAI({
	apiKey: process.env.REVERIE_API_KEY,
	baseURL: "https://reverie.im/api/device/v1",
});

const stream = await client.chat.completions.create({
	model: "Luna [abc12345]",
	messages: [{ role: "user", content: "Hi" }],
	stream: true,
	temperature: 0.8,
});

for await (const chunk of stream) {
	process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}
```

**Ustawienia → Więcej → Klucze API** mają też kreator żądań, który generuje te trzy fragmenty na podstawie jednego z twoich prawdziwych kluczy i prawdziwej postaci.

## Pole `model` wskazuje postać \[#the-model-field-names-a-character]

> **Samo imię postaci nie zadziała.** `model: "Luna"` nie wyszukuje postaci o imieniu Luna. Nie pasuje do niczego, spada na domyślną postać klucza albo na twoją najnowszą rozmowę, i dostajesz odpowiedź od innej postaci bez żadnego błędu. Zawsze używaj formy `Imię [krótkieid]`, którą zwraca `GET /models`.

| Wartość `model`                            | Kto odpowiada                                                                          |
| ------------------------------------------ | -------------------------------------------------------------------------------------- |
| `Luna [abc12345]`                          | Postać albo scenariusz, którego ID kończy się tymi 8 znakami                           |
| Pełne ID postaci albo scenariusza          | Ta postać albo ten scenariusz                                                          |
| ID modelu Reverie, np. `deepseek-v4-flash` | Wybiera **model językowy**; postać bierze się z klucza albo z twojej ostatniej rozmowy |
| Pominięte                                  | Postać przypięta do klucza, a jeśli jej nie ma — twoja najnowsza rozmowa               |

Szczegóły, które decydują, czy krótkie ID się rozwiąże:

* `[...]` musi być na **końcu** tekstu.
* Końcówkę o długości 8 znaków lub mniej porównuje się wyłącznie z postaciami, **z którymi masz już rozmowę** — w sieci albo przez API. Krótkie ID postaci, której nigdy nie otworzyłeś, przepada po cichu.
* Wyszukiwanie scenariusza uruchamia się tylko wtedy, gdy klucz jest przypięty do postaci. Przy kluczu globalnym krótkie ID scenariusza nigdy się nie rozwiąże.
* Więcej niż 8 znaków traktuje się jak pełne ID.

### Sprawdzanie, z kim możesz rozmawiać \[#listing-what-you-can-talk-to]

```bash
curl https://reverie.im/api/device/v1/models \
  -H "Authorization: Bearer $REVERIE_API_KEY"
```

Klucz **globalny** zwraca twoje ostatnie postacie. Klucz **przypięty do postaci** zwraca zamiast tego scenariusze tej postaci, a jeśli żadnego nie ma — samą postać. Każdy wpis wygląda tak:

```json
{
	"id": "Luna [abc12345]",
	"object": "model",
	"created": 1759200000,
	"owned_by": "character",
	"permission": [],
	"root": "<full character id>",
	"parent": null
}
```

Skopiuj `id` prosto do `model`. Błędy tego punktu końcowego mają prostą postać, a nie kopertę OpenAI.

## Co jest czytane z treści żądania \[#what-the-request-body-reads]

Czytane są cztery pola. Cała reszta jest przyjmowana i po cichu odrzucana.

| Pole          | Typ              | Domyślnie                                    | Uwagi                                                        |
| ------------- | ---------------- | -------------------------------------------- | ------------------------------------------------------------ |
| `messages`    | tablica          | wymagane                                     | Patrz niżej — używana jest tylko część                       |
| `model`       | tekst            | opcjonalne                                   | Postać, scenariusz albo model językowy, jak wyżej            |
| `stream`      | wartość logiczna | **`true`**                                   | W odróżnieniu od API OpenAI strumieniowanie jest tu domyślne |
| `temperature` | liczba 0–2       | ustawienie postaci, w przeciwnym razie `0.8` | Wartości spoza zakresu są odrzucane                          |

Ignorowane bez ostrzeżenia: `max_tokens`, `top_p`, `n`, `stop`, `presence_penalty`, `frequency_penalty`, `logit_bias`, `seed`, `user`, `response_format`, `tools`, `tool_choice`, `logprobs`, `stream_options`.

Jak traktowane jest `messages`:

* **Wiadomości `system` są odrzucane.** Osobowość i zachowanie biorą się z własnych pól postaci, a nie z żądania. [Pola promptu →](https://reverie.im/pl/docs/characters/prompt-fields)
* **Nie ma obsługi obrazu.** Treść może być tekstem albo tablicą części, ale czytane są tylko części `text`; części obrazkowe są ignorowane.
* Do rozmowy dopisywana jest tylko \*\*ostatnia wiadomość `user`\*\*. Wcześniejsze wiadomości użytkownika są ignorowane.
* Wiadomości asystenta służą wyłącznie do synchronizacji historii (niżej).
* Pusta lub złożona z samych spacji ostatnia wiadomość użytkownika zwraca `missing_user_message`.

## Odpowiedzi \[#responses]

Odpowiedź bez strumieniowania to zwykły obiekt `chat.completion`. `finish_reason` zawsze wynosi `stop` — wewnętrzne wywołania narzędzi nigdy nie są pokazywane — a liczniki `usage` są wyzerowane, więc tokeny mierz statystykami użycia na stronie kluczy API, a nie z odpowiedzi.

Odpowiedź strumieniowa to `text/event-stream`:

1. Fragmenty treści: obiekty `chat.completion.chunk` z `delta.content`. \*&#x2A;Początkowy fragment `delta: {"role": "assistant"}` nie jest wysyłany.*\*
2. Fragment kończący, z `finish_reason` równym `stop`, `length` albo `content_filter`. Zakończenia wywołane przez narzędzie raportowane są jako `stop`.
3. Fragment użycia z pustą tablicą `choices`.
4. `data: [DONE]`.

Jeśli generowanie padnie w połowie strumienia, strumień wysyła `data: {"error": {...}}`, a potem `[DONE]`.

## Stan rozmowy \[#conversation-state]

Rozmowę przechowuje Reverie. Na każdą parę klucz-postać przypada jedna rozmowa, widać ją w aplikacji webowej obok twoich pozostałych rozmów, a każda tura budowana jest z promptu systemowego i scenariusza postaci, kanonu z ksiąg świata, wspomnień długoterminowych, narastających streszczeń, stylu narracji postaci, długości odpowiedzi i ustawień NSFW, blokady języka wziętej z języka twojego konta oraz tylu ostatnich wiadomości, ile zmieści okno kontekstu modelu. Narzędzia pamięci działają, gdy model obsługuje narzędzia.

Skoro historię trzyma serwer, nie musisz jej odtwarzać.

> **Wysyłanie wiadomości asystenta może usunąć historię.** Jeśli twoja tablica `messages` zawiera wiadomości asystenta, Reverie bierze ostatnią z nich, szuka jej wśród 20 najnowszych zapisanych wiadomości i po trafieniu trwale kasuje każdą wiadomość utworzoną po niej, razem ze wspomnieniami powstałymi po tym momencie. Jeśli nic nie pasuje, nic nie zostaje skasowane. Długość twojej tablicy nie ma znaczenia. Żeby uniknąć tego całkowicie, wysyłaj tylko nową wiadomość użytkownika.

## Który model odpowiada \[#which-llm-answers]

Decyduje postać, a nie żądanie — chyba że sam wskażesz model językowy. Kolejność od najsłabszej do najmocniejszej: domyślny model czatu, potem własne ustawienie modelu w postaci, potem ID modelu Reverie przekazane jako `model`, a na końcu preferencja modelu ustawiona dla tej rozmowy w aplikacji webowej, która bije wszystkie pozostałe. [Modele →](https://reverie.im/pl/docs/reference/models)

## Błędy \[#errors]

Błędy z `/chat/completions` używają koperty OpenAI: `{"error": {"message", "type", "param": null, "code"}}`.

| HTTP   | `code`                 | `type`                  | Przyczyna                                                                                |
| ------ | ---------------------- | ----------------------- | ---------------------------------------------------------------------------------------- |
| 401    | `invalid_api_key`      | `invalid_request_error` | Brak `Authorization` albo zły format, nieznany klucz, albo klucz nieaktywny              |
| 401    | `api_key_expired`      | `invalid_request_error` | Klucz jest po terminie ważności                                                          |
| 404    | `scenario_not_found`   | `invalid_request_error` | ID scenariusza się rozwiązało, ale scenariusza już nie ma                                |
| 404    | `character_not_found`  | `invalid_request_error` | Postaci nie ma albo została usunięta                                                     |
| 404    | `no_chat_history`      | `invalid_request_error` | Brak `model`, brak przypiętej postaci i brak wcześniejszej rozmowy, na którą można spaść |
| 400    | `missing_user_message` | `invalid_request_error` | Brak niepustej wiadomości `user`                                                         |
| 429    | `rate_limit_exceeded`  | `rate_limit_exceeded`   | Okno darmowych modeli wyczerpane. `Retry-After` podaje, ile sekund czekać                |
| 429    | `insufficient_quota`   | `insufficient_quota`    | Za mało kredytów na to żądanie                                                           |
| 502    | `MODEL_EMPTY_RESPONSE` | `server_error`          | Model zakończył czysto, ale bez tekstu                                                   |
| różnie | kod dostawcy           | `server_error`          | Generowanie padło po stronie dostawcy                                                    |

Dwa przypadki wypadają poza tę kopertę: błędy `GET /models` oraz treści żądań odrzucone przy walidacji (na przykład `temperature` spoza zakresu) — oba zwracają prostą postać błędu.

## Limity zapytań i przydziały \[#rate-limits-and-quotas]

To API **nie ma limitu zapytań na klucz, pułapu równoczesności ani przydziału żądań**. Twoje użycie ograniczają tylko dwie rzeczy:

| Ograniczenie          | Wartość                                                                                     |
| --------------------- | ------------------------------------------------------------------------------------------- |
| Saldo kredytów        | Sprawdzane przed każdym żądaniem; przy braku zwraca `insufficient_quota`                    |
| Okno darmowych modeli | 15 wiadomości na 3 godziny, na konto — ×3 w Pro (45), ×4 w Premium (60), ×5 w Ultimate (75) |

Okno darmowych modeli dzielisz z czatem w sieci, historiami, powieściami i botami — to jeden przydział na konto, a nie jeden na każde miejsce. [Darmowe modele →](https://reverie.im/pl/docs/reference/free-models)

Reverie nie wysyła webhooków na zewnątrz; nie ma się do czego zapisać, żeby dostać powiadomienie o zakończeniu generowania.

## Importowanie postaci \[#importing-characters]

Drugi punkt końcowy, `POST /api/v1/characters/import`, tworzy postać z karty postaci. Wymaga klucza z zakresem importu, a to nie jest ten rodzaj klucza, który tworzy strona ustawień. [Klucze API →](https://reverie.im/pl/docs/integrations/api-keys) i [Import postaci →](https://reverie.im/pl/docs/characters/import-characters)

## Powiązane \[#related]

* [Klucze API](https://reverie.im/pl/docs/integrations/api-keys) — tworzenie, przypinanie, wygasanie i podgląd kluczy
* [Modele](https://reverie.im/pl/docs/reference/models) — ID modeli i mnożniki kredytów
* [Limity](https://reverie.im/pl/docs/reference/limits) — pozostałe pułapy w produkcie
* [Kredyty](https://reverie.im/pl/docs/billing/credits) — jak wyceniane są żądania
