Error Handling
The CannMenus API uses standard HTTP status codes and returns detailed error messages to help you diagnose issues quickly.
HTTP Status Codes
| Code | Meaning | Description |
|---|---|---|
200 | Success | Request completed successfully |
400 | Bad Request | Missing or invalid parameters |
401 | Unauthorized | Missing or invalid API token |
403 | Forbidden | Token doesn't have access to this resource |
404 | Not Found | Endpoint or resource doesn't exist |
429 | Too Many Requests | Rate limit exceeded |
500 | Server Error | Something went wrong on our end |
503 | Service Unavailable | API temporarily unavailable |
Error Response Format
All errors return a JSON object with details:
{
"type": "invalid_request",
"message": "Missing required parameter: states",
"documentation_url": "https://cannmenus.com/docs/errors/invalid_request"
}
| Field | Description |
|---|---|
type | Error category (see types below) |
message | Human-readable description of the problem |
documentation_url | Link to relevant documentation |
Error Types
invalid_request
The request was malformed or missing required parameters.
{
"type": "invalid_request",
"message": "Missing required parameter: states"
}
Fix: Check that all required parameters are included and properly formatted.
authentication_error
API token is missing, invalid, or expired.
{
"type": "authentication_error",
"message": "Invalid API token provided"
}
Fix: Verify your token in the X-Token header. Generate a new token from the dashboard if needed.
authorization_error
Token is valid but doesn't have access to the requested resource.
{
"type": "authorization_error",
"message": "Your plan does not include access to this endpoint"
}
Fix: Check your subscription tier or contact support.
rate_limit_exceeded
Too many requests in a short time period.
{
"type": "rate_limit_exceeded",
"message": "Rate limit exceeded. Please slow down your requests."
}
Fix: Add delays between requests or implement exponential backoff. See Rate Limiting.
not_found
Requested resource or endpoint doesn't exist.
{
"type": "not_found",
"message": "Retailer with ID 99999 not found"
}
Fix: Verify the resource ID or endpoint URL.
api_error
Unexpected error on our servers.
{
"type": "api_error",
"message": "An unexpected error occurred. Please try again."
}
Fix: Wait a moment and retry. If persistent, contact support.
Rate Limiting
To ensure fair usage, the API limits request frequency. When you exceed the limit:
- Status code:
429 Too Many Requests - Response includes
Retry-Afterheader with seconds to wait
Best Practices
Add delays between requests:
import time
for page in range(1, total_pages + 1):
response = requests.get(...)
# Process response
time.sleep(0.1) # 100ms delay
Implement exponential backoff:
import time
def make_request_with_retry(url, headers, max_retries=3):
for attempt in range(max_retries):
response = requests.get(url, headers=headers)
if response.status_code == 429:
wait_time = 2 ** attempt # 1s, 2s, 4s
print(f"Rate limited. Waiting {wait_time}s...")
time.sleep(wait_time)
continue
return response
raise Exception("Max retries exceeded")
Handling Errors in Code
Python
import requests
def get_products(params):
response = requests.get(
"https://api.cannmenus.com/v1/products",
headers={"X-Token": "YOUR_API_TOKEN"},
params=params
)
if response.status_code == 200:
return response.json()
error = response.json()
if response.status_code == 400:
raise ValueError(f"Bad request: {error['message']}")
elif response.status_code == 401:
raise PermissionError(f"Authentication failed: {error['message']}")
elif response.status_code == 429:
raise RuntimeError(f"Rate limited: {error['message']}")
else:
raise Exception(f"API error ({response.status_code}): {error['message']}")
JavaScript
async function getProducts(params) {
const queryString = new URLSearchParams(params).toString();
const response = await fetch(
`https://api.cannmenus.com/v1/products?${queryString}`,
{ headers: { "X-Token": "YOUR_API_TOKEN" } }
);
const data = await response.json();
if (!response.ok) {
throw new Error(`${data.type}: ${data.message}`);
}
return data;
}
// Usage
try {
const products = await getProducts({ states: "California", page: 1 });
console.log(products);
} catch (error) {
console.error("API Error:", error.message);
}
Troubleshooting Checklist
| Issue | Check |
|---|---|
| 401 Unauthorized | Is X-Token header present and spelled correctly? |
| 400 Bad Request | Are required parameters (states) included? |
| Empty results | Are filter values valid? Check Categories, Tags |
| 429 Rate Limited | Add delays between requests |
| 500 Server Error | Retry after a few seconds; contact support if persistent |
Getting Help
If you're stuck, contact support with:
- The full error response (type, message)
- The request URL and parameters (without your API token)
- When the issue started
- Steps you've already tried
