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
404Not FoundInvalid API token, or endpoint/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 a detail field:

{
  "detail": "Missing required parameter: states"
}
FieldDescription
detailHuman-readable description of the problem

Common Errors

Missing Required Parameter

{
  "detail": "Missing required parameter: states"
}

Fix: Check that all required parameters are included and properly formatted.

Invalid API Token

Status code: 404

{
  "detail": "Not Found"
}

Fix: Verify your token in the X-Token header. Generate a new token from the dashboard if needed.

Rate Limit Exceeded

Status code: 429

{
  "detail": "Rate limit exceeded. Please slow down your requests."
}

Fix: Add delays between requests or implement exponential backoff. See Rate Limiting.

Server Error

Status code: 500

{
  "detail": "An internal server error occurred."
}

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['detail']}")
    elif response.status_code == 404:
        raise PermissionError(f"Not found or invalid token: {error['detail']}")
    elif response.status_code == 429:
        raise RuntimeError(f"Rate limited: {error['detail']}")
    else:
        raise Exception(f"API error ({response.status_code}): {error['detail']}")

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(`API error (${response.status}): ${data.detail}`);
  }

  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
404 Not FoundIs X-Token header present and spelled correctly? Is the token valid?
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
  2. The request URL and parameters (without your API token)
  3. When the issue started
  4. Steps you've already tried