Error Handling

The CannMenus API uses standard HTTP status codes and returns detailed error messages to help you diagnose issues quickly.


HTTP Status Codes

CodeMeaningDescription
200SuccessRequest completed successfully
400Bad RequestMissing or invalid parameters
401UnauthorizedMissing or invalid API token
403ForbiddenToken doesn't have access to this resource
404Not FoundEndpoint or resource doesn't exist
429Too Many RequestsRate limit exceeded
500Server ErrorSomething went wrong on our end
503Service UnavailableAPI 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"
}
FieldDescription
typeError category (see types below)
messageHuman-readable description of the problem
documentation_urlLink 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-After header 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

IssueCheck
401 UnauthorizedIs X-Token header present and spelled correctly?
400 Bad RequestAre required parameters (states) included?
Empty resultsAre filter values valid? Check Categories, Tags
429 Rate LimitedAdd delays between requests
500 Server ErrorRetry after a few seconds; contact support if persistent

Getting Help

If you're stuck, contact support with:

  1. The full error response (type, message)
  2. The request URL and parameters (without your API token)
  3. When the issue started
  4. Steps you've already tried