Documentation Index Fetch the complete documentation index at: https://docs.satsuma.ai/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The Satsuma API uses standard HTTP status codes and detailed error responses to help you diagnose and handle issues. This guide covers common error scenarios and best practices for robust error handling.
HTTP Status Codes
Success Codes (2xx)
200 OK - Request succeeded
201 Created - Resource created successfully
202 Accepted - Request accepted for processing
204 No Content - Request succeeded with no response body
Client Error Codes (4xx)
400 Bad Request - Invalid request syntax or parameters
401 Unauthorized - Invalid or missing API key
403 Forbidden - Insufficient permissions
404 Not Found - Resource does not exist
409 Conflict - Request conflicts with current state
422 Unprocessable Entity - Validation errors
429 Too Many Requests - Rate limit exceeded
Server Error Codes (5xx)
500 Internal Server Error - Unexpected server error
502 Bad Gateway - Upstream service error
503 Service Unavailable - Temporary service outage
504 Gateway Timeout - Request timeout
All errors return a consistent JSON structure:
{
"error" : {
"code" : "VALIDATION_ERROR" ,
"message" : "One or more fields failed validation" ,
"details" : [
{
"field" : "email" ,
"message" : "Invalid email format"
},
{
"field" : "quantity" ,
"message" : "Must be greater than 0"
}
],
"request_id" : "req_abc123xyz789"
}
}
Common Error Codes
Authentication Errors
Status : 401
Cause : API key is malformed, expired, or doesn’t exist
Solution : Verify your API key and ensure it’s not truncated{
"error" : {
"code" : "INVALID_API_KEY" ,
"message" : "The provided API key is invalid or expired"
}
}
Status : 403
Cause : API key lacks required permissions for the endpoint
Solution : Use a key with appropriate permissions{
"error" : {
"code" : "INSUFFICIENT_PERMISSIONS" ,
"message" : "Your API key does not have permission to access this resource" ,
"required_permission" : "orders"
}
}
Validation Errors
Status : 422
Cause : Request data fails validation rules
Solution : Fix the invalid fields listed in the details array{
"error" : {
"code" : "VALIDATION_ERROR" ,
"message" : "Request validation failed" ,
"details" : [
{
"field" : "latitude" ,
"message" : "Must be between -90 and 90"
}
]
}
}
Status : 400
Cause : Required request parameter is missing
Solution : Include all required fields in your request{
"error" : {
"code" : "MISSING_REQUIRED_FIELD" ,
"message" : "Required field is missing" ,
"field" : "merchant_id"
}
}
Resource Errors
Status : 404
Cause : Requested resource doesn’t exist or has been deleted
Solution : Verify the resource ID and ensure it exists{
"error" : {
"code" : "RESOURCE_NOT_FOUND" ,
"message" : "Product not found" ,
"resource_type" : "product" ,
"resource_id" : "prod_nonexistent123"
}
}
Status : 409
Cause : Request conflicts with current resource state
Solution : Check resource state and retry with correct data{
"error" : {
"code" : "RESOURCE_CONFLICT" ,
"message" : "Cannot modify order that has already been fulfilled" ,
"resource_state" : "completed"
}
}
Business Logic Errors
Status : 422
Cause : Requested quantity exceeds available inventory
Solution : Reduce quantity or choose different product{
"error" : {
"code" : "INSUFFICIENT_INVENTORY" ,
"message" : "Not enough inventory available" ,
"available_quantity" : 3 ,
"requested_quantity" : 5 ,
"product_id" : "prod_123"
}
}
Status : 422
Cause : Payment processing failed
Solution : Use valid payment method or contact payment provider{
"error" : {
"code" : "PAYMENT_FAILED" ,
"message" : "Payment could not be processed" ,
"payment_error" : "card_declined" ,
"decline_reason" : "insufficient_funds"
}
}
Rate Limiting
Status : 429
Cause : Too many requests in time window
Solution : Implement backoff and retry after specified time{
"error" : {
"code" : "RATE_LIMIT_EXCEEDED" ,
"message" : "Rate limit exceeded" ,
"retry_after" : 60 ,
"limit" : 100 ,
"reset" : "2024-01-15T11:00:00Z"
}
}
Implementing Error Handling
Basic Error Handling
curl -X GET 'https://api.satsuma.ai/product?latitude=37.7749&longitude=-122.4194' \
-H 'Authorization: your-api-key' \
-H 'Content-Type: application/json' \
-w "Response Code: %{http_code}\n" \
-s | jq '.'
# Example error response for invalid API key:
# {
# "error": {
# "code": "INVALID_API_KEY",
# "message": "The provided API key is invalid or expired",
# "request_id": "req_abc123xyz789"
# }
# }
Retry Logic with Backoff
Implement exponential backoff for transient errors:
# Retry with exponential backoff using a simple script
#!/bin/bash
url = "https://api.satsuma.ai/product?latitude=37.7749&longitude=-122.4194"
api_key = "your-api-key"
max_retries = 3
for attempt in $( seq 0 $max_retries ); do
response = $( curl -s -w "%{http_code}" \
-H "Authorization: $api_key " \
-H "Content-Type: application/json" \
" $url " )
http_code = "${ response : -3 }"
body = "${ response % ???}"
# Success
if [[ " $http_code " =~ ^2[0-9][0-9]$ ]]; then
echo " $body " | jq '.'
exit 0
fi
# Don't retry 4xx errors (except 429)
if [[ " $http_code " =~ ^4[0-9][0-9]$ ]] && [ " $http_code " != "429" ]; then
echo "Client error $http_code : $body " >&2
exit 1
fi
# Calculate delay for retry
if [ " $attempt " -lt " $max_retries " ]; then
delay = $(( 2**attempt ))
echo "Retrying in ${ delay }s (attempt $(( attempt + 1 ))/$(( max_retries + 1 )))" >&2
sleep $delay
fi
done
echo "Max retries exceeded: $body " >&2
exit 1
Error-Specific Handling
Handle different error types appropriately:
# Error handling in bash script
handle_error () {
local error_code = " $1 "
local error_body = " $2 "
case " $error_code " in
"INVALID_API_KEY" )
echo "ERROR: Invalid API key. Please check your credentials." >&2
# Log security incident
logger "Security: Invalid API key used"
exit 1
;;
"INSUFFICIENT_INVENTORY" )
available = $( echo " $error_body " | jq -r '.error.available_quantity // "unknown"' )
echo "ERROR: Insufficient inventory. Available: $available " >&2
exit 1
;;
"PAYMENT_FAILED" )
reason = $( echo " $error_body " | jq -r '.error.decline_reason // "unknown"' )
echo "ERROR: Payment failed. Reason: $reason " >&2
exit 1
;;
"RATE_LIMIT_EXCEEDED" )
retry_after = $( echo " $error_body " | jq -r '.error.retry_after // 60' )
echo "Rate limit exceeded. Retry after ${ retry_after }s" >&2
return $retry_after
;;
*)
echo "ERROR: Unexpected API error: $error_code " >&2
exit 1
;;
esac
}
Circuit Breaker Pattern
Prevent cascade failures with a circuit breaker:
# Simple circuit breaker state management in bash
#!/bin/bash
CIRCUIT_STATE_FILE = "/tmp/satsuma_circuit_state"
FAILURE_THRESHOLD = 5
TIMEOUT_DURATION = 60
get_circuit_state () {
if [ -f " $CIRCUIT_STATE_FILE " ]; then
cat " $CIRCUIT_STATE_FILE "
else
echo "CLOSED:0:0"
fi
}
update_circuit_state () {
local state = " $1 "
local failures = " $2 "
local next_attempt = " $3 "
echo " $state : $failures : $next_attempt " > " $CIRCUIT_STATE_FILE "
}
execute_with_circuit_breaker () {
local url = " $1 "
local api_key = " $2 "
IFS = ':' read -r state failures next_attempt <<< "$( get_circuit_state )"
current_time = $( date +%s )
# Check if circuit is open and timeout hasn't expired
if [ " $state " = "OPEN" ] && [ " $current_time " -lt " $next_attempt " ]; then
echo "Circuit breaker is OPEN. Retry after: $(( next_attempt - current_time))s" >&2
return 1
fi
# Make the request
response = $( curl -s -w "%{http_code}" \
-H "Authorization: $api_key " \
" $url " )
http_code = "${ response : -3 }"
if [[ " $http_code " =~ ^2[0-9][0-9]$ ]]; then
# Success - reset circuit breaker
update_circuit_state "CLOSED" "0" "0"
echo "${ response % ???}" # Return response body
return 0
else
# Failure - increment counter
failures = $(( failures + 1 ))
if [ " $failures " -ge " $FAILURE_THRESHOLD " ]; then
# Open circuit
next_attempt = $(( current_time + TIMEOUT_DURATION ))
update_circuit_state "OPEN" " $failures " " $next_attempt "
echo "Circuit breaker opened due to failures" >&2
else
update_circuit_state "CLOSED" " $failures " "0"
fi
return 1
fi
}
Monitoring & Alerting
Error Tracking
Track errors for monitoring and debugging:
# Error tracking in bash with logging
track_error () {
local error_code = " $1 "
local error_message = " $2 "
local status_code = " $3 "
local request_id = " $4 "
local endpoint = " $5 "
local user_id = " ${6 :- unknown } "
local retry_attempt = " ${7 :- 0} "
# Create error data JSON
local error_data = $( jq -n \
--arg timestamp "$( date -Iseconds )" \
--arg error_code " $error_code " \
--arg error_message " $error_message " \
--arg status_code " $status_code " \
--arg request_id " $request_id " \
--arg user_id " $user_id " \
--arg endpoint " $endpoint " \
--arg retry_attempt " $retry_attempt " \
'{
timestamp: $timestamp,
error_code: $error_code,
error_message: $error_message,
status_code: ($status_code | tonumber),
request_id: $request_id,
user_id: $user_id,
endpoint: $endpoint,
retry_attempt: ($retry_attempt | tonumber)
}' )
# Log to file
echo " $error_data " >> /var/log/satsuma_errors.log
# Send to monitoring service (replace with your monitoring endpoint)
curl -s -X POST "https://monitoring.yourservice.com/api/errors" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $MONITORING_TOKEN " \
-d " $error_data " > /dev/null
# Alert on critical errors
if [ " $status_code " -ge 500 ] || [ " $error_code " = "PAYMENT_FAILED" ]; then
# Send alert (replace with your alerting service)
curl -s -X POST "https://alerts.yourservice.com/api/critical" \
-H "Content-Type: application/json" \
-d " $error_data " > /dev/null
fi
}
Health Checks
Implement health checks to monitor API status:
#!/bin/bash
# Health check script
API_KEY = "your-api-key"
HEALTH_ENDPOINT = "https://api.satsuma.ai/product?latitude=37.7749&longitude=-122.4194"
METRICS_ENDPOINT = "https://metrics.yourservice.com/api/gauge"
health_check () {
local timestamp = $( date +%s )
# Make health check request with timeout
response = $( timeout 5 curl -s -w "%{http_code}" \
-H "Authorization: $API_KEY " \
" $HEALTH_ENDPOINT " )
local exit_code = $?
local http_code = "${ response : -3 }"
if [ $exit_code -eq 0 ] && [[ " $http_code " =~ ^2[0-9][0-9]$ ]]; then
# Healthy
local health_data = $( jq -n \
--arg status "healthy" \
--arg timestamp " $timestamp " \
'{ status: $status, timestamp: ($timestamp | tonumber) }' )
echo " $health_data "
# Send metrics (1 = healthy)
curl -s -X POST " $METRICS_ENDPOINT " \
-H "Content-Type: application/json" \
-d '{"metric": "api_health", "value": 1, "timestamp": ' $timestamp '}' \
> /dev/null
return 0
else
# Unhealthy
local error_msg = "HTTP $http_code or timeout"
local health_data = $( jq -n \
--arg status "unhealthy" \
--arg error " $error_msg " \
--arg timestamp " $timestamp " \
'{ status: $status, error: $error, timestamp: ($timestamp | tonumber) }' )
echo " $health_data "
# Send metrics (0 = unhealthy)
curl -s -X POST " $METRICS_ENDPOINT " \
-H "Content-Type: application/json" \
-d '{"metric": "api_health", "value": 0, "timestamp": ' $timestamp '}' \
> /dev/null
return 1
fi
}
# Run health check
health_check
# For continuous monitoring, add to cron:
# */1 * * * * /path/to/health_check.sh
Best Practices
Error Handling Strategy
Fail Fast : Return errors immediately for invalid requests
Graceful Degradation : Provide fallback functionality when possible
User-Friendly Messages : Show helpful error messages to end users
Detailed Logging : Log full error context for debugging
Retry Guidelines
Retry transient errors : Network issues, 5xx errors, rate limits
Don’t retry permanent failures : 4xx errors (except 429)
Use exponential backoff : With jitter to prevent thundering herd
Respect rate limits : Use server-provided retry-after values
Security Considerations
Never log sensitive data : API keys, payment info, personal data
Validate all inputs : Even when retrying failed requests
Monitor for anomalies : Unusual error patterns may indicate attacks
Rotate compromised keys : Immediately if invalid key errors occur
Troubleshooting Common Issues
Getting 401 errors with valid API key
Ensure API key is not truncated in environment variables
Check that you’re using the correct header name (Authentication)
Verify you’re hitting the correct environment (staging vs production)
Try regenerating your API key if the issue persists
Intermittent timeout errors
Implement retry logic with exponential backoff
Check your network connectivity and DNS resolution
Consider increasing request timeout limits
Monitor our status page for incidents
High error rates during peak traffic
Review your rate limiting and implement proper backoff
Consider request batching to reduce API calls
Implement caching for frequently accessed data
Contact support for rate limit increases if needed
Getting Help
When reporting errors, include:
Request ID from the error response
Full error message and code
Request payload (without sensitive data)
Timestamp and retry attempts
Your API key prefix (first 8 characters)
Contact support@satsuma.ai for assistance with persistent errors or unexpected behavior.