> ## Documentation Index
> Fetch the complete documentation index at: https://mifr.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Mint a key and run a prompt on an Apple-attested Mac.

Mint a key and send a prompt. You get an answer from an Apple-attested Mac. If you already speak Chat Completions, that is a base URL and an API key.

Mifr will support many models. In this alpha the first ones are `qwen3-4b` and `qwen3-8b`. The examples on this page use `qwen3-4b`.

## 1. Get your API key

Sign in with Google at [Settings](https://mifr-website-production.up.railway.app/settings) and create an API key. The secret is shown once and starts with `sk-mifr_`.

Operator env keys (`MIFR_GATEWAY_KEYS`) are a different product; they are not minted here.

## 2. Make a request

Point the SDK you already use at the gateway. Origin:

```text theme={null}
https://mifr-gateway-production.up.railway.app
```

SDKs want that origin plus `/v1`.

<CodeGroup>
  ```python Python theme={null}
  from openai import OpenAI

  client = OpenAI(
      base_url="https://mifr-gateway-production.up.railway.app/v1",
      api_key="YOUR_MIFR_API_KEY",
  )

  completion = client.chat.completions.create(
      model="qwen3-4b",
      messages=[{"role": "user", "content": "Reply with the single word pong."}],
  )

  print(completion.choices[0].message.content)
  print(completion.usage)
  print(getattr(completion, "mifr_receipt", None) or (completion.model_extra or {}).get("mifr_receipt"))
  ```

  ```typescript TypeScript theme={null}
  import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
  import { generateText } from "ai";

  const mifr = createOpenAICompatible({
    name: "mifr",
    apiKey: process.env.MIFR_API_KEY,
    baseURL: "https://mifr-gateway-production.up.railway.app/v1",
    includeUsage: true,
  });

  const { text } = await generateText({
    model: mifr("qwen3-4b"),
    prompt: "Reply with the single word pong.",
  });
  ```

  ```bash cURL theme={null}
  export MIFR_API_KEY=sk-mifr_…
  curl https://mifr-gateway-production.up.railway.app/v1/chat/completions \
    -H "Authorization: Bearer $MIFR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "qwen3-4b",
      "messages": [{"role": "user", "content": "Reply with the single word pong."}]
    }'
  ```
</CodeGroup>

A 200 body is a `chat.completion` with `usage` and `mifr_receipt`. Verdict headers such as `x-mifr-trust` ride on the HTTP response; those headers are the gateway's report, and `mifr_receipt` is the proof.

Streaming (`stream=true`) sends tokens as they arrive. The receipt and `x_mifr_*` verdicts land on the final chunk, not on the SSE HTTP head, because that head is flushed before a Mac is chosen. If the stream dies after the first token, there is no `[DONE]` and no receipt; start a new request instead of splicing onto those bytes.

A wrong key is HTTP 401:

```json theme={null}
{
  "error": {
    "message": "missing or invalid API key (Authorization: Bearer <key>)",
    "type": "invalid_request_error",
    "code": "invalid_api_key",
    "param": null,
    "mifr_action": "fix_key"
  }
}
```

`mifr_action` is the next step (`fix_key`, `retry`, `wait`, `fix_request`, `pick_model`). OpenAI SDKs ignore extra keys, so read `status_code` and the envelope.

## Next steps

* [Authentication](/authentication) covers how keys are minted, hashed, and rejected.
* [Models](/models) covers aliases, the live list, and pinning a Mac.
* [Chat completions](/api-reference/chat-completions) is the live playground for `POST /v1/chat/completions`.
