Error contract

Errors are JSON with a stable machine-readable error code and, where useful, a human-readable detail:

{
  "error": "replay_detected",
  "detail": "nonce already used"
}
StatuserrorWhen
400missing_idempotency_keyMoney endpoint called without Idempotency-Key.
401missing_signatureNo X-PP-Signature header.
401invalid_signatureSignature does not verify — tampered body/path or wrong key.
401auth_failedToken issuance: unknown consumer key or bad proof.
401signature_errorMalformed signature material.
403Bearer invalid/expired, or calling IP not whitelisted.
409replay_detectedNonce reused, or timestamp stale/future.
422maker_checker_violationPayout approver is the same user as the submitter.
422(validation)Field validation — standard Laravel shape with per-field errors.
429Rate limit exceeded (e.g. token endpoint, checkout STK).

Treat any 5xx as retryable with the same Idempotency-Key; treat 4xx as a bug in the request that retrying unchanged will not fix.