Quickstart

A key, a base URL and a first streamed token. Drael's public surface is OpenAI-compatible, so any client that speaks that format works against it unchanged.

Three things point a client at Drael:

  • The base URL is your host plus /v1.
  • The model ids are drael-v1, the full model, and drael-v1-lite, a lighter and cheaper one. GET /v1/models lists the ones your key may use. Reasoning is chosen per request with reasoning_effort, not by a separate id.
  • The credential is an API key, sent as Authorization: Bearer dk-....

The API is on the Max plan. A key on a lower plan authenticates and is then refused with plan_required, checked on every call rather than at creation, because a subscription ends after a key is made. Create a key at /developers; it is shown once.

curl

curl https://YOUR-HOST/v1/chat/completions \
  -H "Authorization: Bearer dk-YOUR-KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "drael-v1",
    "stream": true,
    "messages": [{"role": "user", "content": "Explain abliteration in one sentence."}]
  }'

The OpenAI SDKs

from openai import OpenAI

client = OpenAI(base_url="https://YOUR-HOST/v1", api_key="dk-YOUR-KEY")

stream = client.chat.completions.create(
    model="drael-v1",
    messages=[{"role": "user", "content": "Explain abliteration in one sentence."}],
    stream=True,
)
for chunk in stream:
    print(chunk.choices[0].delta.content or "", end="")
import OpenAI from 'openai'

const client = new OpenAI({ baseURL: 'https://YOUR-HOST/v1', apiKey: 'dk-YOUR-KEY' })

const stream = await client.chat.completions.create({
  model: 'drael-v1',
  messages: [{ role: 'user', content: 'Explain abliteration in one sentence.' }],
  stream: true,
})
for await (const chunk of stream) process.stdout.write(chunk.choices[0]?.delta?.content ?? '')

Check the key

curl https://YOUR-HOST/v1/models -H "Authorization: Bearer dk-YOUR-KEY"

GET /v1/models answers with the one served model and, when the engine reports it, the context window under both context_length and max_model_len. It needs the same credential as chat: there is no unauthenticated route on /v1.

What you get

The model answers what it is asked. There is no content filter, no disclaimer layer and no refusal path in chat: that is the product, not a setting.

With no tools in your request, Drael also serves its own catalogue and runs the tool loop itself: you receive the answer, not the intermediate turns. A request that carries its own tools gets a plain relay and executes them itself, which is how every OpenAI client already works.

Point a coding client at it

npx @drael/code

One command writes that client's own configuration file and nothing else. See install.

  • Chat completions: every parameter honoured, overridden or dropped, and the shape of the stream.
  • Tools: the catalogue the model is served, and what each call costs.
  • Images: generation in chat, and the OpenAI Images drop-in.
  • Authentication: keys, scopes, sessions and the recovery code.
  • Limits: the context window, what reasoning does to max_tokens, and what is measured rather than promised.
  • Errors: every code this API can answer with.