DynamoDB JSON Converter
Convert DynamoDB marshalled JSON to plain JSON and back — S, N, B, M, L and set types handled with number precision preserved, on this device.
Paste what a DynamoDB API call returned — a bare marshalled item, a get-item {"Item": …} or a query {"Items": […]} — and read it as plain JSON, or switch direction to build a PutItem-ready item. Nothing you paste leaves this tab.
Runs synchronously in this tab and never talks to AWS — no request, no credentials, no SDK. Share links embed the pasted JSON and options. · Press ? for shortcuts
Do it offline:$ aws dynamodb get-item --table-name users --key '{"id":{"S":"42"}}'
How to use it
- Pick a direction: Unmarshall turns DynamoDB's typed JSON into plain JSON; Marshall goes the other way.
- Paste up to 5 MB. Unmarshall accepts a bare marshalled item, a get-item response ({"Item": …}) or a query/scan response ({"Items": […]}) — the badge under the output names the detected shape; bookkeeping like Count is ignored.
- Choose how N values land: exact digit strings when a double would round them (the default), always strings, or always numbers.
- For Marshall, decide whether arrays stay lists (the default) or arrays of unique strings become string sets — then copy or download the result.
Paste the typed JSON that DynamoDB APIs speak — {"S": …}, {"N": …} and the rest — and read it back as plain JSON, or flip the direction and build a PutItem-ready item from ordinary JSON. Big N values keep every digit: by default they come back as exact digit strings once a double would round them. Everything runs in this tab, and nothing ever talks to AWS.
Examples
{"Item":{"id":{"S":"42"},"name":{"S":"Ada Lovelace"},"total":{"N":"19.99"},"active":{"BOOL":true}}}{
"id": "42",
"name": "Ada Lovelace",
"total": 19.99,
"active": true
}Unmarshall a get-item response — the Item envelope is detected and unwrapped, S and BOOL shed their tags, and 19.99 survives a double exactly, so it lands as a plain number.
{"id":"43","email":"ada@example.com","cart":["book","pen"],"coupon":null}{
"id": {
"S": "43"
},
"email": {
"S": "ada@example.com"
},
"cart": {
"L": [
{
"S": "book"
},
{
"S": "pen"
}
]
},
"coupon": {
"NULL": true
}
}Marshall plain JSON into the shape PutItem's --item flag wants: the array stays a list by default, and null becomes {"NULL": true}. Flip the Arrays option and cart would become an SS string set instead.
{"invoice":{"S":"INV-7"},"serial":{"N":"1234567890123456789012345"}}{
"invoice": "INV-7",
"serial": "1234567890123456789012345"
}The precision case — 25 digits cannot survive a double, so the default mode quotes the exact digit string and says so in a counted note. The Numbers option flips this to a bare number token or to strings for every N.
{"Items":[{"sku":{"S":"A1"},"qty":{"N":"2"}},{"sku":{"S":"B7"},"qty":{"N":"1"}}],"Count":2,"ScannedCount":2}[
{
"sku": "A1",
"qty": 2
},
{
"sku": "B7",
"qty": 1
}
]A whole query response — Items unwraps to a plain JSON array, one element per item, while Count and ScannedCount are recognized as bookkeeping and dropped. The badge reads Items envelope, 2 items.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
Why big numbers come back as quoted strings
DynamoDB's N type is an exact decimal with up to 38 significant digits (cited below), but a JavaScript double keeps only about 15 to 17 — past 2^53, integers silently round. The default mode therefore emits N as a plain number only when the digits survive a double round trip, and as an exact digit string otherwise, with a counted W_NUMBER_PRECISION_PRESERVED note. Even 39-digit values convert here — though DynamoDB itself would refuse them server-side.
Empty values: strings yes, sets no
Since AWS relaxed the rule in 2020, an empty string is legal in a non-key S attribute, and this page accepts {"S": ""} without comment. Sets are different: SS, NS and BS must be non-empty and their members unique, so an empty or duplicated set refuses with E1_EMPTY_SET or E1_SET_DUPLICATE — matching what the service itself enforces.
Binary attributes stay base64
B and BS values are base64 text on the wire; Unmarshall passes them through unchanged, with a note counting the values and their decoded byte size — the bytes are never expanded into the output. Marshall cannot express binary, so a former B value re-marshals as a plain S string — the type is lost on that round trip. A hex or byte viewer is deliberately out of scope for this page.
Sets versus lists on the way in
Plain JSON has arrays, DynamoDB has both lists and sets — so marshalling has to choose. The default keeps every array a list (L), which always round-trips. Switching Arrays to detect string sets promotes only non-empty arrays of unique strings to SS; numbers never become NS silently, and an array with duplicates or mixed types stays a list.
Common errors
Unknown type tag "STR" at "id" — DynamoDB type tags are S, N, B, BOOL, NULL, M, L, SS, NS and BS.- Hand-written items often guess a tag that does not exist. Every attribute value must wear exactly one tag from the real set — here the fix is {"S": "42"}, since STR is not a DynamoDB type.
Empty SS set at "tags" — DynamoDB rejects empty sets; remove the attribute or use an empty list (L) instead.- An empty set is invalid on the service side, so the converter refuses it instead of writing something a PutItem call would bounce. Delete the attribute entirely, or model emptiness with {"L": []}, which DynamoDB does allow.
Multiple type tags ("N", "S") in one AttributeValue at "total" — exactly one is allowed.- An AttributeValue is a one-key object: the key is the type, the value is the payload. Two tags usually means a merge went wrong upstream — keep whichever type the table really stores and drop the other.
FAQ
Does this tool call AWS or need credentials?
No. It never talks to AWS — no request, no credentials, no SDK; the conversion is a synchronous walk over the text you pasted, inside this tab. The aws-cli line above is what you would run in your own terminal to fetch an item; this page only converts what it already returned. Share links do embed the pasted JSON with your options, and the page says so before you copy one.
Why did my number turn into a quoted string?
Because it would not have survived otherwise. DynamoDB's N holds up to 38 significant digits; a JavaScript double rounds past 2^53. By default the converter emits N as a plain number only when the digits round-trip exactly, and as an exact digit string when they would be damaged — the counted note names how many. Prefer uniform output? Set Numbers to always strings or always numbers.
Which input shapes does Unmarshall accept?
Three: a bare marshalled item, a get-item response ({"Item": …}) and a query or scan response ({"Items": […]}) — detected in that order, so an item with an attribute literally named Item is never re-interpreted. Sibling response keys such as ConsumedCapacity, Count and ScannedCount are ignored. A bare top-level array is not accepted; wrap it as {"Items": […]} and it converts.