---
title: Quickstart
description: Create an API key, send one request, and get a rendered file back.
sidebar:
  label: Quickstart
  order: 1
---

Three steps and a file lands on disk.

1. **Create an account**

    Sign up at [snhtml.com/sign-up](https://snhtml.com/sign-up). The free plan includes 100 renders a month and needs no card.

2. **Create an API key**

    Open the [dashboard](https://snhtml.com/dashboard), go to **API Keys**, and create one.

    The key is shown once, at creation. Store it as a server-side secret — anyone holding it can spend your render quota.

3. **Render something**

    Post a complete HTML document and write the bytes to a file.

    <CodeGroup>

    ```bash cURL
    curl -X POST https://api.snhtml.com/v1/render \
      -H "authorization: Bearer snhtml_..." \
      -H "content-type: application/json" \
      -d '{
        "html": "<main><h1>Invoice #1842</h1></main>",
        "format": "png",
        "width": 1024,
        "height": 900
      }' \
      --output invoice-1842.png
    ```

    ```ts TypeScript
    const response = await fetch("https://api.snhtml.com/v1/render", {
      method: "POST",
      headers: {
        authorization: `Bearer ${process.env.SNAPHTML_API_KEY}`,
        "content-type": "application/json",
      },
      body: JSON.stringify({
        html: "<main><h1>Invoice #1842</h1></main>",
        format: "png",
        width: 1024,
        height: 900,
        fileName: "invoice-1842",
      }),
    });

    if (!response.ok) {
      const { error } = await response.json();
      throw new Error(error);
    }

    const bytes = Buffer.from(await response.arrayBuffer());
    ```

    ```python Python
    import os
    import requests

    response = requests.post(
        "https://api.snhtml.com/v1/render",
        headers={"authorization": f"Bearer {os.environ['SNAPHTML_API_KEY']}"},
        json={
            "html": "<main><h1>Invoice #1842</h1></main>",
            "format": "pdf",
            "pdfFormat": "A4",
        },
        timeout=30,
    )
    response.raise_for_status()

    with open("invoice-1842.pdf", "wb") as file:
        file.write(response.content)
    ```

    </CodeGroup>

## Try it without writing code

The dashboard's [Sandbox](/dashboard#sandbox) runs the same request from the browser: paste HTML or pick a template, choose a format, and download the result. Sandbox renders count toward your monthly usage, exactly like API renders.

## Next

**[HTTP API](/api)**

Endpoints, headers, and response shape.

**[Render options](/render-options)**

Viewport, waiting, image and PDF settings.

**[Templates](/templates)**

Store HTML once, fill it per customer.

**[Errors](/errors)**

Status codes and what to do about them.
