Errors
The Ping API uses conventional HTTP status codes and a consistent error response format to indicate success or failure. Understanding these patterns will help you debug issues quickly.
Error response format
All Ping API errors follow a consistent JSON structure. Every error response includes:
result- Always"failed"for errorsmessage- Human-readable error descriptioncode- Optional machine-readable error codeerror_info- Optional additional details
This consistent format makes it easy to handle errors programmatically across all endpoints.
Error response envelope
{
"result": "failed",
"message": "Invalid phone number format. Use E.164 format (e.g., +263771234567)",
"code": "INVALID_PHONE_FORMAT",
"error_info": "Phone number must start with country code"
}
Minimal error
{
"result": "failed",
"message": "Missing required field: message"
}
Status codes
The Ping API uses standard HTTP status codes to indicate the outcome of requests.
Success codes
- Name
200 OK- Description
Request succeeded. Response body contains the requested data.
- Name
201 Created- Description
Resource successfully created (e.g., new recipient, template).
Client error codes
- Name
400 Bad Request- Description
Invalid request parameters or missing required fields.
- Name
401 Unauthorized- Description
Missing or invalid authentication credentials (API key or JWT token).
- Name
403 Forbidden- Description
Valid credentials but insufficient permissions for the requested operation.
- Name
404 Not Found- Description
The requested resource does not exist.
- Name
409 Conflict- Description
Request conflicts with existing state (e.g., duplicate resource).
- Name
429 Too Many Requests- Description
Rate limit exceeded. See rate limiting documentation.
Server error codes
- Name
500 Internal Server Error- Description
Something went wrong on Ping's end. Contact support if this persists.
Tip: Always check the HTTP status code first, then parse the error message for specific details about what went wrong.
Common errors
Authentication errors
401 Unauthorized
- Missing
X-Ping-Api-Keyheader - Invalid or expired API key
- Missing
Authorizationheader for JWT endpoints
403 Forbidden
- API key lacks required permission (e.g.,
smspermission for SMS endpoint) - User not a member of the target business
- JWT token valid but user lacks access to resource
Validation errors
400 Bad Request
- Missing required fields (
to_phone,message, etc.) - Invalid phone number format (must be E.164:
+263771234567) - Invalid email address format
- Template not found or not active
- Sender ID not approved
Rate limiting
429 Too Many Requests
- Authentication endpoints: 5 requests per minute
- Exceeded other endpoint-specific rate limits
- Response includes
Retry-Afterheader when available
Business errors
Insufficient credits
{
"result": "failed",
"message": "Insufficient credits. Required: $0.50, Available: $0.20"
}
Unverified business
{
"result": "failed",
"message": "Business verification required. Max 5 recipients for unverified businesses."
}
Example error handling
Python
import requests
response = requests.post(
'https://api.ping.co.zw/v1/notification/api/sms/send',
headers={'X-Ping-Api-Key': api_key},
json={'to_phone': phone, 'message': msg}
)
if response.status_code == 200:
data = response.json()
if data['result'] == 'success':
print('SMS sent successfully')
else:
print(f"Error: {data['message']}")
elif response.status_code == 401:
print('Invalid API key')
elif response.status_code == 429:
retry_after = response.headers.get('Retry-After')
print(f'Rate limited. Retry after {retry_after}s')
else:
print(f'HTTP {response.status_code}')
Node.js
const response = await fetch(url, options)
if (!response.ok) {
if (response.status === 401) {
throw new Error('Invalid credentials')
}
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After')
throw new Error(`Rate limited. Retry after ${retryAfter}s`)
}
}
const data = await response.json()
if (data.result === 'failed') {
throw new Error(data.message)
}
Best practices
Handle errors gracefully
- Check HTTP status code first - Don't assume 200 means success
- Parse the error message - Contains actionable details
- Implement retry logic - With exponential backoff for 429 errors
- Log error details - Include
codeanderror_infofor debugging - Display user-friendly messages - Don't show raw API errors to end users
Retry strategy
For transient errors (500, 429), implement exponential backoff:
- First retry: Wait 1 second
- Second retry: Wait 2 seconds
- Third retry: Wait 4 seconds
- Max retries: 3-5 attempts
For 429 errors, respect the Retry-After header if present.
Before contacting support:
- Check your API key is correct and has the right permissions
- Verify phone numbers are in E.164 format (+country code)
- Ensure required fields are included in the request
- Check you haven't exceeded rate limits
- Review the error message - it usually tells you exactly what's wrong
99% of reported errors are caused by incorrect request parameters.
