Skip to main content

Authentication

How to get an API key, where to put it, and what a 401 looks like so you know immediately if something is wrong.

Get an API key

  1. 1Sign up or sign in.
  2. 2Go to API Keys in your dashboard.
  3. 3Click Create key. Give it a name (e.g. "Production server") and choose the environment.
Key prefixEnvironment
pk_live_…Production — use in servers and CI
pk_test_…Sandbox — safe for local development

Both key types work for rendering — the prefix only affects how usage is attributed in your dashboard.

Bearer header (POST requests)

For server-side code — Node.js, Python, Go, cURL — pass the key in the Authorization header:

text
Authorization: Bearer pk_live_YOUR_API_KEY
bash
curl -X POST https://www.chart-output.com/api/v1/render \ -H "Authorization: Bearer pk_live_YOUR_KEY" \ -H "Content-Type: application/json" \ --output chart.png \ -d '{"type":"bar","data":{"labels":["A","B"],"datasets":[{"data":[1,2]}]}}'

The word Bearer followed by a single space is required. A header without the prefix returns a 401 with the message "Invalid Authorization format."

Query parameter (GET / image embeds)

Browsers cannot send Authorization headers with <img src> requests. Use a query parameter instead:

html
<!-- key= and apiKey= are both accepted --> <img src="https://www.chart-output.com/api/v1/render?key=pk_live_YOUR_KEY&type=bar&labels=A,B&data=1,2&format=png" alt="Chart" width="600" height="300" />

Both ?key= and ?apiKey= are accepted. The header takes precedence if both are present.

Anonymous requests

Whether omitting auth is allowed depends on the HTTP method. The two render entry points behave differently on purpose.

GET — allowed, returns 200

A GET /api/v1/render with no Authorization header and no key query parameter returns 200 on the anonymous plan. This is intentional — <img src> embeds work without signing up. The anonymous plan is its own tier, tighter than Starter:

  • PNG output only — any other format returns 403
  • 1200px maximum per dimension — larger returns 403
  • returnUrl is ignored; you always get image bytes
  • 5 requests per 15 minutes, per IP address

Add ?key= to lift all four limits to your plan's.

POST — auth required, returns 401

A POST /api/v1/render with no credentials returns 401. There is no anonymous POST tier — POST accepts arbitrarily large JSON specs, so it always requires a key:

json
{ "error": "Missing API key. Use Authorization: Bearer <key> header or ?key=<key> query param." }

So on GET, omitting auth entirely is not an error; on POST, it is. On both methods, a 401 also occurs whenever an Authorization header is present but the key is invalid or malformed.

Debugging 401s

There are three distinct 401 bodies:

Invalid or revoked key

json
{ "error": "Invalid API key" }

Malformed header (missing "Bearer " prefix)

json
{ "error": "Invalid Authorization format. Use: Bearer <api_key>" }

No credentials at all (POST only)

json
{ "error": "Missing API key. Use Authorization: Bearer <key> header or ?key=<key> query param." }
SymptomFix
"Invalid API key"Copy the key exactly from the dashboard — no extra spaces, newlines, or quotes
"Invalid Authorization format"Header must be Authorization: Bearer pk_live_… — note the space after Bearer
"Missing API key" on POSTPOST always requires credentials — add the header or ?key=. Only GET has an anonymous tier
200 but anonymous limits on GETYour header or query param isn't reaching the server — check HTTP client configuration
401 in <img> tagUse ?key= in the URL — browsers can't send headers with image requests