Quick Start Guide
Go from zero to your first API call in under five minutes. Follow these seven steps to get started.
Get an API Key
Sign up for a free API key at leefii.com/api-docs/keys. You will receive a key that starts with lf_live_ followed by a 32-character string. Keep this key secure and never expose it in client-side code or public repositories.
Get your free API key →# Your API key will look like this:
lf_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
# Store it as an environment variable:
export LEEFII_API_KEY="lf_live_your_key_here"Make Your First Request
Test your API key with a simple cURL request to the strains endpoint. This returns a paginated list of cannabis strains with their THC/CBD content, effects, and flavors.
curl -X GET \
'https://leefii.com/api/v1/strains?limit=3' \
-H 'X-API-Key: lf_live_your_key_here' \
-H 'Accept: application/json'
# Response:
# {
# "success": true,
# "data": [
# { "slug": "blue-dream", "name": "Blue Dream", "type": "hybrid", "thc": 21.0 },
# { "slug": "og-kush", "name": "OG Kush", "type": "hybrid", "thc": 23.0 },
# { "slug": "girl-scout-cookies", "name": "Girl Scout Cookies", "type": "hybrid", "thc": 25.0 }
# ],
# "meta": { "total": 5632, "limit": 3, "offset": 0 }
# }Explore Strain Data
Use JavaScript to search for indica strains with specific effects. The API supports filtering by type, effect, flavor, and THC/CBD range.
// Search for relaxing indica strains with high THC
const response = await fetch(
'https://leefii.com/api/v1/strains?type=indica&effect=relaxed&thc_min=20&limit=5',
{
headers: {
'X-API-Key': process.env.LEEFII_API_KEY
}
}
);
const { data, meta } = await response.json();
data.forEach(strain => {
console.log(`${strain.name} (${strain.type}) - THC: ${strain.thc}%`);
console.log(` Effects: ${strain.effects.join(', ')}`);
console.log(` Flavors: ${strain.flavors.join(', ')}`);
});
console.log(`Showing ${data.length} of ${meta.total} results`);Search Dispensaries
Use Python to find dispensaries in a specific state and city. The dispensary endpoint supports filtering by location, type (recreational/medical), and delivery availability.
import requests
import os
API_KEY = os.environ['LEEFII_API_KEY']
BASE_URL = 'https://leefii.com/api/v1'
# Find dispensaries in Los Angeles, CA with delivery
response = requests.get(
f'{BASE_URL}/dispensaries',
params={
'state': 'CA',
'city': 'Los Angeles',
'delivery': True,
'limit': 10
},
headers={'X-API-Key': API_KEY}
)
data = response.json()
if data['success']:
for disp in data['data']:
print(f"{disp['name']}")
print(f" Address: {disp['address']}")
print(f" Rating: {disp['rating']}/5")
print(f" Delivery: {'Yes' if disp['delivery'] else 'No'}")
print()
print(f"Found {data['meta']['total']} dispensaries total")
else:
print(f"Error: {data['error']['message']}")Handle Pagination
The API uses limit/offset pagination. Use the meta.total field to determine total results and iterate through pages.
// Fetch all strains using pagination
async function fetchAllStrains(apiKey) {
const PAGE_SIZE = 100;
let allStrains = [];
let offset = 0;
let total = Infinity;
while (offset < total) {
const response = await fetch(
`https://leefii.com/api/v1/strains?limit=${PAGE_SIZE}&offset=${offset}`,
{ headers: { 'X-API-Key': apiKey } }
);
const { data, meta } = await response.json();
allStrains = allStrains.concat(data);
total = meta.total;
offset += PAGE_SIZE;
console.log(`Fetched ${allStrains.length} of ${total} strains`);
// Respect rate limits - wait between requests
await new Promise(resolve => setTimeout(resolve, 1000));
}
return allStrains;
}Error Handling
Always check the success field in responses and handle errors gracefully. The API returns descriptive error messages with documentation links.
async function safeApiCall(endpoint, params = {}) {
const url = new URL(`https://leefii.com/api/v1/${endpoint}`);
Object.entries(params).forEach(([key, val]) =>
url.searchParams.set(key, String(val))
);
try {
const response = await fetch(url.toString(), {
headers: { 'X-API-Key': process.env.LEEFII_API_KEY }
});
const data = await response.json();
if (!data.success) {
switch (data.error.code) {
case 401:
console.error('Invalid API key. Check your X-API-Key header.');
break;
case 429:
console.error('Rate limited. Wait before retrying.');
// Implement exponential backoff
break;
case 404:
console.error('Resource not found.');
break;
default:
console.error(`API Error ${data.error.code}: ${data.error.message}`);
}
return null;
}
return data;
} catch (err) {
console.error('Network error:', err.message);
return null;
}
}
// Usage:
const result = await safeApiCall('strains', { type: 'indica', limit: 10 });
if (result) {
console.log(`Found ${result.meta.total} strains`);
}Add Attribution
The free tier requires a visible "Powered by Leefii" attribution with a dofollow link on any public-facing pages that display API data. Here is the recommended HTML embed code.
<!-- Add this to any page displaying Leefii API data -->
<p style="font-size: 12px; color: #666; margin-top: 16px;">
Data provided by
<a href="https://leefii.com"
rel="dofollow"
style="color: #16a34a; text-decoration: underline;">
Leefii
</a>
— Cannabis Dispensary Directory
</p>
<!-- Or use a compact badge style -->
<a href="https://leefii.com"
rel="dofollow"
style="display: inline-flex; align-items: center; gap: 4px;
padding: 4px 8px; background: #f0fdf4; border-radius: 4px;
font-size: 11px; color: #166534; text-decoration: none;">
Powered by Leefii
</a>Official SDKs
JavaScript SDK
Coming SoonTypeScript-first SDK for Node.js and browser environments. Includes type definitions, pagination helpers, and automatic retry logic.
npm install @leefii/cannabis-api
import { Leefii } from '@leefii/cannabis-api';
const client = new Leefii('lf_live_...');
const strains = await client.strains.list({ type: 'indica' });Python SDK
Coming SoonPython SDK with async support, Pydantic models, and built-in pagination. Works with Python 3.8 and above.
pip install leefii
from leefii import LeefiiClient
client = LeefiiClient('lf_live_...')
strains = client.strains.list(type='indica')