Hailey · API Reference

One endpoint.
Every answer. ask.hailey.io

An OpenAI-compatible AI gateway. Point any OpenAI-style client at Hailey, authenticate with your service key, and get streaming or complete responses — with durable per-project context no vanilla endpoint gives you.

hailey — connection
Base URL https://ask.hailey.io/v1
Auth Authorization: Bearer hly_… get a key
drop-in OpenAI SDK compatible 5 models · one model id picks the engine SSE streaming projects durable context parallel by default
01

Quickstart

Three lines of setup in any OpenAI client — only the base URL changes.

shell
curl https://ask.hailey.io/v1/chat/completions \
  -H "Authorization: Bearer $HAILEY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-opus-4-8",
    "messages": [{"role": "user", "content": "Hello, Hailey."}]
  }'
python
from openai import OpenAI

client = OpenAI(
    base_url="https://ask.hailey.io/v1",
    api_key="hly_…",
)

resp = client.chat.completions.create(
    model="claude-opus-4-8",
    messages=[{"role": "user", "content": "Hello, Hailey."}],
)
print(resp.choices[0].message.content)
typescript
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://ask.hailey.io/v1",
  apiKey: process.env.HAILEY_API_KEY,
});

const resp = await client.chat.completions.create({
  model: "claude-opus-4-8",
  messages: [{ role: "user", content: "Hello, Hailey." }],
});
console.log(resp.choices[0].message.content);
02

Authentication

Every request needs a service key in the Authorization header: Authorization: Bearer hly_…. Keys are created per integration on the API keys page, are shown once at creation, and can be revoked at any time.

Each key can carry a default project — the context it runs in when a request doesn't name one (see Projects).

03

Models & engines

GET /v1/models lists the models your key can use. A model id pins the engine (the AI backend adapter), the model family, and the version in one string — pick the id, and the gateway routes to the right backend.

Model idEngineContext windowMax output
claude-opus-4-8 anthropic 200,000
32,000
claude-opus-4-7 anthropic 200,000
32,000
claude-sonnet-4-6 anthropic 200,000
64,000
claude-haiku-4-5 anthropic 200,000
8,192
claude-fable-5 anthropic 200,000
64,000

Additional engines (e.g. OpenAI-family models) appear in this list as adapters are enabled — your integration code doesn't change, you just select a different model id. Calling a registered model whose engine isn't enabled yet returns 501 engine_not_available. If a request omits model, the project's default model is used.

04

Chat completions

POST /v1/chat/completions — the OpenAI chat-completions shape. Minimal request:

request
{
  "model": "claude-opus-4-8",
  "messages": [
    {"role": "system", "content": "Answer in one sentence."},
    {"role": "user",   "content": "What is Hailey?"}
  ]
}
response
{
  "id": "chatcmpl-…",
  "object": "chat.completion",
  "model": "claude-opus-4-8",
  "choices": [{
    "index": 0,
    "message": { "role": "assistant", "content": "…" },
    "finish_reason": "stop"
  }],
  "usage": { "prompt_tokens": 123, "completion_tokens": 45, "total_tokens": 168 }
}

Send the full messages history each call, exactly as with OpenAI — prior user/assistant turns are treated as conversation context. system messages are appended to the project's own system prompt (project instructions always apply first).

05

Streaming

Set "stream": true to receive server-sent events of chat.completion.chunk objects, terminated by data: [DONE] — the standard OpenAI streaming contract, so SDK streaming helpers work unchanged. The final chunk carries usage.

python
stream = client.chat.completions.create(model="…", messages=[…], stream=True)
for chunk in stream:
    print(chunk.choices[0].delta.content or "", end="")
06

Projects — durable context

A plain gateway call is stateless: it runs in a fresh, empty sandbox. A project gives your calls durable context — the gateway equivalent of running inside your project directory.

A project is a Hailey entity. It exists only in your Hailey account — created at /settings/projects or provisioned for you — and is unrelated to any similarly-named concept elsewhere: it is not a claude.ai Project, not an OpenAI platform project, and not a folder on your machine. If a request names a project that doesn't exist in the calling key's account, the gateway returns 404 project_not_found.
What a project carriesEffect on every call
System promptAlways-on instructions, applied before any request system message.
CLAUDE.mdA project brief placed at the workspace root and auto-loaded by the engine.
Context filesSeeded into the call's workspace — the model can read them while answering.
DefaultsModel (engine + version), parameters, tool allowlist, workspace mode.

