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
403ForbiddenMissing or invalid API token
404Not FoundInvalid API token, or endpoint/resource doesn't exist
422Unprocessable EntityValidation error — missing or invalid parameters
429Too Many RequestsRate limit exceeded (reserved for future use)
500Server ErrorSomething went wrong on our end

Error Response Format

All errors return a JSON object with a detail field. For most errors, detail is a string. For validation errors (422), detail is an array of objects:

{
  "detail": "Invalid or expired token"
}
FieldDescription
detailHuman-readable description of the problem (string), or an array of validation error objects for 422 responses

Common Errors

Missing or Invalid Parameters

Status code: 422

{
  "detail": [
    {
      "loc": ["query", "states"],
      "msg": "field required",
      "type": "value_error.missing"
    }
  ]
}

Fix: Check that all required parameters are included and properly formatted. FastAPI returns validation errors as an array of objects with loc, msg, and type fields.

Invalid API Token

Status code: 404

{
  "detail": "Invalid or expired token"
}

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

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/v2/products",
        headers={"X-Token": "YOUR_API_TOKEN"},
        params=params
    )

    if response.status_code == 200:
        return response.json()

    error = response.json()

    if response.status_code == 422:
        raise ValueError(f"Validation error: {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/v2/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
403 ForbiddenIs X-Token header present? Is the token missing entirely?
404 Not FoundIs the token valid and not expired? Is the endpoint URL correct?
422 Unprocessable EntityAre required parameters (states) included and valid?
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