# Quickstart (/docs/quickstart)

## 1. Get a key [#1-get-a-key]

Create a key on the [API keys](https://www.ohmygpt.com/keys) page and export it:

```bash
export OHMYGPT_API_KEY="sk-..."
```

Your key starts working after your first top-up on the [Billing](https://www.ohmygpt.com/billing) page.

<Callout type="warn">
  Keep the key on your server. Don't commit it or ship it in a browser or mobile app.
</Callout>

## 2. Call the free test model [#2-call-the-free-test-model]

`ohmygpt/mock` costs nothing and answers every endpoint, streaming or not. Use it to check the base URL, the key and your response handling before you spend anything.

```bash
curl https://api.ohmygpt.com/v1/chat/completions \
  -H "Authorization: Bearer $OHMYGPT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "ohmygpt/mock", "messages": [{"role": "user", "content": "ping"}]}'
```

```json
{
  "id": "chatcmpl-ohmygpt-mock",
  "object": "chat.completion",
  "model": "mock",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "This is a mock reply from OhMyGPT. Your integration works; switch to a real model when ready."
      },
      "finish_reason": "stop"
    }
  ],
  "usage": { "prompt_tokens": 15, "completion_tokens": 17, "total_tokens": 32 }
}
```

The mock also tests tool calling for free. If the request declares tools, it calls the first one (or the one `tool_choice` names) with every required argument set to its zero value. After it receives the tool result, it replies with text.

## 3. Switch to a real model [#3-switch-to-a-real-model]

Change only the model ID. Take the ID from the [model list](/docs/model-naming).

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

client = OpenAI(
    base_url="https://api.ohmygpt.com/v1",
    api_key=os.environ["OHMYGPT_API_KEY"],
)

completion = client.chat.completions.create(
    model="openai/gpt-5.4-nano",
    messages=[{"role": "user", "content": "Say hello in one word."}],
)
print(completion.choices[0].message.content)
```

```ts tab="TypeScript"
import OpenAI from 'openai'

const client = new OpenAI({
  baseURL: 'https://api.ohmygpt.com/v1',
  apiKey: process.env.OHMYGPT_API_KEY,
})

const completion = await client.chat.completions.create({
  model: 'openai/gpt-5.4-nano',
  messages: [{ role: 'user', content: 'Say hello in one word.' }],
})
console.log(completion.choices[0].message.content)
```

```bash tab="curl"
curl https://api.ohmygpt.com/v1/chat/completions \
  -H "Authorization: Bearer $OHMYGPT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "openai/gpt-5.4-nano", "messages": [{"role": "user", "content": "Say hello in one word."}]}'
```

To try another model, change `model` to `anthropic/claude-sonnet-5-5` or `zhipu/glm-5.3-flash`; nothing else changes. The same key also works with the Anthropic and Gemini SDKs; the [protocol table](/docs#base-url-and-protocols) lists their base URLs.

## If the call fails [#if-the-call-fails]

The error message says what to do. The most common fixes on a first call:

| Status | `code` | Fix |
|---|---|---|
| 401 | `invalid_api_key` | Check the key in the `Authorization: Bearer` header. |
| 402 | `insufficient_credits` | Top up on the [Billing](https://www.ohmygpt.com/billing) page. |
| 404 | `model_not_found` | Copy the model ID from `GET /v1/models`. |
| 404, body `404 page not found` | — | Check the path. With the Anthropic SDK, remove `/v1` from the base URL. |

[Errors](/docs/errors) covers every status.

## Next steps [#next-steps]

<Cards>
  <Card title="Model IDs" href="/docs/model-naming" description="Look up IDs, endpoints and retirement dates" />
  <Card title="Costs" href="/docs/costs" description="See what each request cost" />
  <Card title="Streaming" href="/docs/api/streaming" description="Stream tokens as they are generated" />
  <Card title="Tool calling" href="/docs/tool-calling" description="Let the model call your functions" />
</Cards>
