Skip to content

Commit 17e6279

Browse files
committed
fix(fetch): auto-detect JSON body Content-Type
When a body is provided via -d and no Content-Type header is explicitly set, auto-detect JSON bodies (starting with { or [) and set Content-Type: application/json. Previously, string bodies defaulted to text/plain via the Fetch spec's Request constructor, causing servers to skip JSON parsing on payment retry.
1 parent 030d41f commit 17e6279

3 files changed

Lines changed: 15 additions & 2 deletions

File tree

packages/x402-proxy/CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [0.8.2] - 2026-03-24
11+
12+
### Fixed
13+
- JSON request bodies sent without explicit `Content-Type` header now auto-detect as `application/json` instead of defaulting to `text/plain` - fixes servers rejecting JSON bodies on payment retry
14+
1015
## [0.8.1] - 2026-03-24
1116

1217
### Added
@@ -214,7 +219,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
214219
- `appendHistory` / `readHistory` / `calcSpend` - JSONL transaction history
215220
- Re-exports from `@x402/fetch`, `@x402/svm`, `@x402/evm`
216221

217-
[Unreleased]: https://github.com/cascade-protocol/x402-proxy/compare/v0.8.1...HEAD
222+
[Unreleased]: https://github.com/cascade-protocol/x402-proxy/compare/v0.8.2...HEAD
223+
[0.8.2]: https://github.com/cascade-protocol/x402-proxy/compare/v0.8.1...v0.8.2
218224
[0.8.1]: https://github.com/cascade-protocol/x402-proxy/compare/v0.8.0...v0.8.1
219225
[0.8.0]: https://github.com/cascade-protocol/x402-proxy/compare/v0.7.1...v0.8.0
220226
[0.7.1]: https://github.com/cascade-protocol/x402-proxy/compare/v0.7.0...v0.7.1

packages/x402-proxy/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "x402-proxy",
3-
"version": "0.8.1",
3+
"version": "0.8.2",
44
"description": "curl for x402 paid APIs. Auto-pays any endpoint on Base, Solana, and Tempo. Also works as an OpenClaw plugin.",
55
"type": "module",
66
"sideEffects": false,

packages/x402-proxy/src/commands/fetch.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,13 @@ Examples:
241241
}
242242

243243
const method = flags.method || "GET";
244+
// Auto-detect JSON body and set Content-Type if not explicitly provided
245+
if (flags.body && !headers.has("Content-Type")) {
246+
const trimmed = flags.body.trimStart();
247+
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
248+
headers.set("Content-Type", "application/json");
249+
}
250+
}
244251
// Convert Headers to plain object so mppx SSE spread doesn't lose them
245252
const init: RequestInit = { method, headers: Object.fromEntries(headers.entries()) };
246253
if (flags.body) init.body = flags.body;

0 commit comments

Comments
 (0)