Skip to main content

HTTP Structured Fields Parser API

REAL DATA

Parse and serialize RFC 9651 structured field values — items, lists, dictionaries, parameters, dates and display strings — with exact type reporting.

Authoritative reference data or standards computation

Base URL
/api/structured-fields
Capabilities
2 routes
Last updated
July 29, 2026
Data source

GET /api/structured-fields/parse

Runs RFC 9651 Section 4.2 over the value, then re-serializes the result with Section 4.1 so you can see its canonical form.

Live requestRuns against the public API
No key required
GET/api/structured-fields/parse?value=u%3D1%2C+i&field=Priority

Request parameters

The raw field value, at most 4096 characters. Whitespace is significant and is not trimmed, and a bare '+' in a query string decodes to a space — percent-encode it as %2B, which matters because '+' is both a base64 character and a token character. Omit the parameter to represent a field that is not present, which is an empty list or dictionary and a parse error for an item.

Top-level structured type, as chosen by the field's own specification. Required unless 'field' resolves it from the IANA registry; supplying both is fine as long as they agree.

Registered HTTP field name (case-insensitive). Its IANA Structured Type selects the top-level type, which is echoed back in the response.

Also require the input to be in canonical form. Set false for plain RFC 9651 parsing, which accepts leading zeros, extra whitespace and unpadded base64.

Advanced response options4 options

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

Return all fields except these (comma-separated).

Pretty-print the JSON response.

Drop the envelope: return the raw array/object without data/meta wrapper.

Response

Example parameters are ready. Send the request to inspect the live response.

Route reference

Code samples Ready-to-copy requests in 4 languages
Choose a code sample language
curl "https://randomapi.dev/api/structured-fields/parse?field=Priority&value=u%3D1%2C%20i"
const res = await fetch("https://randomapi.dev/api/structured-fields/parse?field=Priority&value=u%3D1%2C%20i");
const { data, meta } = await res.json();
import requests

data = requests.get("https://randomapi.dev/api/structured-fields/parse?field=Priority&value=u%3D1%2C%20i").json()["data"]
$json = json_decode(file_get_contents(
  "https://randomapi.dev/api/structured-fields/parse?field=Priority&value=u%3D1%2C%20i"
), true);
$data = $json["data"];
Parameters Route-specific request inputs 4
value string

The raw field value, at most 4096 characters. Whitespace is significant and is not trimmed, and a bare '+' in a query string decodes to a space — percent-encode it as %2B, which matters because '+' is both a base64 character and a token character. Omit the parameter to represent a field that is not present, which is an empty list or dictionary and a parse error for an item.

allowed: ≤ 4096
example: value=u=1, i
type enum

Top-level structured type, as chosen by the field's own specification. Required unless 'field' resolves it from the IANA registry; supplying both is fine as long as they agree.

allowed: item | list | dictionary
example: type=dictionary
field string

Registered HTTP field name (case-insensitive). Its IANA Structured Type selects the top-level type, which is echoed back in the response.

allowed: 1 – 128
example: field=Priority
strict boolean

Also require the input to be in canonical form. Set false for plain RFC 9651 parsing, which accepts leading zeros, extra whitespace and unpadded base64.

default: true
example: strict=false
Universal parameters Shared response and formatting options 4
fields list

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

example: fields=input,type
exclude list

Return all fields except these (comma-separated).

example: exclude=inputIsCanonical
pretty boolean

Pretty-print the JSON response.

default: false
example: pretty=true
unwrap boolean

Drop the envelope: return the raw array/object without data/meta wrapper.

default: false
example: unwrap=true
Response schema Fields returned in each record 7
input string

The field value exactly as supplied, before any whitespace was discarded.

example: u=1, i

type string

Resolved top-level type: item, list or dictionary.

example: dictionary

field string nullable

Registered IANA field name that selected the type, or null when 'type' was given directly.

example: Priority

registryType string nullable

The IANA registry's Structured Type label for that field (Dictionary, List, Item or Token), or null when no field was given.

example: Dictionary

parsed object

