AIAG-726
## Summary
- **401 Unauthorized** - keeps existing "Invalid or expired API key"
message
- **403 Forbidden** - now reads the response body and surfaces the
server's specific permission message (e.g., which scope is missing),
instead of showing the same auth error as 401
- **429 Too Many Requests** - new handler extracts the `Retry-After`
header and tells the user how long to wait
- **Refactored** `checked_text` into early-return + match - body and
detail parsed once, no duplicated logic
Previously both 401 and 403 were reported as "Invalid or expired API
key", masking permission issues as authentication failures.
## Tests
Added 7 integration tests in `tests/api_client/main.rs` covering every
`checked_text` branch:
- 401 unauthorized
- 403 with server message / without server message
- 429 with Retry-After header / without header
- 500 with JSON message / with raw body
---------
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>