category enum Only signatures whose format is in this category.
Detect a file's real format from its magic bytes and flag when the filename or declared MIME type disagrees. Every signature cited to its own spec.
Authoritative reference data or standards computation
Filters are ANDed and rows stay in table order (category, then formatId, then signatureId). With no filters this returns the whole table. No match is an empty list with a warning, never a substituted row.
| Parameter | Type | Default & allowed | Description |
|---|---|---|---|
category | enum | default: any allowed: image | audio | video | archive | compression | document | executable | font | database | disk-image | data | any example: archive | Only signatures whose format is in this category. |
search | string | allowed: 1 – 64 example: zip | Case- and diacritic-insensitive substring match against the format name, the formatId, any extension and the media type. |
extension | string | allowed: 1 – 16 example: webp | Only signatures whose format lists this conventional extension. A leading dot is accepted and stripped; matching is case-insensitive. |
maxOffsetBytes | int | allowed: 1 – 65536 example: 16 | Only signatures decidable within the first N bytes of the file — that is, rows whose bytesNeeded ≤ N. |
containers | enum | default: all allowed: all | only | exclude example: only | 'only' keeps rows that refine another format's container (EPUB inside ZIP, AVIF inside ISO BMFF); 'exclude' keeps standalone signatures only. |
category enum Only signatures whose format is in this category.
search string Case- and diacritic-insensitive substring match against the format name, the formatId, any extension and the media type.
extension string Only signatures whose format lists this conventional extension. A leading dot is accepted and stripped; matching is case-insensitive.
maxOffsetBytes int Only signatures decidable within the first N bytes of the file — that is, rows whose bytesNeeded ≤ N.
containers enum 'only' keeps rows that refine another format's container (EPUB inside ZIP, AVIF inside ISO BMFF); 'exclude' keeps standalone signatures only.
| Parameter | Type | Default & allowed | Description |
|---|---|---|---|
count | int | default: all matches allowed: 1 – 100 example: 3 | Limit the number of returned records (1–100). Defaults to all matches. |
fields | list | example: signatureId,formatId | Return only these fields (comma-separated). Mutually exclusive with 'exclude'. |
exclude | list | example: sourceKind | Return all fields except these (comma-separated). |
format | enum | default: json allowed: json | ndjson | csv example: csv | Response format: json envelope, ndjson (one record per line) or csv. |
pretty | boolean | default: false example: true | Pretty-print the JSON response. |
unwrap | boolean | default: false example: true | Drop the envelope: return the raw array/object without data/meta wrapper. |
count int Limit the number of returned records (1–100). Defaults to all matches.
fields list Return only these fields (comma-separated). Mutually exclusive with 'exclude'.
exclude list Return all fields except these (comma-separated).
format enum Response format: json envelope, ndjson (one record per line) or csv.
pretty boolean Pretty-print the JSON response.
unwrap boolean Drop the envelope: return the raw array/object without data/meta wrapper.
| Field | Type | Description | Example |
|---|---|---|---|
signatureId | string | Stable kebab-case id of this byte pattern; the join key used by /lookup and /detect. | isobmff-ftyp-avif |
formatId | string | Stable kebab-case id of the format this pattern identifies. Several signatures may share one formatId (TIFF has two byte orders, RAR two generations, Mach-O four magics). | avif |
formatName | string | The format's name as its own specification writes it. | AV1 Image File Format |
category | string | One of: image | audio | video | archive | compression | document | executable | font | database | disk-image | data. ('any' is a filter value only, never a row value.) | image |
offset | integer | Byte offset of the pattern from the start of the file. 0 for most; 4 for the ISO BMFF ftyp box type, 36 for the ICC profile signature, 257 for POSIX ustar, 32769 for ISO 9660. | 4 |
pattern | string | The bytes, as space-separated uppercase hex pairs. `??` means "any byte" — a length or version field the format does not fix. | 66 74 79 70 61 76 69 66 |
bytesNeeded | integer | offset + pattern length: how many leading bytes you must have read before this signature can be evaluated at all. | 12 |
literalBytes | integer | Number of non-wildcard bytes in the pattern. This is the ranking weight /detect uses — more literal evidence ranks higher. | 8 |
extensions | string[] | Conventional extensions (lowercase, no dot, sorted). Empty for formats with no conventional extension. Conventions, not guarantees — the whole point of this endpoint is that an extension can lie. | ["avif","avifs"] |
mimeType nullable | string | The media type the format's own registration declares — or, absent a registration, the single type it is universally served as (audio/wav, application/x-tar) — and only when that exact string exists in this API's IANA media-types dataset. null in three cases, each deliberate: the format has neither a registration nor one de-facto type (ELF, Mach-O, Java class, ar, DEX, LZ4); the row identifies a container or tag that can wrap anything, so no type identifies it (CFB, ID3v2, the bare RIFF and ftyp rows, MBR/GPT); or the extension is registered to something unrelated (PSB). Never invented. | image/avif |
containerFormatId nullable | string | The formatId of the container this signature sits inside, when it refines one — 'zip' for EPUB, 'isobmff' for AVIF/HEIC/MP4, 'riff' for WAV/WebP/AVI, 'jpeg' for JFIF/Exif. null for standalone signatures. | isobmff |
trailer nullable | string | The end-of-file marker the format's spec defines, as hex ('3B' for GIF, '25 25 45 4F 46' for PDF's %%EOF). Recorded because upload validators ask for it; /detect never checks it, because /detect sees a prefix, not a whole file. null where the spec defines none. | null |
note nullable | string | What this signature does NOT tell you: the row's own caveat followed by the format's, when both exist — a per-row note never hides the format-level one. null when there is nothing honest to add. | Brand "avif". |
specification | string | Verbatim citation of the document AND clause the byte values were read from. Never a paraphrase, never a secondary source. | MP4 Registration Authority, registered file-type brands (verified 2026-07-30); box structure per ISO/IEC 14496-12, "File Type Box" |
specificationUrl nullable | string | HTTPS link to that document, or null when the only authoritative copy is paywalled (ITU-T T.81, ISO/IEC 14496-12) and no legitimate free copy exists. A decorative link would be worse than null. | https://mp4ra.org/registered-types/brands |
sourceKind | string | Where the citation sits on the authority ladder: standard (ISO/IEC, ITU-T, IETF, ECMA, W3C, POSIX), vendor-specification (Microsoft Open Specifications, Adobe, Google, RARLAB), registry (MP4RA, IANA), reference-implementation (bzip2, 7-Zip, Apple's loader.h — formats with no published specification). | registry |
signatureId string Stable kebab-case id of this byte pattern; the join key used by /lookup and /detect.
example: isobmff-ftyp-avif
formatId string Stable kebab-case id of the format this pattern identifies. Several signatures may share one formatId (TIFF has two byte orders, RAR two generations, Mach-O four magics).
example: avif
formatName string The format's name as its own specification writes it.
example: AV1 Image File Format
category string One of: image | audio | video | archive | compression | document | executable | font | database | disk-image | data. ('any' is a filter value only, never a row value.)
example: image
offset integer Byte offset of the pattern from the start of the file. 0 for most; 4 for the ISO BMFF ftyp box type, 36 for the ICC profile signature, 257 for POSIX ustar, 32769 for ISO 9660.
example: 4
pattern string The bytes, as space-separated uppercase hex pairs. `??` means "any byte" — a length or version field the format does not fix.
example: 66 74 79 70 61 76 69 66
bytesNeeded integer offset + pattern length: how many leading bytes you must have read before this signature can be evaluated at all.
example: 12
literalBytes integer Number of non-wildcard bytes in the pattern. This is the ranking weight /detect uses — more literal evidence ranks higher.
example: 8
extensions string[] Conventional extensions (lowercase, no dot, sorted). Empty for formats with no conventional extension. Conventions, not guarantees — the whole point of this endpoint is that an extension can lie.
example: ["avif","avifs"]
mimeType string nullable The media type the format's own registration declares — or, absent a registration, the single type it is universally served as (audio/wav, application/x-tar) — and only when that exact string exists in this API's IANA media-types dataset. null in three cases, each deliberate: the format has neither a registration nor one de-facto type (ELF, Mach-O, Java class, ar, DEX, LZ4); the row identifies a container or tag that can wrap anything, so no type identifies it (CFB, ID3v2, the bare RIFF and ftyp rows, MBR/GPT); or the extension is registered to something unrelated (PSB). Never invented.
example: image/avif
containerFormatId string nullable The formatId of the container this signature sits inside, when it refines one — 'zip' for EPUB, 'isobmff' for AVIF/HEIC/MP4, 'riff' for WAV/WebP/AVI, 'jpeg' for JFIF/Exif. null for standalone signatures.
example: isobmff
trailer string nullable The end-of-file marker the format's spec defines, as hex ('3B' for GIF, '25 25 45 4F 46' for PDF's %%EOF). Recorded because upload validators ask for it; /detect never checks it, because /detect sees a prefix, not a whole file. null where the spec defines none.
example: null
note string nullable What this signature does NOT tell you: the row's own caveat followed by the format's, when both exist — a per-row note never hides the format-level one. null when there is nothing honest to add.
example: Brand "avif".
specification string Verbatim citation of the document AND clause the byte values were read from. Never a paraphrase, never a secondary source.
example: MP4 Registration Authority, registered file-type brands (verified 2026-07-30); box structure per ISO/IEC 14496-12, "File Type Box"
specificationUrl string nullable HTTPS link to that document, or null when the only authoritative copy is paywalled (ITU-T T.81, ISO/IEC 14496-12) and no legitimate free copy exists. A decorative link would be worse than null.
example: https://mp4ra.org/registered-types/brands
sourceKind string Where the citation sits on the authority ladder: standard (ISO/IEC, ITU-T, IETF, ECMA, W3C, POSIX), vendor-specification (Microsoft Open Specifications, Adobe, Google, RARLAB), registry (MP4RA, IANA), reference-implementation (bzip2, 7-Zip, Apple's loader.h — formats with no published specification).
example: registry
/api/file-signatures?category=archive {
"data": [
{
"signatureId": "sevenzip-signature",
"formatId": "7z",
"formatName": "7z archive",
"category": "archive",
"offset": 0,
"pattern": "37 7A BC AF 27 1C",
"bytesNeeded": 6,
"literalBytes": 6,
"extensions": [
"7z"
],
"mimeType": "application/x-7z-compressed",
"containerFormatId": null,
"trailer": null,
"note": null,
"specification": "7-Zip, DOC/7zFormat.txt — SignatureHeader kSignature = \"7\" \"z\" 0xBC 0xAF 0x27 0x1C (7z has no published specification)",
"specificationUrl": "https://github.com/ip7z/7zip/blob/main/DOC/7zFormat.txt",
"sourceKind": "reference-implementation"
},
{
"signatureId": "ar-magic",
"formatId": "ar",
"formatName": "Unix archive (ar)",
"category": "archive",
"offset": 0,
"pattern": "21 3C 61 72 63 68 3E 0A",
"bytesNeeded": 8,
"literalBytes": 8,
"extensions": [
"a",
"ar"
],
"mimeType": null,
"containerFormatId": null,
"trailer": null,
"note": "No formal standard exists for ar, and there is no registered or de-facto media type for it. This row is also the first 8 bytes of a Debian package.",
"specification": "FreeBSD ar(5), \"ar\" — the archive begins with the magic string \"!<arch>\" followed by a newline; the ar format has no formal standard",
…
"generatedAt": "2026-07-30T15:14:08.000Z"
}
} /api/file-signatures?maxOffsetBytes=16 {
"data": [
{
"signatureId": "isobmff-ftyp-avif",
"formatId": "avif",
"formatName": "AV1 Image File Format",
"category": "image",
"offset": 4,
"pattern": "66 74 79 70 61 76 69 66",
"bytesNeeded": 12,
"literalBytes": 8,
"extensions": [
"avif",
"avifs"
],
"mimeType": "image/avif",
"containerFormatId": "isobmff",
"trailer": null,
"note": "Brand \"avif\".",
"specification": "MP4 Registration Authority, registered file-type brands (verified 2026-07-30); box structure per ISO/IEC 14496-12, \"File Type Box\"",
"specificationUrl": "https://mp4ra.org/registered-types/brands",
"sourceKind": "registry"
},
{
"signatureId": "isobmff-ftyp-avis",
"formatId": "avif",
"formatName": "AV1 Image File Format",
"category": "image",
"offset": 4,
"pattern": "66 74 79 70 61 76 69 73",
"bytesNeeded": 12,
"literalBytes": 8,
"extensions": [
"avif",
"avifs"
],
"mimeType": "image/avif",
"containerFormatId": "isobmff",
"trailer": null,
"note": "Brand \"avis\" — an AVIF image sequence.",
…
"generatedAt": "2026-07-30T15:14:08.000Z"
}
} /api/file-signatures?containers=only {
"data": [
{
"signatureId": "isobmff-ftyp-avif",
"formatId": "avif",
"formatName": "AV1 Image File Format",
"category": "image",
"offset": 4,
"pattern": "66 74 79 70 61 76 69 66",
"bytesNeeded": 12,
"literalBytes": 8,
"extensions": [
"avif",
"avifs"
],
"mimeType": "image/avif",
"containerFormatId": "isobmff",
"trailer": null,
"note": "Brand \"avif\".",
"specification": "MP4 Registration Authority, registered file-type brands (verified 2026-07-30); box structure per ISO/IEC 14496-12, \"File Type Box\"",
"specificationUrl": "https://mp4ra.org/registered-types/brands",
"sourceKind": "registry"
},
{
"signatureId": "isobmff-ftyp-avis",
"formatId": "avif",
"formatName": "AV1 Image File Format",
"category": "image",
"offset": 4,
"pattern": "66 74 79 70 61 76 69 73",
"bytesNeeded": 12,
"literalBytes": 8,
"extensions": [
"avif",
"avifs"
],
"mimeType": "image/avif",
"containerFormatId": "isobmff",
"trailer": null,
"note": "Brand \"avis\" — an AVIF image sequence.",
…
"generatedAt": "2026-07-30T15:14:08.000Z"
}
} /api/file-signatures?extension=webp {
"data": [
{
"signatureId": "webp-riff-form",
"formatId": "webp",
"formatName": "WebP",
"category": "image",
"offset": 0,
"pattern": "52 49 46 46 ?? ?? ?? ?? 57 45 42 50",
"bytesNeeded": 12,
"literalBytes": 8,
"extensions": [
"webp"
],
"mimeType": "image/webp",
"containerFormatId": "riff",
"trailer": null,
"note": "The four wildcard bytes are the RIFF file size.",
"specification": "WebP Container Specification, \"WebP File Header\" — \"RIFF\", file size, then \"WEBP\"",
"specificationUrl": "https://developers.google.com/speed/webp/docs/riff_container",
"sourceKind": "vendor-specification"
}
],
"meta": {
"endpoint": "file-signatures",
"count": 1,
"params": {
"category": "any",
"extension": "webp",
"containers": "all"
},
"generatedAt": "2026-07-30T15:14:08.000Z"
}
} /api/file-signatures?search=zip&fields=signatureId,pattern,specification {
"data": [
{
"signatureId": "epub-ocf-mimetype",
"pattern": "50 4B 03 04 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 6D 69 6D 65 74 79 70 65 61 70 70 6C 69 63 61 74 69 6F 6E 2F 65 70 75 62 2B 7A 69 70",
"specification": "EPUB Open Container Format 3.2, §4.3 \"OCF ZIP Container Media Type Identification\" — the \"mimetype\" file MUST be the first file, uncompressed, with no extra field, and contain \"application/epub+zip\""
},
{
"signatureId": "zip-end-of-central-directory",
"pattern": "50 4B 05 06",
"specification": ".ZIP File Format Specification, APPNOTE 6.3.10 (2022-11-01), §4.3.16 \"End of central directory record\" — signature 0x06054b50"
},
{
"signatureId": "zip-local-file-header",
"pattern": "50 4B 03 04",
"specification": ".ZIP File Format Specification, APPNOTE 6.3.10 (2022-11-01), §4.3.7 \"Local file header\" — signature 0x04034b50"
},
{
"signatureId": "bzip2-stream-header",
"pattern": "42 5A 68 ??",
"specification": "bzip2 1.0.8 reference implementation (compress.c / decompress.c) — the stream header is \"B\" \"Z\" \"h\" followed by the block-size digit \"1\"–\"9\"; bzip2 has no published specification"
},
{
"signatureId": "gzip-member-header",
"pattern": "1F 8B",
"specification": "RFC 1952 §2.3.1 \"Member header and trailer\" — ID1 = 0x1f, ID2 = 0x8b"
}
],
"meta": {
"endpoint": "file-signatures",
"count": 5,
"params": {
"category": "any",
"search": "zip",
"containers": "all"
},
"generatedAt": "2026-07-30T15:14:08.000Z"
}
} Returns every signature the supplied prefix satisfies, ranked by literal evidence. Nothing is fetched and nothing is stored. A malformed claimedType is deliberately NOT a 400 — a garbage Content-Type is the finding you came for, so it is reported inside mismatch and the request still succeeds. mismatch says 'disagrees' only when the bytes genuinely refute the claim; a claim this table cannot decide (DOCX vs a plain ZIP, WebM vs Matroska, or a signature whose deciding bytes lie past your prefix) comes back as null with a reason, never as an accusation.
| Parameter | Type | Default & allowed | Description |
|---|---|---|---|
bytes
required
| string | allowed: 1 – 8192 example: 89504e470d0a1a0a | The first bytes of the file, from offset 0. Hex or base64 per `encoding`. Hex accepts upper/lower case, an optional leading '0x', and space, ':' or '-' separators (so xxd/hexdump output pastes straight in); base64 accepts the RFC 4648 base64 or base64url alphabet, padded or unpadded, with whitespace ignored. 8,192 characters is 4,096 bytes of hex or about 6,144 bytes of base64. |
encoding | enum | default: hex allowed: hex | base64 example: base64 | How `bytes` is encoded. |
claimedName | string | allowed: 1 – 255 example: avatar.png | The filename the client claimed (an upload's `filename`). Only its basename and extension are used; the longest suffix this table registers wins, so 'backup.tar.gz' resolves to 'gz'. Never fetched, never written anywhere. |
claimedType | string | allowed: 1 – 255 example: image/png | The Content-Type the client declared. Parameters (';charset=…') are ignored for comparison. A malformed value is reported in `mismatch`, not rejected with a 400. Percent-encode a structured suffix's '+' as %2B (`application%2Fepub%2Bzip`): a literal '+' in a query string means a space, and a space is never legal in a media type — if that happens the endpoint recovers the '+' and says so in `mismatch.reasons`. |
bytes string required The first bytes of the file, from offset 0. Hex or base64 per `encoding`. Hex accepts upper/lower case, an optional leading '0x', and space, ':' or '-' separators (so xxd/hexdump output pastes straight in); base64 accepts the RFC 4648 base64 or base64url alphabet, padded or unpadded, with whitespace ignored. 8,192 characters is 4,096 bytes of hex or about 6,144 bytes of base64.
encoding enum How `bytes` is encoded.
claimedName string The filename the client claimed (an upload's `filename`). Only its basename and extension are used; the longest suffix this table registers wins, so 'backup.tar.gz' resolves to 'gz'. Never fetched, never written anywhere.
claimedType string The Content-Type the client declared. Parameters (';charset=…') are ignored for comparison. A malformed value is reported in `mismatch`, not rejected with a 400. Percent-encode a structured suffix's '+' as %2B (`application%2Fepub%2Bzip`): a literal '+' in a query string means a space, and a space is never legal in a media type — if that happens the endpoint recovers the '+' and says so in `mismatch.reasons`.
| Parameter | Type | Default & allowed | Description |
|---|---|---|---|
fields | list | example: bytesProvided,encoding | Return only these fields (comma-separated). Mutually exclusive with 'exclude'. |
exclude | list | example: mismatch | Return all fields except these (comma-separated). |
pretty | boolean | default: false example: true | Pretty-print the JSON response. |
unwrap | boolean | default: false example: true | Drop the envelope: return the raw array/object without data/meta wrapper. |
fields list Return only these fields (comma-separated). Mutually exclusive with 'exclude'.
exclude list Return all fields except these (comma-separated).
pretty boolean Pretty-print the JSON response.
unwrap boolean Drop the envelope: return the raw array/object without data/meta wrapper.
| Field | Type | Description | Example |
|---|---|---|---|
bytesProvided | integer | How many bytes `bytes` decoded to. | 8 |
encoding | string | The resolved `encoding`. | hex |
hexPreview | string | The first up to 32 decoded bytes as space-separated uppercase hex, so you can see exactly what was parsed. Truncated with "…" beyond that. | 89 50 4E 47 0D 0A 1A 0A |
matches | object[] | Every signature these bytes satisfy, ranked by literalBytes descending, then offset ascending, then signatureId ascending. Capped at 12 entries (a warning names how many were dropped). Empty array when nothing matches. Element keys: `signatureId`, `formatId`, `formatName`, `category`, `offset`, `pattern`, `matchedBytes` (the bytes actually present at that offset), `bytesNeeded`, `literalBytes`, `mimeType`, `extensions`, `containerFormatId`, `note`, `specification`, `specificationUrl`. | [{"signatureId":"png-signature","formatId":"png","formatName":"Portable Network Graphics","category":"image","offset":0,"pattern":"89 50 4E 47 0D 0A 1A 0A","matchedBytes":"89 50 4E 47 0D 0A 1A 0A","bytesNeeded":8,"literalBytes":8,"mimeType":"image/png","extensions":["png"],"containerFormatId":null,"note":null,"specification":"W3C PNG Specification (Third Edition), §5.2 \"PNG signature\"","specificationUrl":"https://www.w3.org/TR/png-3/"}] |
matchCount | integer | Total matches found (may exceed matches.length when capped). | 1 |
best nullable | object | matches[0], or null when nothing matched. The match with the most literal evidence — not a verdict. Same element shape as `matches`. | {"signatureId":"png-signature","formatId":"png","formatName":"Portable Network Graphics","category":"image","offset":0,"pattern":"89 50 4E 47 0D 0A 1A 0A","matchedBytes":"89 50 4E 47 0D 0A 1A 0A","bytesNeeded":8,"literalBytes":8,"mimeType":"image/png","extensions":["png"],"containerFormatId":null,"note":null,"specification":"W3C PNG Specification (Third Edition), §5.2 \"PNG signature\"","specificationUrl":"https://www.w3.org/TR/png-3/"} |
ambiguous | boolean | true when two or more matches remain that are NOT in a container/refinement relationship with each other — i.e. these bytes genuinely satisfy rival formats. 0xCAFEBABE (a Java class file and a Mach-O universal binary) is the canonical case. | false |
notEvaluated | integer | How many table rows could not be evaluated because their bytesNeeded exceeds bytesProvided. A zero-match answer with a non-zero notEvaluated is not evidence of an unknown format. | 24 |
bytesForWholeTable | integer | The largest bytesNeeded in the table — how many leading bytes would make notEvaluated zero. Constant per deploy, and beyond the `bytes` cap by design while ISO 9660 is in the table. | 32774 |
claimedName nullable | string | The basename of `claimedName` as supplied, or null. Never fetched, never written anywhere. | avatar.png |
claimedType nullable | string | `claimedType` as supplied, lowercased with parameters stripped, or null. | image/png |
mismatch nullable | object | null when neither claim was supplied. Otherwise `{ verdict: "agrees" | "disagrees" | "undetermined", claimedExtension, extensionAgrees, typeAgrees, reasons }`. A flag is `false` only when the bytes REFUTE the claim — every signature of every format that claims that extension or media type has a literal byte you supplied that contradicts it. It is `null` when the claim was not supplied, could not be parsed, names something this table has no signature for (DOCX, JAR, video/webm and audio/x-ms-wma are all indistinguishable from their container in a prefix), or is still consistent with a signature whose deciding bytes lie past the prefix you supplied. `verdict` is "undetermined" when nothing matched, when the claim could not be parsed, and whenever neither flag came out true or false. `reasons` is a bounded list of plain-English findings, each naming the claim and the evidence. | {"verdict":"disagrees","claimedExtension":"jpg","extensionAgrees":false,"typeAgrees":false,"reasons":["The bytes match Portable Network Graphics; the filename claims '.jpg', which this table registers only for JPEG (JFIF/Exif-agnostic baseline marker sequence), JPEG with an Exif APP1 segment — and every signature those formats define is contradicted by the bytes you supplied.","The declared Content-Type 'image/jpeg' belongs to JPEG (JFIF/Exif-agnostic baseline marker sequence), JPEG with a JFIF APP0 segment, JPEG with an Exif APP1 segment in this table, and every signature those formats define is contradicted by the bytes you supplied (which match image/png)."]} |
bytesProvided integer How many bytes `bytes` decoded to.
example: 8
encoding string The resolved `encoding`.
example: hex
hexPreview string The first up to 32 decoded bytes as space-separated uppercase hex, so you can see exactly what was parsed. Truncated with "…" beyond that.
example: 89 50 4E 47 0D 0A 1A 0A
matches object[] Every signature these bytes satisfy, ranked by literalBytes descending, then offset ascending, then signatureId ascending. Capped at 12 entries (a warning names how many were dropped). Empty array when nothing matches. Element keys: `signatureId`, `formatId`, `formatName`, `category`, `offset`, `pattern`, `matchedBytes` (the bytes actually present at that offset), `bytesNeeded`, `literalBytes`, `mimeType`, `extensions`, `containerFormatId`, `note`, `specification`, `specificationUrl`.
example: [{"signatureId":"png-signature","formatId":"png","formatName":"Portable Network Graphics","category":"image","offset":0,"pattern":"89 50 4E 47 0D 0A 1A 0A","matchedBytes":"89 50 4E 47 0D 0A 1A 0A","bytesNeeded":8,"literalBytes":8,"mimeType":"image/png","extensions":["png"],"containerFormatId":null,"note":null,"specification":"W3C PNG Specification (Third Edition), §5.2 \"PNG signature\"","specificationUrl":"https://www.w3.org/TR/png-3/"}]
matchCount integer Total matches found (may exceed matches.length when capped).
example: 1
best object nullable matches[0], or null when nothing matched. The match with the most literal evidence — not a verdict. Same element shape as `matches`.
example: {"signatureId":"png-signature","formatId":"png","formatName":"Portable Network Graphics","category":"image","offset":0,"pattern":"89 50 4E 47 0D 0A 1A 0A","matchedBytes":"89 50 4E 47 0D 0A 1A 0A","bytesNeeded":8,"literalBytes":8,"mimeType":"image/png","extensions":["png"],"containerFormatId":null,"note":null,"specification":"W3C PNG Specification (Third Edition), §5.2 \"PNG signature\"","specificationUrl":"https://www.w3.org/TR/png-3/"}
ambiguous boolean true when two or more matches remain that are NOT in a container/refinement relationship with each other — i.e. these bytes genuinely satisfy rival formats. 0xCAFEBABE (a Java class file and a Mach-O universal binary) is the canonical case.
example: false
notEvaluated integer How many table rows could not be evaluated because their bytesNeeded exceeds bytesProvided. A zero-match answer with a non-zero notEvaluated is not evidence of an unknown format.
example: 24
bytesForWholeTable integer The largest bytesNeeded in the table — how many leading bytes would make notEvaluated zero. Constant per deploy, and beyond the `bytes` cap by design while ISO 9660 is in the table.
example: 32774
claimedName string nullable The basename of `claimedName` as supplied, or null. Never fetched, never written anywhere.
example: avatar.png
claimedType string nullable `claimedType` as supplied, lowercased with parameters stripped, or null.
example: image/png
mismatch object nullable null when neither claim was supplied. Otherwise `{ verdict: "agrees" | "disagrees" | "undetermined", claimedExtension, extensionAgrees, typeAgrees, reasons }`. A flag is `false` only when the bytes REFUTE the claim — every signature of every format that claims that extension or media type has a literal byte you supplied that contradicts it. It is `null` when the claim was not supplied, could not be parsed, names something this table has no signature for (DOCX, JAR, video/webm and audio/x-ms-wma are all indistinguishable from their container in a prefix), or is still consistent with a signature whose deciding bytes lie past the prefix you supplied. `verdict` is "undetermined" when nothing matched, when the claim could not be parsed, and whenever neither flag came out true or false. `reasons` is a bounded list of plain-English findings, each naming the claim and the evidence.
example: {"verdict":"disagrees","claimedExtension":"jpg","extensionAgrees":false,"typeAgrees":false,"reasons":["The bytes match Portable Network Graphics; the filename claims '.jpg', which this table registers only for JPEG (JFIF/Exif-agnostic baseline marker sequence), JPEG with an Exif APP1 segment — and every signature those formats define is contradicted by the bytes you supplied.","The declared Content-Type 'image/jpeg' belongs to JPEG (JFIF/Exif-agnostic baseline marker sequence), JPEG with a JFIF APP0 segment, JPEG with an Exif APP1 segment in this table, and every signature those formats define is contradicted by the bytes you supplied (which match image/png)."]}
/api/file-signatures/detect?bytes=89504e470d0a1a0a {
"data": {
"bytesProvided": 8,
"encoding": "hex",
"hexPreview": "89 50 4E 47 0D 0A 1A 0A",
"matches": [
{
"signatureId": "png-signature",
"formatId": "png",
"formatName": "Portable Network Graphics",
"category": "image",
"offset": 0,
"pattern": "89 50 4E 47 0D 0A 1A 0A",
"matchedBytes": "89 50 4E 47 0D 0A 1A 0A",
"bytesNeeded": 8,
"literalBytes": 8,
"mimeType": "image/png",
"extensions": [
"png"
],
"containerFormatId": null,
"note": null,
"specification": "W3C PNG Specification (Third Edition), §5.2 \"PNG signature\"",
"specificationUrl": "https://www.w3.org/TR/png-3/"
}
],
"matchCount": 1,
"best": {
"signatureId": "png-signature",
"formatId": "png",
"formatName": "Portable Network Graphics",
"category": "image",
"offset": 0,
"pattern": "89 50 4E 47 0D 0A 1A 0A",
"matchedBytes": "89 50 4E 47 0D 0A 1A 0A",
"bytesNeeded": 8,
"literalBytes": 8,
"mimeType": "image/png",
"extensions": [
"png"
…
"generatedAt": "2026-07-30T15:14:08.000Z"
}
} /api/file-signatures/detect?bytes=89504e470d0a1a0a&claimedName=avatar.jpg&claimedType=image/jpeg {
"data": {
"bytesProvided": 8,
"encoding": "hex",
"hexPreview": "89 50 4E 47 0D 0A 1A 0A",
"matches": [
{
"signatureId": "png-signature",
"formatId": "png",
"formatName": "Portable Network Graphics",
"category": "image",
"offset": 0,
"pattern": "89 50 4E 47 0D 0A 1A 0A",
"matchedBytes": "89 50 4E 47 0D 0A 1A 0A",
"bytesNeeded": 8,
"literalBytes": 8,
"mimeType": "image/png",
"extensions": [
"png"
],
"containerFormatId": null,
"note": null,
"specification": "W3C PNG Specification (Third Edition), §5.2 \"PNG signature\"",
"specificationUrl": "https://www.w3.org/TR/png-3/"
}
],
"matchCount": 1,
"best": {
"signatureId": "png-signature",
"formatId": "png",
"formatName": "Portable Network Graphics",
"category": "image",
"offset": 0,
"pattern": "89 50 4E 47 0D 0A 1A 0A",
"matchedBytes": "89 50 4E 47 0D 0A 1A 0A",
"bytesNeeded": 8,
"literalBytes": 8,
"mimeType": "image/png",
"extensions": [
"png"
…
]
}
} /api/file-signatures/detect?bytes=cafebabe {
"data": {
"bytesProvided": 4,
"encoding": "hex",
"hexPreview": "CA FE BA BE",
"matches": [
{
"signatureId": "java-class-magic",
"formatId": "java-class",
"formatName": "Java class file",
"category": "executable",
"offset": 0,
"pattern": "CA FE BA BE",
"matchedBytes": "CA FE BA BE",
"bytesNeeded": 4,
"literalBytes": 4,
"mimeType": null,
"extensions": [
"class"
],
"containerFormatId": null,
"note": "Compiled Java classes have no IANA registration, and no single type they are universally served as either — a class file is loaded by a JVM, not served over HTTP — so this row reports none rather than pick the unregistered application/java-vm that some servers send for .class. The magic is shared with the Mach-O universal binary header.",
"specification": "Java Virtual Machine Specification, Java SE 21, §4.1 \"The ClassFile Structure\" — magic = 0xCAFEBABE",
"specificationUrl": "https://docs.oracle.com/javase/specs/jvms/se21/html/jvms-4.html"
},
{
"signatureId": "macho-fat-32",
"formatId": "mach-o-universal",
"formatName": "Mach-O universal (\"fat\") binary",
"category": "executable",
"offset": 0,
"pattern": "CA FE BA BE",
"matchedBytes": "CA FE BA BE",
"bytesNeeded": 4,
"literalBytes": 4,
"mimeType": null,
"extensions": [
"dylib"
],
"containerFormatId": null,
…
]
}
} /api/file-signatures/detect?bytes=UklGRiQAAABXRUJQ&encoding=base64 {
"data": {
"bytesProvided": 12,
"encoding": "base64",
"hexPreview": "52 49 46 46 24 00 00 00 57 45 42 50",
"matches": [
{
"signatureId": "webp-riff-form",
"formatId": "webp",
"formatName": "WebP",
"category": "image",
"offset": 0,
"pattern": "52 49 46 46 ?? ?? ?? ?? 57 45 42 50",
"matchedBytes": "52 49 46 46 24 00 00 00 57 45 42 50",
"bytesNeeded": 12,
"literalBytes": 8,
"mimeType": "image/webp",
"extensions": [
"webp"
],
"containerFormatId": "riff",
"note": "The four wildcard bytes are the RIFF file size.",
"specification": "WebP Container Specification, \"WebP File Header\" — \"RIFF\", file size, then \"WEBP\"",
"specificationUrl": "https://developers.google.com/speed/webp/docs/riff_container"
},
{
"signatureId": "riff-header",
"formatId": "riff",
"formatName": "Resource Interchange File Format (bare header)",
"category": "data",
"offset": 0,
"pattern": "52 49 46 46",
"matchedBytes": "52 49 46 46",
"bytesNeeded": 4,
"literalBytes": 4,
"mimeType": null,
"extensions": [],
"containerFormatId": null,
"note": "A generic container. The form type at offset 8 is what names the format — WAVE, AVI and WebP are separate rows here and outrank this one.",
"specification": "Microsoft AVI RIFF File Reference, \"RIFF File Format\" — the RIFF header is the FOURCC \"RIFF\", a 4-byte file size, then a FOURCC form type",
…
"generatedAt": "2026-07-30T15:14:08.000Z"
}
} /api/file-signatures/detect?bytes=504b0304 {
"data": {
"bytesProvided": 4,
"encoding": "hex",
"hexPreview": "50 4B 03 04",
"matches": [
{
"signatureId": "zip-local-file-header",
"formatId": "zip",
"formatName": "ZIP archive",
"category": "archive",
"offset": 0,
"pattern": "50 4B 03 04",
"matchedBytes": "50 4B 03 04",
"bytesNeeded": 4,
"literalBytes": 4,
"mimeType": "application/zip",
"extensions": [
"zip"
],
"containerFormatId": null,
"note": "The first entry of a non-empty archive. DOCX, XLSX, PPTX, JAR, APK, ODF-in-name-only and ZIP-based installers all begin with exactly these four bytes, and none of their specifications fixes the entry order, so they cannot be told apart from a plain ZIP in the prefix. EPUB and OpenDocument are the only exceptions in this table because their specifications DO require an uncompressed \"mimetype\" first entry.",
"specification": ".ZIP File Format Specification, APPNOTE 6.3.10 (2022-11-01), §4.3.7 \"Local file header\" — signature 0x04034b50",
"specificationUrl": "https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"
}
],
"matchCount": 1,
"best": {
"signatureId": "zip-local-file-header",
"formatId": "zip",
"formatName": "ZIP archive",
"category": "archive",
"offset": 0,
"pattern": "50 4B 03 04",
"matchedBytes": "50 4B 03 04",
"bytesNeeded": 4,
"literalBytes": 4,
"mimeType": "application/zip",
"extensions": [
"zip"
…
"generatedAt": "2026-07-30T15:14:08.000Z"
}
} /api/file-signatures/detect?bytes=504b0304&claimedName=report.docx&claimedType=application%2Fvnd.openxmlformats-officedocument.wordprocessingml.document {
"data": {
"bytesProvided": 4,
"encoding": "hex",
"hexPreview": "50 4B 03 04",
"matches": [
{
"signatureId": "zip-local-file-header",
"formatId": "zip",
"formatName": "ZIP archive",
"category": "archive",
"offset": 0,
"pattern": "50 4B 03 04",
"matchedBytes": "50 4B 03 04",
"bytesNeeded": 4,
"literalBytes": 4,
"mimeType": "application/zip",
"extensions": [
"zip"
],
"containerFormatId": null,
"note": "The first entry of a non-empty archive. DOCX, XLSX, PPTX, JAR, APK, ODF-in-name-only and ZIP-based installers all begin with exactly these four bytes, and none of their specifications fixes the entry order, so they cannot be told apart from a plain ZIP in the prefix. EPUB and OpenDocument are the only exceptions in this table because their specifications DO require an uncompressed \"mimetype\" first entry.",
"specification": ".ZIP File Format Specification, APPNOTE 6.3.10 (2022-11-01), §4.3.7 \"Local file header\" — signature 0x04034b50",
"specificationUrl": "https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"
}
],
"matchCount": 1,
"best": {
"signatureId": "zip-local-file-header",
"formatId": "zip",
"formatName": "ZIP archive",
"category": "archive",
"offset": 0,
"pattern": "50 4B 03 04",
"matchedBytes": "50 4B 03 04",
"bytesNeeded": 4,
"literalBytes": 4,
"mimeType": "application/zip",
"extensions": [
"zip"
…
"generatedAt": "2026-07-30T15:14:08.000Z"
}
} /api/file-signatures/detect?bytes=504b0304&claimedType=application%2Fepub%2Bzip {
"data": {
"bytesProvided": 4,
"encoding": "hex",
"hexPreview": "50 4B 03 04",
"matches": [
{
"signatureId": "zip-local-file-header",
"formatId": "zip",
"formatName": "ZIP archive",
"category": "archive",
"offset": 0,
"pattern": "50 4B 03 04",
"matchedBytes": "50 4B 03 04",
"bytesNeeded": 4,
"literalBytes": 4,
"mimeType": "application/zip",
"extensions": [
"zip"
],
"containerFormatId": null,
"note": "The first entry of a non-empty archive. DOCX, XLSX, PPTX, JAR, APK, ODF-in-name-only and ZIP-based installers all begin with exactly these four bytes, and none of their specifications fixes the entry order, so they cannot be told apart from a plain ZIP in the prefix. EPUB and OpenDocument are the only exceptions in this table because their specifications DO require an uncompressed \"mimetype\" first entry.",
"specification": ".ZIP File Format Specification, APPNOTE 6.3.10 (2022-11-01), §4.3.7 \"Local file header\" — signature 0x04034b50",
"specificationUrl": "https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"
}
],
"matchCount": 1,
"best": {
"signatureId": "zip-local-file-header",
"formatId": "zip",
"formatName": "ZIP archive",
"category": "archive",
"offset": 0,
"pattern": "50 4B 03 04",
"matchedBytes": "50 4B 03 04",
"bytesNeeded": 4,
"literalBytes": 4,
"mimeType": "application/zip",
"extensions": [
"zip"
…
"generatedAt": "2026-07-30T15:14:08.000Z"
}
} /api/file-signatures/detect?bytes=52494646&claimedName=hero.webp&claimedType=image%2Fwebp {
"data": {
"bytesProvided": 4,
"encoding": "hex",
"hexPreview": "52 49 46 46",
"matches": [
{
"signatureId": "riff-header",
"formatId": "riff",
"formatName": "Resource Interchange File Format (bare header)",
"category": "data",
"offset": 0,
"pattern": "52 49 46 46",
"matchedBytes": "52 49 46 46",
"bytesNeeded": 4,
"literalBytes": 4,
"mimeType": null,
"extensions": [],
"containerFormatId": null,
"note": "A generic container. The form type at offset 8 is what names the format — WAVE, AVI and WebP are separate rows here and outrank this one.",
"specification": "Microsoft AVI RIFF File Reference, \"RIFF File Format\" — the RIFF header is the FOURCC \"RIFF\", a 4-byte file size, then a FOURCC form type",
"specificationUrl": "https://learn.microsoft.com/en-us/windows/win32/directshow/avi-riff-file-reference"
}
],
"matchCount": 1,
"best": {
"signatureId": "riff-header",
"formatId": "riff",
"formatName": "Resource Interchange File Format (bare header)",
"category": "data",
"offset": 0,
"pattern": "52 49 46 46",
"matchedBytes": "52 49 46 46",
"bytesNeeded": 4,
"literalBytes": 4,
"mimeType": null,
"extensions": [],
"containerFormatId": null,
"note": "A generic container. The form type at offset 8 is what names the format — WAVE, AVI and WebP are separate rows here and outrank this one.",
"specification": "Microsoft AVI RIFF File Reference, \"RIFF File Format\" — the RIFF header is the FOURCC \"RIFF\", a 4-byte file size, then a FOURCC form type",
…
"generatedAt": "2026-07-30T15:14:08.000Z"
}
} Provide exactly one of extension, mimeType or formatId. A key claimed by several formats resolves to the least refined of them — a standalone format before one that only exists inside another, so .jpg resolves to jpeg rather than to the Exif refinement of it — then table order, and a warning always names the other claimants. An unknown key is an honest 404 that says the format is not covered by this table — never a substituted record.
| Parameter | Type | Default & allowed | Description |
|---|---|---|---|
extension | string | allowed: 1 – 16 example: webp | Extension to look up (case-insensitive; a leading dot is fine: 'webp' or '.webp'). |
mimeType | string | allowed: 1 – 255 example: application/pdf | Media type to look up (case-insensitive; parameters are stripped). |
formatId | string | allowed: 1 – 48 example: sqlite3 | This table's own format id, as returned by the list route (case-insensitive). |
extension string Extension to look up (case-insensitive; a leading dot is fine: 'webp' or '.webp').
mimeType string Media type to look up (case-insensitive; parameters are stripped).
formatId string This table's own format id, as returned by the list route (case-insensitive).
| Parameter | Type | Default & allowed | Description |
|---|---|---|---|
fields | list | example: formatId,formatName | Return only these fields (comma-separated). Mutually exclusive with 'exclude'. |
exclude | list | example: note | Return all fields except these (comma-separated). |
pretty | boolean | default: false example: true | Pretty-print the JSON response. |
unwrap | boolean | default: false example: true | Drop the envelope: return the raw array/object without data/meta wrapper. |
fields list Return only these fields (comma-separated). Mutually exclusive with 'exclude'.
exclude list Return all fields except these (comma-separated).
pretty boolean Pretty-print the JSON response.
unwrap boolean Drop the envelope: return the raw array/object without data/meta wrapper.
| Field | Type | Description | Example |
|---|---|---|---|
formatId | string | This table's stable id for the format. | webp |
formatName | string | The format's name as its own specification writes it. | WebP |
category | string | One of: image | audio | video | archive | compression | document | executable | font | database | disk-image | data. | image |
extensions | string[] | Conventional extensions (lowercase, no dot, sorted). Conventions, not guarantees. | ["webp"] |
mimeType nullable | string | The media type the format's own registration declares (or the single type it is universally served as), when that exact string exists in this API's IANA media-types dataset. null when no type identifies this format — see the list route's field description for the three cases. | image/webp |
containerFormatId nullable | string | The container this format lives inside, when it has one. | riff |
signatures | object[] | Every signature registered for this format, in table order, bounded by construction (the most any format has today is four, for Mach-O). Element keys: `signatureId`, `offset`, `pattern`, `bytesNeeded`, `literalBytes`, `trailer`, `note`, `specification`, `specificationUrl`, `sourceKind`. | [{"signatureId":"webp-riff-form","offset":0,"pattern":"52 49 46 46 ?? ?? ?? ?? 57 45 42 50","bytesNeeded":12,"literalBytes":8,"trailer":null,"note":"The four wildcard bytes are the RIFF file size.","specification":"WebP Container Specification, \"WebP File Header\" — \"RIFF\", file size, then \"WEBP\"","specificationUrl":"https://developers.google.com/speed/webp/docs/riff_container","sourceKind":"vendor-specification"}] |
signatureCount | integer | signatures.length. | 1 |
note nullable | string | Format-level caveat: what this signature does not tell you. null when there is nothing honest to add. | null |
formatId string This table's stable id for the format.
example: webp
formatName string The format's name as its own specification writes it.
example: WebP
category string One of: image | audio | video | archive | compression | document | executable | font | database | disk-image | data.
example: image
extensions string[] Conventional extensions (lowercase, no dot, sorted). Conventions, not guarantees.
example: ["webp"]
mimeType string nullable The media type the format's own registration declares (or the single type it is universally served as), when that exact string exists in this API's IANA media-types dataset. null when no type identifies this format — see the list route's field description for the three cases.
example: image/webp
containerFormatId string nullable The container this format lives inside, when it has one.
example: riff
signatures object[] Every signature registered for this format, in table order, bounded by construction (the most any format has today is four, for Mach-O). Element keys: `signatureId`, `offset`, `pattern`, `bytesNeeded`, `literalBytes`, `trailer`, `note`, `specification`, `specificationUrl`, `sourceKind`.
example: [{"signatureId":"webp-riff-form","offset":0,"pattern":"52 49 46 46 ?? ?? ?? ?? 57 45 42 50","bytesNeeded":12,"literalBytes":8,"trailer":null,"note":"The four wildcard bytes are the RIFF file size.","specification":"WebP Container Specification, \"WebP File Header\" — \"RIFF\", file size, then \"WEBP\"","specificationUrl":"https://developers.google.com/speed/webp/docs/riff_container","sourceKind":"vendor-specification"}]
signatureCount integer signatures.length.
example: 1
note string nullable Format-level caveat: what this signature does not tell you. null when there is nothing honest to add.
example: null
/api/file-signatures/lookup?extension=webp {
"data": {
"formatId": "webp",
"formatName": "WebP",
"category": "image",
"extensions": [
"webp"
],
"mimeType": "image/webp",
"containerFormatId": "riff",
"signatures": [
{
"signatureId": "webp-riff-form",
"offset": 0,
"pattern": "52 49 46 46 ?? ?? ?? ?? 57 45 42 50",
"bytesNeeded": 12,
"literalBytes": 8,
"trailer": null,
"note": "The four wildcard bytes are the RIFF file size.",
"specification": "WebP Container Specification, \"WebP File Header\" — \"RIFF\", file size, then \"WEBP\"",
"specificationUrl": "https://developers.google.com/speed/webp/docs/riff_container",
"sourceKind": "vendor-specification"
}
],
"signatureCount": 1,
"note": null
},
"meta": {
"endpoint": "file-signatures",
"route": "/lookup",
"params": {
"extension": "webp"
},
"generatedAt": "2026-07-30T15:14:08.000Z"
}
} /api/file-signatures/lookup?mimeType=application/pdf {
"data": {
"formatId": "pdf",
"formatName": "Portable Document Format",
"category": "document",
"extensions": [
"pdf"
],
"mimeType": "application/pdf",
"containerFormatId": null,
"signatures": [
{
"signatureId": "pdf-header",
"offset": 0,
"pattern": "25 50 44 46 2D",
"bytesNeeded": 5,
"literalBytes": 5,
"trailer": "25 25 45 4F 46",
"note": "The version digits after %PDF- are not part of this pattern. The %%EOF trailer is recorded but never checked: /detect sees a prefix, not a whole file.",
"specification": "ISO 32000-2:2020 (PDF 2.0), §7.5.2 \"File header\" — the first line is %PDF-n.m; §7.5.5 \"File trailer\" — the last line of the file is %%EOF",
"specificationUrl": "https://pdfa.org/sponsored-standards/",
"sourceKind": "standard"
}
],
"signatureCount": 1,
"note": "The version digits after %PDF- are not part of this pattern. The %%EOF trailer is recorded but never checked: /detect sees a prefix, not a whole file."
},
"meta": {
"endpoint": "file-signatures",
"route": "/lookup",
"params": {
"mimeType": "application/pdf"
},
"generatedAt": "2026-07-30T15:14:08.000Z"
}
} /api/file-signatures/lookup?formatId=isobmff {
"data": {
"formatId": "isobmff",
"formatName": "ISO base media file format (bare ftyp box)",
"category": "video",
"extensions": [],
"mimeType": null,
"containerFormatId": null,
"signatures": [
{
"signatureId": "isobmff-ftyp",
"offset": 4,
"pattern": "66 74 79 70",
"bytesNeeded": 8,
"literalBytes": 4,
"trailer": null,
"note": "This row means only \"an ISO base media file\". The 4-byte major brand at offset 8 is what names the format, and every brand this table covers is a separate row that outranks this one.",
"specification": "ISO/IEC 14496-12, \"File Type Box\" — the ftyp box type occupies bytes 4–7 of the file and is followed by the major brand",
"specificationUrl": null,
"sourceKind": "standard"
}
],
"signatureCount": 1,
"note": "This row means only \"an ISO base media file\". The 4-byte major brand at offset 8 is what names the format, and every brand this table covers is a separate row that outranks this one."
},
"meta": {
"endpoint": "file-signatures",
"route": "/lookup",
"params": {
"formatId": "isobmff"
},
"generatedAt": "2026-07-30T15:14:08.000Z"
}
} /api/file-signatures/lookup?formatId=mach-o {
"data": {
"formatId": "mach-o",
"formatName": "Mach-O object/executable",
"category": "executable",
"extensions": [
"dylib",
"o"
],
"mimeType": null,
"containerFormatId": null,
"signatures": [
{
"signatureId": "macho-cigam-32",
"offset": 0,
"pattern": "CE FA ED FE",
"bytesNeeded": 4,
"literalBytes": 4,
"trailer": null,
"note": "MH_CIGAM — 32-bit, byte-swapped relative to the host (little-endian on disk). Four magics: two byte orders times 32- and 64-bit. Mach-O has no registered media type.",
"specification": "Apple xnu, EXTERNAL_HEADERS/mach-o/loader.h, the \"mach_header\" / \"mach_header_64\" magic constants — MH_MAGIC 0xfeedface, MH_CIGAM 0xcefaedfe, MH_MAGIC_64 0xfeedfacf, MH_CIGAM_64 0xcffaedfe (Mach-O has no published specification)",
"specificationUrl": "https://github.com/apple-oss-distributions/xnu/blob/main/EXTERNAL_HEADERS/mach-o/loader.h",
"sourceKind": "reference-implementation"
},
{
"signatureId": "macho-cigam-64",
"offset": 0,
"pattern": "CF FA ED FE",
"bytesNeeded": 4,
"literalBytes": 4,
"trailer": null,
"note": "MH_CIGAM_64 — 64-bit little-endian on disk, which is what current macOS binaries look like. Four magics: two byte orders times 32- and 64-bit. Mach-O has no registered media type.",
"specification": "Apple xnu, EXTERNAL_HEADERS/mach-o/loader.h, the \"mach_header\" / \"mach_header_64\" magic constants — MH_MAGIC 0xfeedface, MH_CIGAM 0xcefaedfe, MH_MAGIC_64 0xfeedfacf, MH_CIGAM_64 0xcffaedfe (Mach-O has no published specification)",
"specificationUrl": "https://github.com/apple-oss-distributions/xnu/blob/main/EXTERNAL_HEADERS/mach-o/loader.h",
"sourceKind": "reference-implementation"
},
{
"signatureId": "macho-magic-32",
"offset": 0,
"pattern": "FE ED FA CE",
…
"generatedAt": "2026-07-30T15:14:08.000Z"
}
} /api/file-signatures/lookup?extension=jpg {
"data": {
"formatId": "jpeg",
"formatName": "JPEG (JFIF/Exif-agnostic baseline marker sequence)",
"category": "image",
"extensions": [
"jpe",
"jpeg",
"jpg"
],
"mimeType": "image/jpeg",
"containerFormatId": null,
"signatures": [
{
"signatureId": "jpeg-soi",
"offset": 0,
"pattern": "FF D8 FF",
"bytesNeeded": 3,
"literalBytes": 3,
"trailer": null,
"note": "The third byte is the X'FF' that begins the marker after SOI, which the marker syntax requires; the marker itself is not fixed, so this row deliberately claims only three bytes.",
"specification": "ITU-T T.81 (09/1992), also published as ISO/IEC 10918-1, Annex B \"Compressed data formats\", \"Marker assignments\" (Table B.1) — SOI = X'FFD8', and every marker is X'FF' followed by a byte that is neither X'00' nor X'FF'",
"specificationUrl": "https://www.w3.org/Graphics/JPEG/itu-t81.pdf",
"sourceKind": "standard"
}
],
"signatureCount": 1,
"note": "The third byte is the X'FF' that begins the marker after SOI, which the marker syntax requires; the marker itself is not fixed, so this row deliberately claims only three bytes."
},
"meta": {
"endpoint": "file-signatures",
"route": "/lookup",
"params": {
"extension": "jpg"
},
"generatedAt": "2026-07-30T15:14:08.000Z",
"warnings": [
"'.jpg' is claimed by 2 formats in this table — it resolves to the least refined of them, 'jpeg'. Also claiming it: exif-jpeg."
]
}
} Answers the question every upload tutorial skips: 'read the first 16 bytes' decides some of this table and not the rest, and this route says exactly which. All figures are counted from the shipped table, never hand-written.
| Parameter | Type | Default & allowed | Description |
|---|---|---|---|
bytes | int | default: 16 allowed: 1 – 65536 example: 12 | How many leading bytes your validator reads. The default is 16 because 'read the first 16 bytes' is the convention every upload tutorial repeats — this route says what that actually buys you. |
category | enum | default: any allowed: image | audio | video | archive | compression | document | executable | font | database | disk-image | data | any example: image | Restrict the answer to one category. |
bytes int How many leading bytes your validator reads. The default is 16 because 'read the first 16 bytes' is the convention every upload tutorial repeats — this route says what that actually buys you.
category enum Restrict the answer to one category.
| Parameter | Type | Default & allowed | Description |
|---|---|---|---|
fields | list | example: category,bytesRequested | Return only these fields (comma-separated). Mutually exclusive with 'exclude'. |
exclude | list | example: beyondRequest | Return all fields except these (comma-separated). |
pretty | boolean | default: false example: true | Pretty-print the JSON response. |
unwrap | boolean | default: false example: true | Drop the envelope: return the raw array/object without data/meta wrapper. |
fields list Return only these fields (comma-separated). Mutually exclusive with 'exclude'.
exclude list Return all fields except these (comma-separated).
pretty boolean Pretty-print the JSON response.
unwrap boolean Drop the envelope: return the raw array/object without data/meta wrapper.
| Field | Type | Description | Example |
|---|---|---|---|
category | string | Resolved `category`. | any |
bytesRequested | integer | Resolved `bytes` (echoed here as well as in meta.params). | 16 |
signatureCount | integer | Signatures in scope. | 116 |
formatCount | integer | Distinct formats in scope. | 99 |
signaturesDecidable | integer | Signatures whose bytesNeeded ≤ bytesRequested. | 108 |
formatsDecidable | integer | Formats with at least one decidable signature. | 91 |
maxBytesNeeded | integer | Largest bytesNeeded in scope — the ceiling that decides everything. | 32774 |
thresholds | object[] | Fixed, documented cut-offs (4, 8, 12, 16, 32, 64, 128, 264, 512, 1024, then maxBytesNeeded if not already listed), each `{ bytes, signaturesDecidable, formatsDecidable }`. Cut-offs above maxBytesNeeded are omitted. | [{"bytes":4,"signaturesDecidable":62,"formatsDecidable":55}] |
beyondRequest | object[] | Up to 10 signatures that need more than bytesRequested, ascending by bytesNeeded, each `{ signatureId, formatName, bytesNeeded }` — so the number is never mysterious. A warning names how many more exist. | [{"signatureId":"tar-ustar","formatName":"POSIX ustar archive","bytesNeeded":265}] |
category string Resolved `category`.
example: any
bytesRequested integer Resolved `bytes` (echoed here as well as in meta.params).
example: 16
signatureCount integer Signatures in scope.
example: 116
formatCount integer Distinct formats in scope.
example: 99
signaturesDecidable integer Signatures whose bytesNeeded ≤ bytesRequested.
example: 108
formatsDecidable integer Formats with at least one decidable signature.
example: 91
maxBytesNeeded integer Largest bytesNeeded in scope — the ceiling that decides everything.
example: 32774
thresholds object[] Fixed, documented cut-offs (4, 8, 12, 16, 32, 64, 128, 264, 512, 1024, then maxBytesNeeded if not already listed), each `{ bytes, signaturesDecidable, formatsDecidable }`. Cut-offs above maxBytesNeeded are omitted.
example: [{"bytes":4,"signaturesDecidable":62,"formatsDecidable":55}]
beyondRequest object[] Up to 10 signatures that need more than bytesRequested, ascending by bytesNeeded, each `{ signatureId, formatName, bytesNeeded }` — so the number is never mysterious. A warning names how many more exist.
example: [{"signatureId":"tar-ustar","formatName":"POSIX ustar archive","bytesNeeded":265}]
/api/file-signatures/prefix-length {
"data": {
"category": "any",
"bytesRequested": 16,
"signatureCount": 116,
"formatCount": 99,
"signaturesDecidable": 102,
"formatsDecidable": 85,
"maxBytesNeeded": 32774,
"thresholds": [
{
"bytes": 4,
"signaturesDecidable": 48,
"formatsDecidable": 40
},
{
"bytes": 8,
"signaturesDecidable": 71,
"formatsDecidable": 61
},
{
"bytes": 12,
"signaturesDecidable": 100,
"formatsDecidable": 83
},
{
"bytes": 16,
"signaturesDecidable": 102,
"formatsDecidable": 85
},
{
"bytes": 32,
"signaturesDecidable": 104,
"formatsDecidable": 87
},
{
"bytes": 64,
"signaturesDecidable": 108,
"formatsDecidable": 91
},
…
]
}
} /api/file-signatures/prefix-length?bytes=12&category=image {
"data": {
"category": "image",
"bytesRequested": 12,
"signatureCount": 23,
"formatCount": 19,
"signaturesDecidable": 23,
"formatsDecidable": 19,
"maxBytesNeeded": 12,
"thresholds": [
{
"bytes": 4,
"signaturesDecidable": 7,
"formatsDecidable": 6
},
{
"bytes": 8,
"signaturesDecidable": 12,
"formatsDecidable": 10
},
{
"bytes": 12,
"signaturesDecidable": 23,
"formatsDecidable": 19
}
],
"beyondRequest": []
},
"meta": {
"endpoint": "file-signatures",
"route": "/prefix-length",
"params": {
"bytes": 12,
"category": "image"
},
"generatedAt": "2026-07-30T15:14:08.000Z"
}
} /api/file-signatures/prefix-length?bytes=65536 {
"data": {
"category": "any",
"bytesRequested": 65536,
"signatureCount": 116,
"formatCount": 99,
"signaturesDecidable": 116,
"formatsDecidable": 99,
"maxBytesNeeded": 32774,
"thresholds": [
{
"bytes": 4,
"signaturesDecidable": 48,
"formatsDecidable": 40
},
{
"bytes": 8,
"signaturesDecidable": 71,
"formatsDecidable": 61
},
{
"bytes": 12,
"signaturesDecidable": 100,
"formatsDecidable": 83
},
{
"bytes": 16,
"signaturesDecidable": 102,
"formatsDecidable": 85
},
{
"bytes": 32,
"signaturesDecidable": 104,
"formatsDecidable": 87
},
{
"bytes": 64,
"signaturesDecidable": 108,
"formatsDecidable": 91
},
…
"generatedAt": "2026-07-30T15:14:08.000Z"
}
} 116 byte patterns across 99 file formats, every one of them read from the format's own published specification and cited to the document and clause it came from — 84 distinct citations, verified 2026-07-30. Nothing here comes from an aggregated signature list, an npm package or memory. If a clause could not be cited, the row was left out.
Four routes:
/api/file-signatures — the whole table, filterable by category, search, extension, maxOffsetBytes and containers./api/file-signatures/detect?bytes=… — paste the first bytes you read off a stream (hex or base64) and get every signature they satisfy, ranked. Add claimedName and claimedType and it also tells you whether an upload's filename and Content-Type agree with its bytes./api/file-signatures/lookup?extension=… — one format and all of its signatures, by extension, media type or format id./api/file-signatures/prefix-length?bytes=16 — how many leading bytes a streaming validator must read, and exactly what that buys you./detect returns a ranked list, not a verdict. The order is a total order: literalBytes descending, then offset ascending, then signatureId ascending — no randomness, no scoring heuristic, no tie left to array order. A refinement therefore naturally outranks its container (ftyp + brand avif is 8 literal bytes and beats the bare ftyp row's 4) and both are returned. best is documented as "the match with the most literal evidence", which is not the same thing as "what this file is".
claimedName and claimedType are checked against the bytes, and extensionAgrees/typeAgrees are deliberately three-valued. A claim is only false when the bytes refute it: every signature of every format in this table that claims that extension or media type has a literal byte, inside the prefix you supplied, that contradicts it. PNG bytes labelled .jpg/image/jpeg are refuted, because byte 0 of all three JPEG rows disagrees — so that is false, and verdict is "disagrees".
Two situations produce null instead, and both used to be the easy place for a tool like this to lie:
application/…wordprocessingml.document can be neither confirmed nor refuted. You get null and a reason naming what the bytes do match — never an accusation the endpoint has no basis for..webp sits at byte 8. Those four bytes do not contradict the claim, so the answer is null with the byte count the signature needs — the same honesty notEvaluated gives the match list.That is why the useful pattern for an upload validator is "reject on disagrees, read more bytes on undetermined", not "reject on anything that is not agrees".
safe, valid or trusted field, and there never will be./detect returns a list.offset/skip parameter: a caller-asserted offset base cannot be verified, and getting it wrong produces a confidently wrong answer. Rows whose bytesNeeded exceeds what you supplied are counted in notEvaluated, never silently treated as "no match". ISO 9660's identifier sits at byte 32 769 and is therefore always unevaluable through /detect — that is stated rather than hidden, because it is what makes /prefix-length honest.trailer exists because upload validators ask for it. A prefix cannot see the end of a file./detect returns zip and says so — and a DOCX or JAR claimedType comes back as typeAgrees: null with a reason, not as a mismatch, because these bytes cannot refute it. EPUB and OpenDocument are the only exceptions, because OCF §4.3 and ODF Part 2 §3.3 require an uncompressed mimetype first entry — for those, the bytes really are a signature..doc, .xls, .ppt, .msg and .msi all share the Compound File Binary header; the distinguishing streams live in the directory, which a prefix does not reach.DocType element decides, and reading it means parsing EBML. A video/webm claim therefore comes back null, not false. The same applies to ASF: whether the file is WMV or WMA lives in the stream properties objects, past the prefix.<!DOCTYPE is neither required nor case-fixed — the HTML spec matches it ASCII-case-insensitively, so unlike XML's <?xml, which XML 1.0 §2.8 spells exactly, it is not a fixed byte sequence at all), Brotli (RFC 7932 defines none), raw DEFLATE, zlib streams (RFC 1950's CMF/FLG is a checksummed pair, not a constant), raw MPEG audio frames (the FF Ex sync word is a frame marker, not a file signature) and .pyc (the magic changes with every CPython release). Each absence is a documented decision, not an oversight.?? wildcard cannot express without claiming all 256 first bytes.extensions describes what people name these files. This endpoint exists precisely because that can lie./detect takes the first bytes you read off the stream (hex or base64) and returns every signature those bytes satisfy, ranked by how many literal bytes matched, with the canonical media type. Pass claimedName and claimedType and it also tells you whether the upload's filename and Content-Type agree with the bytes.
No. A match means the header is consistent with a format. It is not a validity check, not a parse, and not a malware scan; a polyglot file can satisfy two signatures at once, which is why /detect returns a ranked list instead of one winner.
You cannot, from the first bytes: all of them begin with the same ZIP local-file-header signature, and none of their specifications fixes the entry order. /detect says so instead of guessing — pass claimedType=application/vnd.openxmlformats-officedocument.wordprocessingml.document and it reports typeAgrees: null, not a mismatch. EPUB and OpenDocument are the exceptions: their own specs require an uncompressed mimetype entry first, so those bytes really are a signature.
Because extensionAgrees and typeAgrees are only false when the bytes genuinely refute the claim — every signature for that extension or media type contradicts a byte you supplied. null means this table has no signature for what you claimed (a real DOCX or WebM), or the deciding bytes sit past your prefix (four bytes of a WebP are just the RIFF header). Reject on disagrees; read more bytes on undetermined.
/prefix-length answers it from the table: state how many bytes you can afford and it reports how many signatures and formats that decides, which ones need more (POSIX ustar sits at offset 257; ISO 9660's CD001 at 32769) and the exact ceiling for the whole table, which is 32774 bytes.
The complete IANA media type registry with file extensions merged in — look up any type or extension, or strictly parse a Content-Type value into its parts.
Fake file metadata — kebab-case names, the correct MIME type for every extension, plausible per-kind sizes, unix paths and seeded SHA-256-style checksums.
Generate coherent mock file-upload sessions and multipart records with exact byte progress, lifecycle states, checksums and safe example URLs.
Test glob patterns and .gitignore rules against paths — which rule won, at which line, and whether a negation was cancelled by an excluded parent directory.
Strict RFC 4648 base16, base32, base64 and base64url encoding/decoding with Unicode-safe UTF-8, padding control and malformed-input errors.
Diagnose and repair mojibake — the byte round-trip that turned café into café and привет into привет — across 28 legacy encodings.