API Debugging Playbook: From Capture to Contract Validation

A repeatable incident pipeline—parse URLs, format responses, json-diff, JWT checks, and schema validation, all browser-local.

· Все гиды

When APIs break, start with evidence—not guesses

Production API incidents rarely fail with a helpful single-line error. You get a 502 from the gateway, a 200 with {"success":false}, a truncated JSON body, or a JWT that "worked in Postman" but fails in the mobile app. The fastest teams treat debugging as a reproducible pipeline: capture the request, normalize the response, diff against known-good, validate contracts, then narrow to auth, routing, or payload semantics.

This playbook walks through that pipeline using Towalles browser-local tools. Nothing here uploads your captures to Towalles servers—still redact tokens and customer fields before pasting. For deeper JSON technique see json-formatting-guide; for URL query edge cases see url-api-debugging-guide.

Phase 1: Capture and parse the request

Reproduce minimally — One failing endpoint, one identity, one payload variant. Note method, path, query, headers (redact Authorization), and body.

Parse the URL — Paste the full URL into url-parser. Confirm scheme, host, path segments, and decoded query keys. Double-encoding (%252F) and plus-vs-space in query strings cause silent mismatches between client SDKs.

Encode sanity — If parameters look garbled, run suspect values through url-encoder and base64-encoder-decoder to see layering mistakes (Base64 inside URL encoding inside JSON).

Document findings in the incident doc: "Query filter decoded to empty string because client sent filter= with no value."

Phase 2: Normalize the response body

Format first — Minified error JSON hides the real failure three levels deep in error.details[0].message. Paste into json-formatter. If parse fails, you may have HTML error page, SSE chunk, or truncated gzip—check Content-Type and body length in Network tab.

Extract from LLM wrappers — AI gateways often return Markdown fences. Use llm-json-extractor before formatting when the body mixes prose and JSON.

Compare environments — Save staging and production responses (redacted). Format both, then json-diff for path-level changes. Teams frequently discover a missing data.version field or type change (numberstring) that mobile parsers reject.

Example diff insight:

// staging
{ "user": { "id": 42, "tier": "pro" } }
// production
{ "user": { "id": "42", "tier": "pro" } }

ID type coercion breaks strict TypeScript clients—formatting alone would not flag it; diff does.

Phase 3: Auth and token inspection

When errors are 401/403 or intermittent:

  1. Paste bearer token into jwt-decoder (strip Bearer prefix).
  2. Check exp, nbf, aud, iss, clock skew.
  3. Confirm custom claims (scope, roles) match route policy.
  4. Remember: decoding is not verification—pair with server logs for signature failures.

For opaque API keys, use api-key-format-checker to identify provider format (Stripe, AWS, etc.) and ensure you did not swap test/live prefixes. Rotate if a live key appeared in a ticket attachment.

Chain with hmac-generator only for local test vector reproduction—never paste production signing secrets.

Phase 4: Contract and schema validation

Syntax-valid JSON can still violate OpenAPI. After formatting:

  • Run structured-output-validator against your JSON Schema fixture.
  • Use openapi-formatter to inspect component definitions if the field should exist per spec.

CI should own schema validation; during incidents, manual validator runs prove whether the bug is "server drift" vs "client assumption."

yaml-toml-config-guide mindset applies when config drives API behavior—convert deployment YAML with yaml-converter, format, diff against last release.

Phase 5: Time, cron, and idempotency

Scheduled jobs failing? Validate cron with cron-validator and expressions from cron-scheduling-guide. Off-by-one timezone errors mimic "random" API failures when batch windows misalign.

For retry storms, check idempotency keys in headers (often UUIDs)—generate test IDs with uuid-generator / ulid-generator and document expected header names in your API catalog.

Phase 6: Communicate and close

Incident comment template

  • Request: method, path, query summary (no secrets)
  • Response: status, formatted excerpt of error path
  • Diff: what changed vs last known good
  • Auth: exp/aud/iss summary (no raw token)
  • Next owner: backend / gateway / client

Post-incident — Add a fixture to CI, link json-formatting-guide in runbook, rotate exposed credentials.

Tool chain cheat sheet

Symptom First tool Then
Garbled query url-parser url-encoder
Unreadable JSON json-formatter json-diff
401 after deploy jwt-decoder server verify logs
"Valid JSON", wrong shape structured-output-validator OpenAPI diff
Webhook body in chat llm-json-extractor json-formatter
Config regression yaml-converter json-diff

Pitfalls that waste hours

  • Debugging production with live refresh tokens in shared tabs.
  • Assuming pretty JSON meant the server sent valid JSON (proxy may have rewritten body).
  • Ignoring Content-Encoding and double-parsed strings.
  • Skipping diff—eyeballing 200-line objects for one field change.

Towalles tool pages link to focused guides; this playbook ties them into an incident-ready sequence. Bookmark it for your next SEV-2 and run the phases in order before escalating to "maybe cache" theories.

Appendix: Worked example (synthetic data)

Symptom — Mobile app login fails after API gateway deploy; Postman with same bearer token returns 200.

Phase 1url-parser on https://api.example.com/v2/users/me?fields=profile,settings confirms path /v2/users/me (gateway added /v2 strip rule).

Phase 2json-formatter on mobile error body:

{"error":{"code":"PROFILE_SHAPE","details":[{"path":"user.id","expected":"number"}]}}

Phase 3jwt-decoder: exp valid; aud matches mobile-app; not an auth issue.

Phase 4json-diff staging vs production user object → production id became string after serializer change.

Resolution — Backend hotfix coerces ID to number; add schema test with structured-output-validator; document in api-debugging-playbook runbook link.

Total time saved by ordered tools vs random log grep: usually 30–90 minutes on cross-team incidents.

Appendix: Status-code routing table

HTTP status First hypothesis Towalles first step
400 Malformed body/query json-formatter or url-parser
401 Token missing/invalid jwt-decoder
403 Scope/role mismatch jwt-decoder claims + policy doc
404 Path/version drift url-parser + deployment diff
409 Idempotency conflict uuid-generator test headers
422 Schema validation structured-output-validator
429 Rate limit less tool—check retry-after header
502/504 Gateway/upstream capture body anyway; may be JSON error envelope

Appendix: curl → Towalles handoff

curl -sS -D - https://api.example.com/health -o /tmp/body.json

Copy body from /tmp/body.json into json-formatter; paste response headers into incident doc (redact cookies). Do not pipe live tokens into shell history—use env vars cleared after command.

Keeping curl for transport and Towalles for inspection matches choosing-local-online-tools hybrid pattern.

Соответствующие инструменты