The CLI uses distinct exit codes for each error category. Scripts and AI agents can branch on the exit code without parsing the error message.
Exit Codes
| Code | Type | Meaning |
|---|
0 | Success | Command completed successfully |
1 | Client error | Invalid flags, validation failure, or bad request |
2 | Auth error | Missing or invalid API key |
3 | Rate limited | Too many requests (HTTP 429) |
4 | Credits exhausted | API credit limit reached (HTTP 402) |
5 | Server/network error | Server failure or connectivity issue |
Errors are written to stderr as structured JSON:
{
"error": "descriptive message explaining what went wrong",
"code": 2,
"error_type": "auth_error"
}
The error_type field provides a machine-readable classification:
| error_type | Exit Code | Common Causes |
|---|
client_error | 1 | Missing required flags, invalid flag values |
validation_error | 1 | Invalid date range, bad geo_id format (HTTP 422) |
auth_error | 2 | No API key configured, or key is invalid (HTTP 401) |
rate_limited | 3 | Too many concurrent requests (HTTP 429) |
credit_exhausted | 4 | Monthly credit limit reached (HTTP 402) |
server_error | 5 | Shovels API returned a 5xx error |
network_error | 5 | DNS failure, timeout, or connection refused |
Common Errors and Solutions
Exit 1: Client Error
Missing required flags:
$ shovels permits search --geo-id 92024
Error: required flags "permit-from", "permit-to" not set
Fix: Add the required --permit-from and --permit-to flags.
Invalid date range:
{
"error": "permit_from must be before permit_to",
"code": 1,
"error_type": "validation_error"
}
Fix: Ensure your --permit-from date is earlier than --permit-to. Use YYYY-MM-DD format.
Exit 2: Auth Error
{
"error": "API key is required. Set SHOVELS_API_KEY or run: shovels config set api-key YOUR_KEY",
"code": 2,
"error_type": "auth_error"
}
Fix: Set your API key via environment variable or config file. See CLI authentication.
Exit 3: Rate Limited
{
"error": "rate limited after 3 retries",
"code": 3,
"error_type": "rate_limited"
}
The CLI automatically retries rate-limited requests with exponential backoff and jitter (up to 3 retries). If this error appears, wait a moment and try again, or contact support if it persists.
Use --no-retry to disable automatic retry if you want to handle rate limits yourself in a script.
Exit 4: Credits Exhausted
{
"error": "credit limit reached",
"code": 4,
"error_type": "credit_exhausted"
}
Your monthly credit allowance is used up. Check your usage with shovels usage and contact sales@shovels.ai to increase your limit.
Exit 5: Server or Network Error
{
"error": "connection timeout after 30s",
"code": 5,
"error_type": "network_error"
}
Check your internet connection. If the Shovels API is down, try again later. You can adjust the timeout with --timeout 60s.
Using Exit Codes in Scripts
shovels permits search --geo-id 92024 \
--permit-from 2024-01-01 --permit-to 2024-12-31 \
> results.json 2> error.json
case $? in
0) echo "Success: $(jq '.meta.count' results.json) records" ;;
2) echo "Auth failed — check your API key" ;;
3) echo "Rate limited — retrying in 60s"; sleep 60 ;;
4) echo "Out of credits — contact sales" ;;
*) echo "Error: $(cat error.json)" ;;
esac
Related Articles