# Open API

> Isang endpoint na compatible sa OpenAI para sa iyong mga karakter.

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

May inilalantad ang Reverie na Chat Completions endpoint na compatible sa OpenAI. Ituro rito ang kahit anong OpenAI client, magpasa ng Reverie API key, at gamitin ang field na `model` para pangalanan ang isang **karakter o scenario** sa halip na isang LLM. Itinatago ng Reverie sa panig nito ang usapan, ang mga memorya at ang mga buod, kaya ang bago mo lang na mensahe ang kailangan ng bawat request.

Magagamit ito ng kahit anong naka-sign in na account. Walang subscription tier at walang waitlist — API key lang ang kailangan mo. [Gumawa ng isa →](https://reverie.im/fil/docs/integrations/api-keys)

## Base URL at auth \[#base-url-and-auth]

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

Ipinapakita ng **Mga Setting → Higit pa → Mga API Key** ang eksaktong base URL sa card na **API Endpoint**, na may copy button.

> **Server-side API ito.** Hinaharang ang mga cross-origin na request mula sa
> browser, kaya papalya ang fetch mula sa sarili mong web page anuman ang key.
> Tawagin ito mula sa isang backend, at huwag ilagay ang key sa client code.

## Mabilis na pagsisimula \[#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 ?? "");
}
```

May request builder din ang **Mga Setting → Higit pa → Mga API Key** na bumubuo ng tatlong snippet na ito gamit ang isa sa mga totoo mong key at isang totoong karakter.

## Karakter ang pinapangalanan ng field na `model` \[#the-model-field-names-a-character]

> **Hindi gumagana ang pangalan lang ng karakter.** Hindi naghahanap ang
> `model: "Luna"` ng karakter na nagngangalang Luna. Wala itong natutugma, kaya
> babagsak ito sa default na karakter ng key o sa pinakahuli mong chat, at
> sasagot ang ibang karakter nang walang error. Laging gamitin ang anyong
> `Name [shortid]` na ibinabalik ng `GET /models`.

| Halaga ng `model`                                   | Ano ang sumasagot                                                       |
| --------------------------------------------------- | ----------------------------------------------------------------------- |
| `Luna [abc12345]`                                   | Ang karakter o scenario na nagtatapos ang ID sa 8 character na iyon     |
| Buong ID ng karakter o scenario                     | Ang karakter o scenario na iyon                                         |
| Isang model ID ng Reverie, hal. `deepseek-v4-flash` | Pinipili ang **LLM**; galing sa key o sa huli mong chat ang karakter    |
| Wala                                                | Ang naka-pin na karakter ng key, kung hindi ay ang pinakahuli mong chat |

Mga detalyeng nagpapasya kung mare-resolve ang maikling ID:

* Dapat nasa **dulo** ng string ang `[...]`.
* Ang suffix na 8 character o mas maikli ay itinutugma lang sa mga karakter na **may chat ka na**, sa web man o sa pamamagitan ng API. Ang maikling ID ng karakter na hindi mo pa nabubuksan ay tahimik na babagsak sa iba.
* Tumatakbo lang ang paghahanap ng scenario kapag naka-pin ang key sa isang karakter. Sa global key, hindi kailanman mare-resolve ang maikling scenario ID.
* Itinuturing na buong ID ang higit sa 8 character.

### Paglilista ng mga puwede mong kausapin \[#listing-what-you-can-talk-to]

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

Ibinabalik ng **global** key ang mga kamakailan mong karakter. Ang key na **naka-pin sa isang karakter** ay ibinabalik ang mga scenario ng karakter na iyon, o ang karakter mismo kung wala itong scenario. Ganito ang itsura ng bawat entry:

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

Kopyahin nang direkta ang `id` sa `model`. Gumagamit ang mga error mula sa endpoint na ito ng simpleng hugis ng error sa halip na ang OpenAI envelope.

## Ano ang binabasa sa request body \[#what-the-request-body-reads]

Apat na field ang binabasa. Tinatanggap at tahimik na itinatapon ang lahat ng iba pa.

| Field         | Uri          | Default                                  | Mga tala                                          |
| ------------- | ------------ | ---------------------------------------- | ------------------------------------------------- |
| `messages`    | array        | kailangan                                | Tingnan sa ibaba — bahagi lang nito ang ginagamit |
| `model`       | string       | opsyonal                                 | Karakter, scenario o LLM, gaya ng nasa itaas      |
| `stream`      | boolean      | **`true`**                               | Streaming ang default, hindi tulad ng OpenAI API  |
| `temperature` | numerong 0–2 | setting ng karakter, kung hindi ay `0.8` | Tinatanggihan ang mga halagang lampas sa saklaw   |

Binabalewala nang walang babala: `max_tokens`, `top_p`, `n`, `stop`, `presence_penalty`, `frequency_penalty`, `logit_bias`, `seed`, `user`, `response_format`, `tools`, `tool_choice`, `logprobs`, `stream_options`.

Paano hinahawakan ang `messages`:

* **Inaalis ang mga mensaheng `system`.** Galing sa sariling mga field ng karakter ang persona at pag-uugali, hindi sa request. [Mga prompt field →](https://reverie.im/fil/docs/characters/prompt-fields)
* **Walang suporta sa vision.** Puwedeng string o parts array ang content, pero mga `text` part lang ang binabasa; binabalewala ang mga image part.
* Ang \*&#x2A;huling mensaheng `user`*\* lang ang idinadagdag sa usapan. Binabalewala ang mga naunang mensahe ng user.
* Para lang sa history sync ang mga assistant message (tingnan sa ibaba).
* Ibinabalik ang `missing_user_message` kapag walang laman o puro whitespace ang huling mensahe ng user.

## Mga response \[#responses]

Ang non-streaming na response ay karaniwang object na `chat.completion`. Laging `stop` ang `finish_reason` — hindi kailanman inilalantad ang mga internal na tool call — at puro zero ang mga counter ng `usage`, kaya sukatin ang mga token mula sa mga istatistika ng paggamit sa pahina ng mga API key sa halip na mula sa response.

Ang streaming na response ay `text/event-stream`:

1. Mga content chunk: mga object na `chat.completion.chunk` na may `delta.content`. \*&#x2A;Walang ipinapadalang paunang chunk na `delta: {"role": "assistant"}`.*\*
2. Isang finish chunk, na may `finish_reason` na `stop`, `length` o `content_filter`. Iniuulat bilang `stop` ang pagtatapos dahil sa tool call.
3. Isang usage chunk na may walang lamang array na `choices`.
4. `data: [DONE]`.

Kapag pumalya ang pag-generate sa gitna ng stream, maglalabas ang stream ng `data: {"error": {...}}` at saka `[DONE]`.

## Estado ng usapan \[#conversation-state]

Ang Reverie ang nag-iimbak ng usapan. Iisang chat ang umiiral bawat pares ng key at karakter, lumalabas ito sa web app kasama ng iba mo pang mga chat, at binubuo ang bawat turn mula sa system prompt at scenario ng karakter, canon ng World Book, pangmatagalang memorya, mga rolling summary, istilo ng pagsasalaysay ng karakter, haba ng sagot at mga NSFW na setting, isang language lock mula sa locale ng iyong account, at kasindami ng kamakailang history na kakayanin ng context window ng model. Tumatakbo ang mga memory tool kapag sumusuporta sa mga tool ang model.

Dahil ang server ang may hawak ng history, hindi mo na kailangang i-replay ito.

> **Puwedeng mag-delete ng history ang pagpapadala ng mga assistant message.**
> Kapag may mga assistant message ang iyong array na `messages`, kinukuha ng
> Reverie ang huli, hinahanap ito sa 20 pinakabagong naka-imbak na mensahe, at —
> kapag may tumugma — permanenteng dine-delete ang bawat mensaheng ginawa
> pagkatapos nito, kasama ang mga memoryang ginawa pagkatapos ng puntong iyon.
> Kapag walang tumugma, walang made-delete. Walang kinalaman ang haba ng iyong
> array. Para tuluyang maiwasan ito, ang bagong mensahe lang ng user ang ipadala.

## Aling LLM ang sumasagot \[#which-llm-answers]

Ang karakter ang nagpapasya, hindi ang request — maliban kung magpangalan ka ng LLM. Pagkakasunod-sunod ng prayoridad, mula pinakamababa hanggang pinakamataas: ang default na chat model, saka ang sariling setting ng model ng karakter, saka ang model ID ng Reverie na ipinasa bilang `model`, at panghuli ang preference ng model bawat chat na itinakda mo sa web app, na nangingibabaw sa lahat. [Mga model →](https://reverie.im/fil/docs/reference/models)

## Mga error \[#errors]

Gumagamit ng OpenAI envelope ang mga error mula sa `/chat/completions`: `{"error": {"message", "type", "param": null, "code"}}`.

| HTTP    | `code`                 | `type`                  | Dahilan                                                                                             |
| ------- | ---------------------- | ----------------------- | --------------------------------------------------------------------------------------------------- |
| 401     | `invalid_api_key`      | `invalid_request_error` | Wala o mali ang anyo ng `Authorization`, hindi kilala ang key, o hindi aktibo ang key               |
| 401     | `api_key_expired`      | `invalid_request_error` | Lampas na sa pag-expire ang key                                                                     |
| 404     | `scenario_not_found`   | `invalid_request_error` | Na-resolve ang isang scenario ID pero wala na ang scenario                                          |
| 404     | `character_not_found`  | `invalid_request_error` | Nawawala o na-delete ang karakter                                                                   |
| 404     | `no_chat_history`      | `invalid_request_error` | Walang `model`, walang naka-pin na karakter, at walang naunang chat na mababagsakan                 |
| 400     | `missing_user_message` | `invalid_request_error` | Walang mensaheng `user` na may laman                                                                |
| 429     | `rate_limit_exceeded`  | `rate_limit_exceeded`   | Ubos na ang window ng libreng model. Ibinibigay ng `Retry-After` ang bilang ng segundong hihintayin |
| 429     | `insufficient_quota`   | `insufficient_quota`    | Kulang ang credits para sa request                                                                  |
| 502     | `MODEL_EMPTY_RESPONSE` | `server_error`          | Natapos nang maayos ang model pero walang text                                                      |
| iba-iba | code ng provider       | `server_error`          | Pumalya ang pag-generate sa upstream                                                                |

Dalawang kaso ang labas sa envelope na iyon: mga error ng `GET /models`, at mga request body na tinanggihan ng validation (halimbawa, `temperature` na lampas sa saklaw) — parehong nagbabalik ng simpleng hugis ng error.

## Mga rate limit at quota \[#rate-limits-and-quotas]

**Walang rate limit bawat key, walang limitasyon sa sabay-sabay na request at walang request quota** sa API na ito. Dalawang bagay ang naglilimita sa paggamit mo:

| Hangganan               | Halaga                                                                                           |
| ----------------------- | ------------------------------------------------------------------------------------------------ |
| Credit balance          | Sinusuri bago ang bawat request; kapag kulang, ibinabalik ang `insufficient_quota`               |
| Window ng libreng model | 15 mensahe bawat 3 oras, bawat account — ×3 sa Pro (45), ×4 sa Premium (60), ×5 sa Ultimate (75) |

Kahati ng window ng libreng model ang web chat, mga story, mga nobela at ang mga bot — iisang allowance ito bawat account, hindi isa bawat lugar. [Mga libreng model →](https://reverie.im/fil/docs/reference/free-models)

Walang ipinapadalang outbound webhook ang Reverie; walang masu-subscribe-an para sa mga completion event.

## Pag-import ng mga karakter \[#importing-characters]

Isang ikalawang endpoint, ang `POST /api/v1/characters/import`, ang gumagawa ng karakter mula sa isang character card. Kailangan nito ng key na may import scope, na hindi ang uri ng key na ginagawa ng pahina ng mga setting. [Mga API key →](https://reverie.im/fil/docs/integrations/api-keys) at [Mag-import ng mga karakter →](https://reverie.im/fil/docs/characters/import-characters)

## Kaugnay \[#related]

* [Mga API key](https://reverie.im/fil/docs/integrations/api-keys) — gumawa, mag-pin, mag-expire at magbantay ng mga key
* [Mga model](https://reverie.im/fil/docs/reference/models) — mga model ID at credit multiplier
* [Mga limitasyon](https://reverie.im/fil/docs/reference/limits) — ang iba pang hangganan sa produkto
* [Credits](https://reverie.im/fil/docs/billing/credits) — paano pinepresyuhan ang mga request
