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
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/:
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.
| Host | What it is | Does 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 |
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 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.
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:
- Method
POST, URLhttps://api.docbutterfly.com/api/ConvertHtmlToPdf. - A header — not an auth preset — named
X-API-Keywith yourdf_…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.) - A raw JSON body — not form-encoded, not multipart. With a good key and an
empty or malformed body you get a
400naming 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 get | It means | Fix |
|---|---|---|
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. |
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:
- Is the host
api.docbutterfly.com? If it is anything else, that is the answer. - Does
GET https://api.docbutterfly.com/api/healthreturn 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. - Is the endpoint name spelled as the API Reference has it?
Routing ignores case —
/api/converthtmltopdfworks — but a name that is not in the catalog is a404, and so is a missing/api/segment. - Is the method right? Every operation is
POSTunless the reference says otherwise; aGETto aPOST-only route does not answer200.
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.
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.
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.