When debugging production issues, the most common move is to copy an API response and format it. That response often carries access tokens, user emails, phone numbers and even order amounts. Pasting it into an unknown online formatter hands all of that to a stranger's server. This article describes a workflow for formatting, redacting, diffing and validating in the browser, and shows how to verify for yourself that nothing is uploaded.
First, understand where the risk really is
Online tools generally work in one of two ways. Some send your input to a server and return the formatted result. Others process it with JavaScript in the browser. The risk of the first kind is obvious: your data lands in someone else's access logs, error logs or even a database, and you do not know how long it is kept or who can read it. The second kind does not send content out, but it still has several leak surfaces that are easy to overlook.
| Leak surface | What happens | Mitigation |
|---|---|---|
| Server-side tools | Your input appears in the request body and logs of someone else's server | Do not use them for sensitive data, or use a local CLI such as jq |
| Browser extensions | Extensions with permission to read all site data can see page content | Use a private window without extensions, or redact first |
| Clipboard history | OS or third-party clipboard managers keep the tokens you copied | Clear clipboard history afterwards |
| Screen sharing and recording | Tokens displayed on screen in a meeting | Redact before sharing |
| Third-party scripts on the page | Analytics and ad scripts are unrelated to your data but sit inside the page trust boundary | Confirm in the Network panel that your input is not sent; still redact first |
A repeatable local workflow
- Before copying a sample, confirm its source and take only the smallest fragment that serves the task, not the whole response.
- Paste it into the JSON Formatter. After about 300 ms it auto-formats and the right side shows a collapsible tree.
- Use the JSONPath page to find every sensitive field, for example $..token and $..password.
- Delete unneeded nodes in the tree view, or replace values with placeholders in the input box.
- Compare before and after in the JSON Diff page and confirm only expected fields changed.
- After copying or downloading the result, clear the input and close the tab.
Worked example: redacting an API response
Here is a typical login response sample (fictional content):
{
"code": 0,
"data": {
"user": {
"id": 88231,
"name": "Li Wei",
"email": "liwei@example.com",
"phone": "13800138000"
},
"auth": {
"accessToken": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI4ODIzMSJ9.abc123",
"refreshToken": "r_9f2b7c1d",
"expiresIn": 3600
},
"orders": [
{ "id": "A-1001", "amount": 607.5, "card": "4111111111111111" }
]
}
}Step 1: find every sensitive field with JSONPath
Human eyes miss deeply nested fields. Query in the JSONPath page and you get every match:
$..accessToken → ["eyJhbGciOiJIUzI1NiJ9..."]
$..refreshToken → ["r_9f2b7c1d"]
$..email → ["liwei@example.com"]
$..card → ["4111111111111111"]The $.. prefix means recursive descent and matches a field of that name at any depth. Treat the results as a checklist where every field gets a decision: delete, replace with a placeholder, or keep.
Step 2: delete or replace
Every node in the tree view can be deleted, which suits removing the whole auth object. When you need to keep the field structure and only hide values, for instance to let a colleague reproduce a parsing problem, replace values with placeholders in the input box:
{
"code": 0,
"data": {
"user": {
"id": 0,
"name": "REDACTED",
"email": "user@example.test",
"phone": "00000000000"
},
"orders": [
{ "id": "A-0000", "amount": 607.5, "card": "REDACTED" }
]
}
}amount was kept because the problem may involve monetary precision, and the whole auth object was removed because this investigation has nothing to do with authentication. What to keep should be driven by the debugging goal, not by mechanically wiping everything.
Step 3: diff to confirm
Put the original on the left and the redacted result on the right in the JSON Diff page. You should see only changed and removed entries and no unexpected added ones. Arrays are compared by index, so if you removed an array element, later elements show as changed, which is normal. The value of this step is proving you did not accidentally break a structural field.
Verify "no upload" yourself with the Network panel
Do not rely on claims on a web page. The check is simple:
- Open the browser developer tools, switch to the Network panel and click the clear button.
- Paste a distinctive marker into the page, such as {"probe":"UNIQUE-STRING-123"}, and click Format.
- Watch for new requests. Use the search box to look for your marker string in all request bodies and URLs.
- Normally no request should carry your content. If one does, inspect its target domain and payload.
A stricter version: load the page, then go offline, then keep working. If formatting still works, processing is truly local. One reminder: the page itself may still load analytics or ad scripts, which produce requests that have nothing to do with your JSON. The test is whether your content appears in any request.
One more Network panel trick: enable "Preserve log", then repeat the same test on the other tool pages you use. That compares several tools in one go instead of verifying only one. Every page that invites you to paste sensitive content deserves this one-minute check, which is far more reliable than reading a privacy statement.
Easily overlooked details
- Never put data in shared links: do not put JSON into URL parameters, since URLs end up in browser history, proxies and logs.
- Screenshots leak too: expanded nodes in the tree view are your data. Collapse them or redact before taking a screenshot.
- Deleting a node only changes the result on the page, not the original input, unless you paste the output back. Make sure what you finally share is the redacted version, not what is still in the original input box.
- Treat tokens as sensitive even if they look expired: refresh tokens often outlive access tokens, so a leftover refreshToken is far more dangerous than an accessToken.
- Redact both keys and values: some systems put usernames in keys, such as {"user_liwei": {...}}.
Four redaction methods and how to choose
Redaction is not only deletion. Each method preserves a different amount of information and suits different cases. The wrong choice either strips the sample of its reproduction value or leaves a leak.
| Method | How | Advantage | Risk and limits |
|---|---|---|---|
| Delete | Remove the whole field or object | Most thorough, nothing left behind | Structure changes, so problems tied to that field may not reproduce |
| Fixed placeholder | Replace values with a constant such as REDACTED | Keeps field structure, easy to see what changed | Type and length information is lost, so length-validation logic cannot be reproduced |
| Same-type fake value | Use fictional data in the same format, such as user@example.test | Keeps type and format, good for reproducing parse problems | Make sure the fake value does not point at a real object, for instance do not use a real domain |
| One-way hash | Replace with a hash so equal inputs give equal outputs | Preserves the fact that two places hold the same value | Small value spaces such as phone numbers or short IDs can be brute-forced, so it is unsuitable for strict privacy needs |
A practical rule: first ask whether the field is relevant to the problem. Delete irrelevant fields. For relevant but sensitive ones, use same-type fake values. Consider hashing only when the relationship between equal values is itself the crux of the problem.
Putting the sample in a ticket: a format you can reuse
After redaction, what you give colleagues or a ticket system should also follow a consistent format, otherwise people keep asking follow-up questions. Include at least the following:
- Source: the endpoint path, the environment (test or production) and when it was captured, without tokens or full request headers.
- Expected versus actual: what you expected and what you got. A JSON Diff result states it most clearly.
- Redaction note: which fields were deleted and which replaced with placeholders, so nobody assumes the data really looks like that.
- Minimal sample: keep only the fields and array elements needed to reproduce the problem, not the full response.
A minimal sample has another benefit: it is small, needs no scrolling once formatted, and reviewers can take it in at a glance.
Limits: when not to rely on this alone
- Local browser processing solves "not sent to a third-party server". It does not replace your company's data compliance requirements. If the data is bound by regulation or contract, follow internal procedure and use company-approved internal tools where needed.
- Very large files (tens of MB and up) slow the browser down. Use jq or another command-line tool locally.
- Redacting thousands of files in bulk: a web page is manual. Write a script whose redaction rules can be tested.
- Manual replacement cannot guarantee completeness. For high-compliance cases use an allowlist approach and keep only fields confirmed safe, rather than hunting for every sensitive field to delete.