What it does

Callcheck reads a PayPal call you paste in, predicts what the API will do with it, and then makes the call in the sandbox to show whether the prediction held.

It checks against PayPal's live OpenAPI schema and a catalogue of 44 known failures. Every one of those 44 is backed by a real sandbox probe, so the behaviour is recorded rather than assumed. Several contradict the published documentation.

Paste a curl command, a raw request, a fetch call, an SDK snippet or an MCP config.


You find out in production

Payment APIs mostly fail quietly at first. The call returns 201, your code moves on, and the problem arrives later — as a duplicate payout, a rejected invoice, or money sitting in a state nobody designed a screen for.

We know because it kept happening to us while building against PayPal: a call that looked fine, documentation that said one thing, and an API that did another.

A few examples, each one something we hit:

  • A 201 from Payouts proves nothing. An item can still land on UNCLAIMED, FAILED or RETURNED minutes later. If you treat the 201 as success, you have written a bug.
  • Invoicing v2 ignores PayPal-Request-Id on create. Idempotency comes from a deterministic invoice_number instead. Payouts honours sender_batch_id exactly as documented, so the two behave differently in a way nothing warns you about.
  • The MCP server is at /mcp, not the /http path in the docs.
  • Money values are strings. The schema says so, the live API accepts the number 10 anyway, and the generated SDK refuses it.

None of that is in a tutorial. All of it is findable only by sending the call and seeing what comes back.


So Callcheck sends it for you

Paste a call

Paste a curl command, a raw HTTP request, a fetch(), an SDK snippet or an MCP config. Callcheck reads it against PayPal's live OpenAPI schema and a catalogue of known failures, says what will happen, and then makes the call in the sandbox to show whether the prediction held.

Predicted, then observed

Send the same payout batch twice with the same sender_batch_id and Callcheck predicts 201 then SUCCESS for the first, and 400 USER_BUSINESS_ERROR for the second. Then it sends both. Predicted and observed sit side by side.

Being checkable is the point. A tool that only predicts is a tool you have to take on trust.


44 traps, each one probed

The catalogue

The catalogue holds 44 ways a PayPal integration goes wrong, and every single one is backed by a real sandbox probe. We did not read these in a blog post. We sent the call, recorded what came back, and kept the evidence.

Several contradict the published documentation. Those are flagged as such, with both sources shown.

Worked examples


Where APIMatic comes in

What the plugin generated

The APIMatic Context Plugin generated the SDK that Callcheck checks calls against — and in doing so revealed its own limit, which turned out to be useful.

SDK 2.5.0 covers 40 operations across Orders, Payments, Subscriptions, Transaction Search and Vault. It covers none for Payouts, Invoicing, Disputes, Webhooks or Catalog.

That gap is exactly where the trouble lives. An SDK teaches you the shape of the API it covers; the parts it does not cover are the parts you write by hand, from documentation, at speed.

Agent Claude Sonnet 4.5 on Amazon Bedrock, reading a call against the live schema and the trap catalogue
Source of truth PayPal's live OpenAPI schemas, fetched rather than cached
Evidence A real sandbox probe behind all 44 traps
Platform AWS Lambda, DynamoDB, S3 and CloudFront

Built With

  • bedrock
  • dynomodb
  • lambda
  • paypal
  • sonnet
Share this project:

Updates

Submission history