How to normalize json key casing for an sdk or api migration
- Step 1Read the new version's casing convention — Check the SDK/API changelog for the new naming convention. If the migration is purely a casing standardization (e.g. v1 mixed camelCase, v2 is all snake_case), that target style is all you need here.
- Step 2Export a representative sample — Pull a JSON sample that contains every field variant in production. Drop the file onto the dropzone — free tier handles up to 2 MB, enough for a thorough sample.
- Step 3Select the new convention's case — Click the v2 case style in the Target case style row. Every key in the sample, at every level, is rewritten to that style.
- Step 4Keep Deep rename on — Leave Deep rename checked so nested historical bodies migrate fully. Uncheck only for nested blobs that must remain in the old shape for compatibility.
- Step 5Validate the migrated sample — Click Rename Keys and diff the output against the v2 schema. Note any field whose WORDS differ (not just case) — those need a separate scripted rename.
- Step 6Script the production migration — Use the verified casing transform as the spec for your migration script (a Mongo
$rename, an SQL column rename, or a pipeline map). This tool proves the casing logic; your script applies it at scale.
What a casing migration covers
Casing standardizations this tool performs vs. true renames it cannot. Plan the second column as scripted work.
| v1 key | v2 convention | Casing-only? | Tool handles it |
|---|---|---|---|
accessToken | access_token | Yes | Select snake_case |
userName | user_name | Yes | Select snake_case |
createdAt | created_at | Yes | Select snake_case |
created | created_at | No (word added) | Script it |
token | bearer_token | No (word changed) | Script it |
Tier limits for migration samples
How big a sample you can run per tier. The cap is on file bytes.
| Tier | Max JSON file | Batch files |
|---|---|---|
| Free | 2 MB | 1 |
| Pro | 100 MB | 10 |
| Pro + Media | 500 MB | 50 |
| Developer | 5 GB | unlimited |
Cookbook
Before/after pairs from version-migration work. Tokens and PII anonymised. Each shows a casing migration — and one that's actually a word rename.
v1 camelCase to v2 snake_case
ExampleThe new SDK standardizes on snake_case. Normalize a stored v1 record.
Input (v1):
{ "accessToken": "a", "userName": "sue", "createdAt": "2026-01-01" }
Target: snake_case
Output (v2 shape):
{ "access_token": "a", "user_name": "sue", "created_at": "2026-01-01" }Rollback: re-cast v2 back to v1 camelCase
ExampleFor a backward-compat adapter or rollback, run the same sample with the old style.
Input (v2):
{ "access_token": "a", "user_name": "sue" }
Target: camelCase
Output (v1 shape):
{ "accessToken": "a", "userName": "sue" }Nested historical body migrated
ExampleDeep rename reaches into nested v1 structures.
Input (v1):
{ "sessionInfo": { "refreshToken": "r", "expiresIn": 3600 } }
Target: snake_case
Output:
{ "session_info": { "refresh_token": "r", "expires_in": 3600 } }Word rename masquerading as a migration
ExampleIf v2 renamed the word, not just the case, the tool can't do it.
v1:
{ "created": "2026-01-01" }
v2 wants: created_at
Target snake_case output:
{ "created": "2026-01-01" } (already lowercase)
created -> created_at adds a word; script that rename separately.Acronym in a migrated token field
ExampleAuth migrations carry acronym keys; here's the normalization.
Input (v1):
{ "oAuthToken": "x", "apiKeyID": "k1" }
Target: snake_case
Output:
{ "o_auth_token": "x", "api_key_id": "k1" }Errors and edge cases
Real errors and silent failures sourced from each platform's own documentation. Match the wording to the row, fix what the row says to fix.
Migration adds or changes a word
Out of scopecreated → created_at or token → bearer_token are not casing changes — no case style produces them. Script those renames separately (Mongo $rename, SQL ALTER TABLE ... RENAME COLUMN); this tool only normalizes case.
Some records already on the new convention
IdempotentA record already in the target case is returned unchanged and not counted as renamed. Running the casing normalization over a mixed dataset is safe — already-migrated records stay put.
Casing collision during migration
Silent overwriteIf v1 stored both userId and user_id, migrating to snake_case collapses them to user_id and one value is lost silently. Find such records before the bulk migration and reconcile them.
Acronym casing not preserved on rollback
By designRound-tripping v1 acronyms is lossy: accessTokenID → access_token_id → accessTokenId. The trailing ID capitalization is gone. If v1 depended on exact acronym casing, the rollback won't be byte-identical.
Nested compatibility blob
Use Deep OFFA nested object kept in the old shape for a legacy consumer should not be deep-renamed. Uncheck Deep rename so only the top-level migrates.
Array of records
SupportedA JSON array of historical records is normalized element by element — convenient for migrating an exported batch.
Tokens and secrets in the sample
PreservedValues like access tokens are never touched — only keys change — and nothing is uploaded, so secrets stay local. Still scrub real secrets from shared samples as a matter of hygiene.
Sample over 2 MB on free
Blocked on freeA large sample exceeds the 2 MB free JSON limit and is blocked with an upgrade prompt. Trim the sample or upgrade to Pro (100 MB).
Malformed export
Parse errorA truncated or NDJSON export fails JSON.parse. Convert NDJSON to a JSON array first, then run the casing migration.
Frequently asked questions
Can I map old field names to entirely new names?
Only when the difference is casing. accessToken → access_token works; token → bearer_token does not, because the words changed. Script true renames separately and use this tool for the casing standardization.
Is the casing migration reversible?
At the casing level, mostly — re-run with the old style to produce the old shape. But acronyms are lossy on round-trip (accessTokenID does not come back exactly), so don't rely on byte-identical reversal.
Will it touch nested historical bodies?
Yes, with Deep rename on (default). Uncheck it for nested blobs you intend to keep in the legacy shape.
Is it safe to run over records that are already migrated?
Yes. Keys already in the target case are returned unchanged and not counted as renamed, so the operation is idempotent on the casing dimension.
How do I apply this to millions of MongoDB documents?
Use the casing transform here to confirm the exact old→new key names, then script db.collection.updateMany({}, { $rename: { oldKey: newKey, ... } }). Test on a _id-filtered subset first.
What about records that use a mix of old and new field names?
Normalizing to the new case unifies them. But watch for collisions: if both userId and user_id exist in one document, one will be dropped. Filter and reconcile those before the bulk run.
Does it change values, like rewriting a token format?
No — only keys. Token and secret values pass through unchanged.
Can I paste a sample instead of uploading?
The tool reads a dropped file. Save the sample as a .json file and drop it on the dropzone.
Which case styles are available?
camelCase, snake_case, PascalCase, kebab-case, and UPPER_SNAKE — pick whichever the new SDK version standardizes on.
How big a sample can I test?
Up to 2 MB on free, 100 MB on Pro, more on higher tiers — enough to cover every field variant in most APIs.
Is migration data uploaded?
No. All renaming runs in your browser; tokens, keys, and user records never reach JAD Apps servers.
Where do I see how many keys changed?
After running, the tool reports the renamed key count, which is a quick sanity check that the casing migration actually did something on your sample.
Privacy first
Conversion runs locally in your browser. No file is uploaded — only metadata counters are saved for signed-in dashboard stats.