We are in official beta.

Base URL & hosts

Which host serves the API, which one does not, and why a correct request can still come back 404.

The base URL

https://api.docbutterfly.com

Every endpoint hangs off /api/… on that host. There is no versioned prefix and no per-account subdomain — the endpoint name from the API Reference goes straight after /api/:

How a URL is built
https://api.docbutterfly.com  +  /api/  +  ConvertHtmlToPdf
= https://api.docbutterfly.com/api/ConvertHtmlToPdf

Which host is which

Three names come up. Only one of them serves the API.

HostWhat it isDoes it serve /api/…?
api.docbutterfly.com The API. This is the one to use. Yes
docbutterfly.com This website — marketing pages, the portal, these docs. It serves no API. No — every /api/ path here is a 404
If you were given beta.docbutterfly.com: that is another name for the production website — the same site, the same accounts, the same data. It is not a separate beta environment and it serves no API, so an /api/… path there is a 404 like any other website path. Use the base URL above for calls.
A line at the top of the page saying "this is test, not production" means exactly that. Our own development and test sites label themselves in one small line; production carries no such line. If you see one, you are not on the site your account and your tokens live on.

A call that works, right now

Put your key in the environment, then paste this. It converts a line of HTML to a PDF and prints the response headers, so you can see what the call cost.

cURL
export DOCBUTTERFLY_API_KEY=df_your_key_here

curl -i -X POST "https://api.docbutterfly.com/api/ConvertHtmlToPdf" \
  -H "X-API-Key: $DOCBUTTERFLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"html": "<h1>Hello</h1>", "returnBase64": true}'

A 200 comes back with the PDF as base64 in the body, and three headers worth reading: X-Tokens-Used, X-Tokens-Remaining and X-Correlation-Id.

In a REST client — Hoppscotch, Postman, Insomnia, Bruno, Thunder Client

Same three things, whatever the client calls them:

  1. Method POST, URL https://api.docbutterfly.com/api/ConvertHtmlToPdf.
  2. A header — not an auth preset — named X-API-Key with your df_… key as the value. (If you would rather use the client's built-in Bearer auth, that works too: the same key as a bearer token.)
  3. A raw JSON body — not form-encoded, not multipart. With a good key and an empty or malformed body you get a 400 naming what was wrong; that is still progress.

If you already have a saved request that 404s, you do not need to rebuild it: change the host to api.docbutterfly.com and leave the path, the header and the body alone.

Authentication, and what a wrong key looks like

Every call carries the key in an X-API-Key header (or Authorization: Bearer df_…). A key in the query string is refused deliberately, because full request URLs end up in diagnostic logs.

You getIt meansFix
404 Wrong host, or a misspelled endpoint name. The API never answers 404 for a credential problem. Check the host is api.docbutterfly.com, then check the endpoint spelling. (Case does not matter — /api/converthtmltopdf routes the same as /api/ConvertHtmlToPdf.)
401 You reached the API and it does not accept that key — missing, mistyped, or replaced by a later regenerate. Compare against Portal → API Key. Reaching a 401 is progress: the host is right.
402 The key is good and the balance is not. Usage & Billing.
Use a deliberately bad key as a host test. Send X-API-Key: not-a-real-key to https://api.docbutterfly.com/api/ConvertHtmlToPdf. A 401 proves you are talking to the API. A 404 proves you are not.

“I am getting 404 on every request”

Almost always one thing: the request went to docbutterfly.com. That host serves this website. It has no /api routes at all, so it answers 404 to every one of them — with a valid key, an invalid key, or no key, identically. Nothing about the response tells you the host was the problem, which is what makes it worth an entry of its own.

Work through it in this order:

  1. Is the host api.docbutterfly.com? If it is anything else, that is the answer.
  2. Does GET https://api.docbutterfly.com/api/health return JSON in a browser? It needs no key. If that works and your call does not, the host is fine and the problem is the path or the method.
  3. Is the endpoint name spelled as the API Reference has it? Routing ignores case — /api/converthtmltopdf works — but a name that is not in the catalog is a 404, and so is a missing /api/ segment.
  4. Is the method right? Every operation is POST unless the reference says otherwise; a GET to a POST-only route does not answer 200.

Still stuck? Troubleshooting covers the rest of the status codes, and every error body carries a stable code field worth quoting when you ask us.

Two calls that cost you nothing

Both are useful before you write any real integration.

GET /api/health — which build am I talking to?

No key, no tokens. Open it in a browser if you like.

Health probe
curl "https://api.docbutterfly.com/api/health"

# { "status": "ok", "app": "dbf-prod", "env": "prod",
#   "commit": "df8059810b6eb9c6e815551a202338ee99b9fa70",
#   "shortCommit": "df805981", "branch": "...", "builtAt": "2026-09-04T17:23:55.000Z",
#   "node": "v24.19.0", "uptimeSeconds": 5121, "serverTime": "..." }

Quote shortCommit when you report something — it says exactly which build answered you, which is the difference between a bug and a deploy you have not picked up yet.

POST /api/quote — what will this job cost?

Takes your key, spends nothing. It prices a job — including a stacked pipeline — before you run it, and refuses operation names it does not recognize rather than quoting a default, so a typo cannot come back as a cheap answer for an expensive call.

Price a two-step job
curl -X POST "https://api.docbutterfly.com/api/quote" \
  -H "X-API-Key: $DOCBUTTERFLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"operations": ["ConvertHtmlToPdf", "WatermarkPdf"], "mode": "pipeline"}'

The answer carries tokens, the holdTokens that will actually be reserved, your balance, and whether the job is affordable. See Usage & Billing for how reservations and refunds work.

Webhooks and web forms use the same host

A published orchestration is reachable at https://api.docbutterfly.com/api/Webhook/{your-slug}, and a published web form at https://api.docbutterfly.com/api/f/{form-id}. Both are shown in full, with a copy button, on the page that published them — Orchestrator and Web Forms. Copy them from there rather than assembling them by hand; those are rendered from the same configuration as this page.

When you register one of these with somebody else — a payment provider, a scheduler, another SaaS — give them that exact URL. A webhook registered against docbutterfly.com will be delivered to a 404, and most senders retry silently before giving up.

Next: Quick Start walks the whole first call, and the API Testbed runs any endpoint from the browser without a key of your own.