---
title: Quickstart
description: Get a key, send a GPT, Claude or Gemini request at half the official price with your existing SDK, stream it, and see what it cost.
---

This page takes you from an empty account to a streamed answer and a line in your usage log. It uses the OpenAI SDK because most code already has it, but the same key works with the Anthropic and Google SDKs.

:::steps
### Get a key {#get-a-key}

[Create an account](/signup), go to [API keys](/app/keys) and press **New key**. The key begins with `ho-` and appears only this once, so copy it before closing the dialog.

Keep it out of your source files by exporting it:

```bash
export HALFOFF_API_KEY="ho-..."
```

You also need a positive balance. Top up from the dashboard with PayPal; see [Billing](/docs/account/billing).

### Point your client at Half Off Dev {#first-request}

Point the client at `https://halfoff.dev/v1` and pass your key. Nothing else in the call changes.

```bash title="cURL"
curl https://halfoff.dev/v1/chat/completions \
  -H "Authorization: Bearer $HALFOFF_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "model": "gpt-6.1-sol",
    "messages": [{"role": "user", "content": "Explain a race condition in two sentences."}]
  }'
```

```python title="Python"
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://halfoff.dev/v1",
    api_key=os.environ["HALFOFF_API_KEY"],
)
completion = client.chat.completions.create(
    model="gpt-6.1-sol",
    messages=[{"role": "user", "content": "Explain a race condition in two sentences."}],
)
print(completion.choices[0].message.content)
```

```js title="Node.js"
import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'https://halfoff.dev/v1',
  apiKey: process.env.HALFOFF_API_KEY,
});
const completion = await client.chat.completions.create({
  model: 'gpt-6.1-sol',
  messages: [{ role: 'user', content: 'Explain a race condition in two sentences.' }],
});
console.log(completion.choices[0].message.content);
```

Prefer the native SDKs? Claude through the Anthropic SDK is in [Anthropic Messages](/docs/models/anthropic), Gemini through the Google SDK in [Gemini](/docs/models/gemini).

### Stream tokens as they arrive {#stream}

Set `stream` to true and read the chunks. The event format is exactly what the vendor's own API sends.

```bash title="cURL"
curl -N https://halfoff.dev/v1/chat/completions \
  -H "Authorization: Bearer $HALFOFF_API_KEY" \
  -H "content-type: application/json" \
  -d '{"model": "gpt-6.1-sol", "stream": true,
       "messages": [{"role": "user", "content": "List the planets, one per line."}]}'
```

```python title="Python"
stream = client.chat.completions.create(
    model="gpt-6.1-sol",
    messages=[{"role": "user", "content": "List the planets, one per line."}],
    stream=True,
)
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)
```

```js title="Node.js"
const stream = await client.chat.completions.create({
  model: 'gpt-6.1-sol',
  messages: [{ role: 'user', content: 'List the planets, one per line.' }],
  stream: true,
});
for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
}
```

More detail in [Streaming](/docs/models/streaming).

### See what you paid {#check-cost}

Open [Logs](/app/logs). Each call shows up within seconds with its input and output tokens, the amount charged, time to first token and tokens per second. Every response also has an `x-halfoff-request-id` header; quote it if you ever ask support about that call.
:::

## Finding model ids {#model-ids}

`GET /v1/models` needs no key and returns every model with its context window and price. The [model list](/models) page shows the same data.

```bash title="cURL"
curl https://halfoff.dev/v1/models
```

Ids are matched loosely, so `claude-sonnet-5.5`, `claude-sonnet-5-5` and `anthropic/claude-sonnet-5.5` all reach the same model.

## Where to go from here {#next}

:::cards
- :plug: [Integrations](/docs/integrations) Claude Code, Codex CLI, Gemini CLI and desktop chat apps.
- :layers: [Prompt caching](/docs/models/caching) Pay the cached-input rate on long, repeated context.
- :key: [API keys](/docs/account/api-keys) Restrict models, cap spend and set an expiry per key.
- :card: [Pricing](/docs/models/pricing) How the half-price rates are calculated and charged.
:::