Create and manage projects at /settings/projects. Bind one to a key as its default, or select per request with hailey.project. Keys without a project use an auto-provisioned personal default project. A key can only reach projects owned by the same account.

Workspace modes

Calls run in parallel by default — including calls on the same key, project, and account. Fire as many concurrent requests as you need; nothing on the server queues them. Sequential execution is opt-in: pass "hailey": { "params": { "serial": true } } and calls to that project queue and wait their turn — each request blocks until the one ahead of it finishes, then runs. You only see 409 project_busy if a call waits longer than the server's queue cap (minutes) — an exceptional case, not the norm.

conversation default · parallel

Each call gets a fresh workspace seeded from the project's context files. File mutations are discarded after the call. Fully parallel — serialize with params.serial when order matters.

shared always serial

Calls run inside the project's persistent workspace — files written by one call are visible to the next. Two engines can't safely share one live workspace, so calls queue per project.

Conversations (shared mode)

In shared mode you may pass a conversation id of your choosing. The gateway maps it to a persistent engine session and resumes it on every call with the same id — server-side memory without re-sending history:

json
"hailey": { "workspace": "shared", "conversation": "onboarding-7c2" }
07

The hailey extension & headers

Hailey-specific options ride in an optional hailey object in the request body (use extra_body in the OpenAI SDKs). Clients that can't add body fields can send the equivalent headers.

request body
{
  "model": "claude-opus-4-8",
  "messages": [ … ],
  "hailey": {
    "project":      "birthday-gold",   // project slug or id (default: the key's project)
    "workspace":    "shared",          // 'conversation' (default) | 'shared'
    "conversation": "onboard-7c2",     // shared mode only: resume this session
    "params":       { "max_turns": 8 } // per-call engine parameter overrides
  }
}
header equivalents
X-Hailey-Project: birthday-gold
X-Hailey-Workspace: shared
X-Hailey-Conversation: onboard-7c2
python sdk
client.chat.completions.create(
    model="claude-opus-4-8",
    messages=[{"role": "user", "content": "Summarize the seed data."}],
    extra_body={"hailey": {"project": "birthday-gold"}},
)
08

Parameters

Parameters resolve in three layers: project defaults → per-request hailey.params → standard OpenAI top-level fields. Support depends on the engine; unsupported parameters are accepted and ignored, never fatal.

ParameterWhereSupportBehavior (anthropic engine)
modeltop levelhonoredSelects engine, family, and version.
streamtop levelhonoredSSE streaming on/off.
messages (system)top levelhonoredAppended to the project system prompt.
max_turnshailey.params / projecthonoredCaps agentic tool-use turns (1–50, default 20).
max_thinking_tokenshailey.params / projecthonoredExtended-thinking budget (0–32000). Default 0: thinking off for the fastest answers; raise it for harder reasoning.
serialhailey.params / projecthonoredDefault false: calls run fully in parallel, even within one account. Set true and calls queue per project, each waiting for the previous one to finish.
tool allowlistproject settinghonoredRestricts which tools the engine may use. Code-execution and file-mutation tools are always disabled on gateway calls.
temperature, top_p, max_tokenstop levelignoredAccepted for compatibility; the engine manages sampling and output budget.
09

Errors

Errors use the OpenAI error envelope:

json
{ "error": { "type": "authentication_error", "message": "Invalid API key.", "code": null } }
StatusCodeMeaning
401Missing or invalid Authorization: Bearer hly_….
400invalid_workspace_mode, conversation_requires_shared, …Malformed request.
404project_not_foundProject unknown to this account (or archived).
404model_not_foundUnknown or disabled model id.
409project_busyA serialized call (shared mode or params.serial) waited longer than the queue cap. Exceptional — serialized calls normally queue and complete. Retry with backoff.
501engine_not_availableThe model's engine has no adapter enabled yet.
502upstream_errorThe engine failed mid-call. Safe to retry.
503engine_unavailableThe engine is temporarily unavailable (e.g. mid-update). Retry shortly.

Ready to build?

Request access, create a key, give it a project — and every call arrives briefed.

Request access Create a key See the live demo