Token exchange fails for form-urlencoded requests with a valid authorization code ("Invalid API key: should be in the format keystring:shared_secret"), identical JSON request succeeds #1678
Replies: 2 comments
|
We tested this against Form-urlencoded (RFC 6749 §4.1.3 compliant): JSON body: In both cases Your RFC 6749 §4.1.3 read is correct: form-urlencoded is the required encoding and JSON is not in the spec for token requests. We also searched across our logs and are not seeing any broader elevation in 403s on the token endpoint, which further suggests this isn't a universal server regression. The fact that both formats succeeded in our verification but form-urlencoded fails for yours points to something app-specific. |
|
Thanks for testing it on your side. Since you suspect this is app-specific, the original report includes a request trace uuid from a real failing form-encoded exchange: If you need anything else from our side to look into the app's state, let us know. The JSON workaround is holding up in the meantime, but we'd rather be back on the standard flow. |
Uh oh!
There was an error while loading. Please reload this page.
Since at least July 31, 2026,
POST https://api.etsy.com/v3/public/oauth/tokenreturns HTTP 403 with:{"error":"Invalid API key: should be in the format 'keystring:shared_secret'."}for a spec-compliant authorization_code + PKCE token exchange sent as
Content-Type: application/x-www-form-urlencoded, when the request carries a valid, freshly issued authorization code. The identical request sent asContent-Type: application/jsonsucceeds and returns tokens.RFC 6749 §4.1.3 requires token requests to be form-urlencoded, so this breaks standards-compliant OAuth client libraries (hit this in n8n, whose generic OAuth2 client cannot switch to JSON bodies, and most OAuth2 SDKs are in the same position).
Reproduction (personal app, PKCE, single valid code each attempt):
https://www.etsy.com/oauth/connectnormally (consent succeeds, code is issued to the registered redirect URI).Fails (403, error above):
Succeeds (200, tokens issued), same fields:
Additional matrix (all form-urlencoded unless noted):
invalid_grant / code is invalid(key check passes with a fake code, so the failure only appears with real codes, which makes this hard to debug)Invalid API key: should be in the format 'keystring:shared_secret'x-api-key: keystring:secretheader, real codeinvalid_client / client_id is invalidclient_id=keystring:secret(compound)invalid_client / client_id is invalidInvalid access token: not a Bearer token or token format is incorrectSample failing request trace:
x-etsy-request-uuid: Euwds5TllZ3QOzHHmZTnSwprtQa7(2026-07-31 01:45:29 UTC, served by cache-bos-kbos510041-BOS).This looks related to the February 2026 shared-secret enforcement: the form-urlencoded path appears to route token requests through the OpenAPI key validation (which now demands the compound x-api-key format) instead of the OAuth token handler, while the JSON path routes correctly.
Could you confirm whether form-urlencoded token requests are still supported, and restore RFC-compliant handling? Happy to provide more traces.
All reactions