Generate curl Snippets from OpenAPI to Reproduce API Bugs
Turn OpenAPI operations into accurate curl commands, attach auth headers correctly, and use snippets to reproduce frontend API failures for backend teammates.
Get Content-Type right for APIs, file uploads, and static assets — charset parameters, multipart boundaries, sniffing risks, and a practical MIME lookup workflow.
By codefunc
Every HTTP response that carries a body should say what that body is. The Content-Type header is how clients decide to parse JSON, render HTML, download a PDF, or reject a file upload. When the header is missing, wrong, or disagrees with the bytes, browsers guess — and guessing is how XSS slips through "safe" downloads and how mobile apps throw opaque parse errors on perfectly valid payloads.
Bottom line: Set Content-Type deliberately on API responses and uploads; include charset for text; never trust a client-supplied type without verifying magic bytes. Look up extensions and types with MIME Type Lookup, inspect raw header blocks with HTTP Header Parser, and decode data: URLs with Data URI Parser — all client-side.
Frontend and API developers who debug fetch failures, configure static hosting, accept file uploads, or wire multipart forms. If you have ever fixed a bug by "adding application/json" and hoped for the best, this guide makes the rules explicit.
A MIME type (media type) looks like:
type/subtype[; parameter=value]
Examples:
Content-Type: application/json
Content-Type: text/html; charset=utf-8
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxk
Content-Type: image/png
| Type tree | Role |
|---|---|
text/* |
Textual; often needs charset |
application/* |
Opaque or structured data (json, pdf, octet-stream) |
image/*, audio/*, video/* |
Binary media |
multipart/* |
Several parts, each with headers |
font/* |
Web fonts |
IANA registers official types; browsers also recognize common unofficial ones. When inventing a private format, prefer application/vnd.yourcompany.thing+json over overloading text/plain.
JSON APIs should send:
Content-Type: application/json; charset=utf-8
Notes:
charset on JSON is optional in theory (JSON is Unicode) but harmless and clarifies legacy clients.text/json is wrong — use application/json.text/plain with a JSON body forces clients to opt into parsing; some fetch wrappers will not auto-.json().200 + text/html to an API client is a frequent gateway bug.For fetch:
const res = await fetch("/api/items");
const type = res.headers.get("content-type") ?? "";
if (!type.includes("application/json")) {
throw new Error(`Expected JSON, got ${type}`);
}
Paste a captured response header block into HTTP Header Parser when you need to see duplicates, casing, or proxy-injected fields clearly.
| Body | Header |
|---|---|
| JSON | application/json |
| URL-encoded form | application/x-www-form-urlencoded |
| Multipart upload | multipart/form-data; boundary=… (set by the runtime) |
| Raw file PUT | Match the file (image/png, …) |
| GraphQL over HTTP | Usually application/json |
With FormData in the browser, do not set Content-Type manually — the boundary parameter must match the body, and fetch / XMLHttpRequest will set it for you. Overriding with multipart/form-data and no boundary breaks servers.
Never trust File.type or the client Content-Type alone. Browsers guess from extension; attackers rename files.
Defense in depth:
Content-Disposition: attachment when appropriateContent-Type when serving user content (for example, always image/jpeg after re-encoding)text/html and image/svg+xml uploads if you will serve them inline without sanitization — SVG can carry scriptUse MIME Type Lookup during development to map .wasm → application/wasm, .woff2 → font/woff2, .csv → text/csv, and similarly for less common assets. Wrong static-host mappings cause browsers to refuse fonts (CORS + type) or fail module loads.
For text/html, text/css, text/plain, and similar:
Content-Type: text/html; charset=utf-8
Missing charset leads to legacy encoding guesswork (mojibake). Serving UTF-8 bytes labeled as ISO-8859-1 corrupts non-ASCII. Keep files, DB connections, and HTTP headers aligned on UTF-8.
CSV downloads deserve care: Excel often expects a BOM or a vendor-specific type. Prefer text/csv; charset=utf-8 and document open-in-Excel quirks separately.
| Extension | Typical Content-Type |
|---|---|
.html |
text/html; charset=utf-8 |
.js / .mjs |
text/javascript; charset=utf-8 |
.css |
text/css; charset=utf-8 |
.json |
application/json |
.svg |
image/svg+xml |
.wasm |
application/wasm |
.map |
application/json |
| unknown | application/octet-stream (download) |
Service workers and module scripts are strict about types. A JS file served as application/octet-stream may not execute as a module.
Browsers historically sniffed bytes when Content-Type was missing or generic. Mitigations:
X-Content-Type-Options: nosniff
Pair nosniff with accurate types. Serving untrusted HTML as text/plain without nosniff has led to past XSS vectors in some browsers. For user-generated files, prefer attachment disposition plus correct types plus sanitization.
Data URLs embed a MIME type in the URI:
data:image/png;base64,iVBORw0KGgo…
data:text/plain;charset=utf-8,hello
When you receive an opaque data: string, parse it before trusting the payload. Data URI Parser splits media type, parameters, and data so you can verify you are about to embed an image — not text/html with a script — into the DOM.
| Symptom | Likely Content-Type issue |
|---|---|
res.json() throws |
Body is HTML error page or empty |
| Font blocked | Wrong type or missing CORS on font file |
| CSV opens as garbage | Charset / BOM / wrong type |
| Upload rejected | Boundary missing; client overrode header |
| Browser renders download as page | text/html on attacker-controlled bytes |
| SW fails to cache JS | Script served with wrong MIME |
Capture headers from DevTools, paste into HTTP Header Parser, and confirm the type against MIME Type Lookup.
Use these codefunc tools alongside this guide:
Treat Content-Type as part of your API contract, not decoration. Send precise types for JSON and static assets, let the browser set multipart boundaries, validate uploads by content rather than client labels, and disable sniffing with X-Content-Type-Options: nosniff. When debugging, look up the expected type, parse the header block, and inspect embedded data: media types locally with MIME Type Lookup, HTTP Header Parser, and Data URI Parser — no data needs to leave your machine.
Turn OpenAPI operations into accurate curl commands, attach auth headers correctly, and use snippets to reproduce frontend API failures for backend teammates.
Understand browser CORS, OPTIONS preflight, Access-Control-Allow-Origin, and credentials mode — plus the SPA misconfigurations that waste hours in production debugging.
A practical guide to Base64 and Base64url on the web — encoding binaries for data URLs and Authorization headers, padding rules, size costs, and when client-side tools keep secrets offline.
Find a developer tool