The parsed value in this API's own JSON mapping: every node is {type, value} plus {params} wherever RFC 9651 allows parameters. RFC 9651 defines no JSON mapping; this one is ours.

example: {"type":"dictionary","value":{"u":{"type":"integer","value":1,"params":{}},"i":{"type":"boolean","value":true,"params":{}}}}

canonical string

The parsed value re-serialized with RFC 9651 Section 4.1. Empty when an empty list or dictionary means the field should be omitted entirely.

example: u=1, i

inputIsCanonical boolean

True when 'input' already equals 'canonical' character for character.

example: true

Documented examples

Build-generated requests and complete responses
5
Parse a Priority header via the IANA registry
GET /api/structured-fields/parse?field=Priority&value=u%3D1%2C%20i
{
  "data": {
    "input": "u=1, i",
    "type": "dictionary",
    "field": "Priority",
    "registryType": "Dictionary",
    "parsed": {
      "type": "dictionary",
      "value": {
        "u": {
          "type": "integer",
          "value": 1,
          "params": {}
        },
        "i": {
          "type": "boolean",
          "value": true,
          "params": {}
        }
      }
    },
    "canonical": "u=1, i",
    "inputIsCanonical": true
  },
  "meta": {
    "endpoint": "structured-fields",
    "route": "/parse",
    "params": {
      "value": "u=1, i",
      "field": "Priority",
      "strict": true,
      "type": "dictionary"
    },
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
Parse a Cache-Status list with parameters
GET /api/structured-fields/parse?field=Cache-Status&value=ExampleCache%3Bhit%3Bttl%3D376
{
  "data": {
    "input": "ExampleCache;hit;ttl=376",
    "type": "list",
    "field": "Cache-Status",
    "registryType": "List",
    "parsed": {
      "type": "list",
      "value": [
        {
          "type": "token",
          "value": "ExampleCache",
          "params": {
            "hit": {
              "type": "boolean",
              "value": true
            },
            "ttl": {
              "type": "integer",
              "value": 376
            }
          }
        }
      ]
    },
    "canonical": "ExampleCache;hit;ttl=376",
    "inputIsCanonical": true
  },
  "meta": {
    "endpoint": "structured-fields",
    "route": "/parse",
    "params": {
      "value": "ExampleCache;hit;ttl=376",
      "field": "Cache-Status",
      "strict": true,
      "type": "list"
    },
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
Dictionary with an inner list
GET /api/structured-fields/parse?type=dictionary&value=a%3D(1%202)%2C%20b%3D3%2C%20c%3D4%3Baa%3Dbb
{
  "data": {
    "input": "a=(1 2), b=3, c=4;aa=bb",
    "type": "dictionary",
    "field": null,
    "registryType": null,
    "parsed": {
      "type": "dictionary",
      "value": {
        "a": {
          "type": "innerlist",
          "value": [
            {
              "type": "integer",
              "value": 1,
              "params": {}
            },
            {
              "type": "integer",
              "value": 2,
              "params": {}
            }
          ],
          "params": {}
        },
        "b": {
          "type": "integer",
          "value": 3,
          "params": {}
        },
        "c": {
          "type": "integer",
          "value": 4,
          "params": {
            "aa": {
              "type": "token",
              "value": "bb"
            }
          }
        }
    …
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
Accept a non-canonical value
GET /api/structured-fields/parse?type=list&value=1%20%2C%2042&strict=false
{
  "data": {
    "input": "1 , 42",
    "type": "list",
    "field": null,
    "registryType": null,
    "parsed": {
      "type": "list",
      "value": [
        {
          "type": "integer",
          "value": 1,
          "params": {}
        },
        {
          "type": "integer",
          "value": 42,
          "params": {}
        }
      ]
    },
    "canonical": "1, 42",
    "inputIsCanonical": false
  },
  "meta": {
    "endpoint": "structured-fields",
    "route": "/parse",
    "params": {
      "value": "1 , 42",
      "type": "list",
      "strict": false
    },
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
Date and display string items
GET /api/structured-fields/parse?type=list&value=%401659578233%2C%20%25%22caf%25c3%25a9%22
{
  "data": {
    "input": "@1659578233, %\"caf%c3%a9\"",
    "type": "list",
    "field": null,
    "registryType": null,
    "parsed": {
      "type": "list",
      "value": [
        {
          "type": "date",
          "value": 1659578233,
          "params": {}
        },
        {
          "type": "displaystring",
          "value": "café",
          "params": {}
        }
      ]
    },
    "canonical": "@1659578233, %\"caf%c3%a9\"",
    "inputIsCanonical": true
  },
  "meta": {
    "endpoint": "structured-fields",
    "route": "/parse",
    "params": {
      "value": "@1659578233, %\"caf%c3%a9\"",
      "type": "list",
      "strict": true
    },
    "generatedAt": "2026-07-29T08:13:22.000Z",
    "warnings": [
      "This value uses the Date and Display String types, which RFC 9651 added; parsers written against the obsolete RFC 8941 reject them."
    ]
  }
}

GET /api/structured-fields/serialize

Applies RFC 9651 Section 4.1, including half-to-even decimal rounding, Boolean-true omission and canonical base64 padding.

Live requestRuns against the public API
No key required
GET/api/structured-fields/serialize?json=%7B%22type%22%3A%22integer%22%2C%22value%22%3A5%2C%22params%22%3A%7B%22foo%22%3A%7B%22type%22%3A%22token%22%2C%22value%22%3A%22bar%22%7D%7D%7D&type=item

Request parameters

The structure to serialize in this API's JSON mapping, at most 4096 characters. The 'parsed' object returned by /parse can be pasted here unchanged. Percent-encode '+' as %2B: a bare '+' in a query string decodes to a space, which corrupts base64 byte-sequence values.

Top-level structured type the JSON describes. An item's own 'type' is its bare type (integer, token, …), so this states which of the three containers is being serialized.

Advanced response options4 options

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

Return all fields except these (comma-separated).

Pretty-print the JSON response.

Drop the envelope: return the raw array/object without data/meta wrapper.

Response

Example parameters are ready. Send the request to inspect the live response.

Route reference

Code samples Ready-to-copy requests in 4 languages
Choose a code sample language
curl "https://randomapi.dev/api/structured-fields/serialize?type=item&json=%7B%22type%22%3A%22integer%22%2C%22value%22%3A5%2C%22params%22%3A%7B%22foo%22%3A%7B%22type%22%3A%22token%22%2C%22value%22%3A%22bar%22%7D%7D%7D"
const res = await fetch("https://randomapi.dev/api/structured-fields/serialize?type=item&json=%7B%22type%22%3A%22integer%22%2C%22value%22%3A5%2C%22params%22%3A%7B%22foo%22%3A%7B%22type%22%3A%22token%22%2C%22value%22%3A%22bar%22%7D%7D%7D");
const { data, meta } = await res.json();
import requests

data = requests.get("https://randomapi.dev/api/structured-fields/serialize?type=item&json=%7B%22type%22%3A%22integer%22%2C%22value%22%3A5%2C%22params%22%3A%7B%22foo%22%3A%7B%22type%22%3A%22token%22%2C%22value%22%3A%22bar%22%7D%7D%7D").json()["data"]
$json = json_decode(file_get_contents(
  "https://randomapi.dev/api/structured-fields/serialize?type=item&json=%7B%22type%22%3A%22integer%22%2C%22value%22%3A5%2C%22params%22%3A%7B%22foo%22%3A%7B%22type%22%3A%22token%22%2C%22value%22%3A%22bar%22%7D%7D%7D"
), true);
$data = $json["data"];
Parameters Route-specific request inputs 2
json string required

The structure to serialize in this API's JSON mapping, at most 4096 characters. The 'parsed' object returned by /parse can be pasted here unchanged. Percent-encode '+' as %2B: a bare '+' in a query string decodes to a space, which corrupts base64 byte-sequence values.

allowed: 2 – 4096
example: json={"type":"integer","value":5,"params":{"foo":{"type":"token","value":"bar"}}}
type enum required

Top-level structured type the JSON describes. An item's own 'type' is its bare type (integer, token, …), so this states which of the three containers is being serialized.

allowed: item | list | dictionary
example: type=item
Universal parameters Shared response and formatting options 4
fields list

Return only these fields (comma-separated). Mutually exclusive with 'exclude'.

example: fields=type,structure
exclude list

Return all fields except these (comma-separated).

example: exclude=omitField
pretty boolean

Pretty-print the JSON response.

default: false
example: pretty=true
unwrap boolean

Drop the envelope: return the raw array/object without data/meta wrapper.

default: false
example: unwrap=true
Response schema Fields returned in each record 4
type string

The requested top-level type: item, list or dictionary.

example: item

structure object

The structure that was actually serialized, after normalization: decimals rounded to three fractional digits, byte sequences re-encoded as padded base64 and omitted 'params' filled in. RFC 9651 defines no JSON mapping; this shape is ours.

example: {"type":"integer","value":5,"params":{"foo":{"type":"token","value":"bar"}}}

serialized string

Canonical ASCII field value produced by RFC 9651 Section 4.1.

example: 5;foo=bar

omitField boolean

True when the structure is an empty list or dictionary, which RFC 9651 Section 4.1 says must be sent by omitting the field entirely rather than as an empty value.

example: false

Documented examples

Build-generated requests and complete responses
4
Serialize an item with a parameter
GET /api/structured-fields/serialize?type=item&json=%7B%22type%22%3A%22integer%22%2C%22value%22%3A5%2C%22params%22%3A%7B%22foo%22%3A%7B%22type%22%3A%22token%22%2C%22value%22%3A%22bar%22%7D%7D%7D
{
  "data": {
    "type": "item",
    "structure": {
      "type": "integer",
      "value": 5,
      "params": {
        "foo": {
          "type": "token",
          "value": "bar"
        }
      }
    },
    "serialized": "5;foo=bar",
    "omitField": false
  },
  "meta": {
    "endpoint": "structured-fields",
    "route": "/serialize",
    "params": {
      "json": "{\"type\":\"integer\",\"value\":5,\"params\":{\"foo\":{\"type\":\"token\",\"value\":\"bar\"}}}",
      "type": "item"
    },
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
Round a decimal half-to-even
GET /api/structured-fields/serialize?type=item&json=%7B%22type%22%3A%22decimal%22%2C%22value%22%3A0.0025%7D
{
  "data": {
    "type": "item",
    "structure": {
      "type": "decimal",
      "value": 0.002,
      "params": {}
    },
    "serialized": "0.002",
    "omitField": false
  },
  "meta": {
    "endpoint": "structured-fields",
    "route": "/serialize",
    "params": {
      "json": "{\"type\":\"decimal\",\"value\":0.0025}",
      "type": "item"
    },
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
Serialize a Priority dictionary
GET /api/structured-fields/serialize?type=dictionary&json=%7B%22type%22%3A%22dictionary%22%2C%22value%22%3A%7B%22u%22%3A%7B%22type%22%3A%22integer%22%2C%22value%22%3A1%7D%2C%22i%22%3A%7B%22type%22%3A%22boolean%22%2C%22value%22%3Atrue%7D%7D%7D
{
  "data": {
    "type": "dictionary",
    "structure": {
      "type": "dictionary",
      "value": {
        "u": {
          "type": "integer",
          "value": 1,
          "params": {}
        },
        "i": {
          "type": "boolean",
          "value": true,
          "params": {}
        }
      }
    },
    "serialized": "u=1, i",
    "omitField": false
  },
  "meta": {
    "endpoint": "structured-fields",
    "route": "/serialize",
    "params": {
      "json": "{\"type\":\"dictionary\",\"value\":{\"u\":{\"type\":\"integer\",\"value\":1},\"i\":{\"type\":\"boolean\",\"value\":true}}}",
      "type": "dictionary"
    },
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}
An empty list omits the field
GET /api/structured-fields/serialize?type=list&json=%7B%22type%22%3A%22list%22%2C%22value%22%3A%5B%5D%7D
{
  "data": {
    "type": "list",
    "structure": {
      "type": "list",
      "value": []
    },
    "serialized": "",
    "omitField": true
  },
  "meta": {
    "endpoint": "structured-fields",
    "route": "/serialize",
    "params": {
      "json": "{\"type\":\"list\",\"value\":[]}",
      "type": "list"
    },
    "generatedAt": "2026-07-29T08:13:22.000Z"
  }
}

About this API

Coverage & behavior

A complete RFC 9651 (Structured Field Values for HTTP) parser and serializer. /parse turns a raw field value into typed JSON; /serialize turns typed JSON back into canonical field text. Both are pure computations — no clock, no network, and the only table either route reads is the bundled IANA field-name registry that ?field= resolves against.

Every Section 3 type is implemented: Integer, Decimal, String, Token, Byte Sequence, Boolean, Date and Display String, plus Inner Lists and Parameters at both levels. The specification's bounds are enforced exactly as written: integers are at most fifteen digits, decimals at most twelve integer digits and three fractional digits (rounded half-to-even on serialization, so 0.0015 becomes 0.002 and 0.0025 also becomes 0.002), strings are printable ASCII with backslash escapes, byte sequences are colon-delimited base64, and display strings are %"…" with percent-encoded UTF-8.

?field= reads the IANA registry. Pass a registered field name — ?field=Priority — and the top-level type is taken from the "Structured Type" column of the pinned IANA HTTP Field Name Registry that also powers /api/http-fields, then echoed back in the response and in meta.params. 35 of the 257 registered field names currently carry a Structured Type. A field with an empty column returns 400 rather than a guess, and an unregistered name returns 404.

strict defaults to true, which additionally requires the input to already be in canonical form. Non-canonical but legal input — leading zeros, 1 , 42, a; b=1, unpadded base64 — is rejected with the canonical form in the error message. Set strict=false for plain RFC 9651 parsing, which accepts all of it.

Honest limits

  • The JSON shape is ours, not the RFC's. RFC 9651 defines an abstract data model and a wire format, not a JSON encoding. {"type":"token","value":"bar"} is this API's invention; do not cite it as standard. The wire format on either side of it is the standard.
  • Syntax only. Knowing that Priority is a Dictionary tells you nothing about what u and i mean. Nothing here validates a field's semantics, allowed keys, value ranges or cardinality, and for the one field IANA labels Token the value is parsed as an item without enforcing that the bare item is a token.
  • RFC 9651 obsoletes RFC 8941 and adds the Date and Display String types. Fields defined against RFC 8941 may be handled by peers that reject @1659578233 and %"…", so responses containing those types carry a warning.
  • 4096-character inputs. Both value and json travel in a query string, so they are capped at 4096 characters. RFC 9651 asks parsers to support larger values still (16384-octet byte sequences, 1024-member lists); the parser itself has no limit, but this HTTP transport does.

Use it for

  • Inspect the exact types inside a Priority, Cache-Status or Signature-Input header while debugging
  • Check whether a field value your service emits is already in RFC 9651 canonical form
  • Build structured-field fixtures, including the Date and Display String types RFC 9651 added

Frequently asked questions

How do I parse a Priority header?

Call /api/structured-fields/parse?field=Priority&value=u%3D1,%20i. The IANA registry records Priority as a Dictionary, so the type is resolved for you and echoed back as registryType.

Is the JSON output defined by RFC 9651?

No. RFC 9651 specifies the wire format and an abstract data model, not a JSON encoding. The {type, value, params} shape is this API's own mapping — the field text it parses and produces is the standard part.

What is the difference between RFC 8941 and RFC 9651?

RFC 9651 obsoletes RFC 8941 and adds two types: Date (@1659578233) and Display String (%"caf%c3%a9"). This endpoint implements RFC 9651 and warns whenever a value uses either of them.

Why was my header rejected as non-canonical?

strict defaults to true, so 1 , 42, 042 or a; b=1 return 400 with the canonical form in the message. Add strict=false to parse them the way RFC 9651 Section 4.2 does.

Does the API check what a field's values mean?

No — it checks syntax only. It will happily parse Priority: u=99 because u=99 is a valid Dictionary member; whether 99 is a legal urgency is the field specification's business, not this parser's.

Standards & references