# Quickstart

> Get an API key and render your first PDF from JSON in under a minute, with curl, TypeScript, Python or the CLI.

You need an API key and one HTTP request. No template is required: send any JSON object and Quire returns a PDF.

## 1. Get an API key

Sign in with your email. The CLI waits while you click the link, then saves your key:

```bash
npx quirepdf-cli login you@example.com
```

The free plan includes 20 renders a month, with no card, plus unlimited watermarked **test renders**: add `--test` in the CLI, `test: true` in the SDKs or `?test=true` to the API while you build, and they never count. Your key starts with `qk_live_`. In code, read it from the `QUIRE_API_KEY` environment variable.

## 2. Render a PDF

Send your data to `POST /v1/render`:

```bash
curl https://api.quirepdf.dev/v1/render \
  -H "Authorization: Bearer $QUIRE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"Packing list","to":{"name":"Little Owl Café"},"items":[{"item":"Espresso, 1 kg","qty":12}]}' \
  -o packing-list.pdf
```

The same call with the SDKs:

```ts
import { Quire } from "quirepdf";
import { writeFile } from "node:fs/promises";

const quire = new Quire(); // reads QUIRE_API_KEY
const pdf = await quire.render({ title: "Packing list", items: [{ item: "Espresso, 1 kg", qty: 12 }] });
await writeFile("packing-list.pdf", pdf.bytes);
```

```python
from quirepdf import Quire

Quire().render({"title": "Packing list", "items": [{"item": "Espresso, 1 kg", "qty": 12}]}).save("packing-list.pdf")
```

Or straight from a file:

```bash
npx quirepdf-cli render packing-list.json
```

## 3. Choose a template (optional)

The response headers tell you which layout was used:

| Header | Example | Meaning |
|---|---|---|
| `x-template` | `document` | The template that rendered the page |
| `x-template-source` | `fallback` | `explicit` (you named it), `detected` (your data matched it) or `fallback` (generic layout) |
| `x-template-hint` | `invoice (seller is required)` | A template your data almost matched, and what's missing |

Data shaped like an invoice, receipt, quote, credit note, statement or certificate gets that template automatically. To require a specific one, name it:

```bash
curl "https://api.quirepdf.dev/v1/render?template=invoice" ...
```

Naming a template validates your data against its schema. If something is wrong, you get every problem at once:

```json
{"error":{"type":"invalid_data","message":"data has 2 problems","fields":[
  {"path":"seller","message":"seller is required"},
  {"path":"items[0].qty","message":"items[0].qty must be a number"}]}}
```

See each template's fields in the [template gallery](/templates), or with `npx quirepdf-cli templates invoice`.

## Next steps

- [Render API reference](/docs/render-api): every endpoint, parameter and header
- [How the generic layout works](/docs/templates-and-layout): shape any JSON into a good-looking document
- [MCP server](/docs/mcp): let Claude and other agents render documents
- [Errors](/docs/errors): every error type and how to fix it