JavaScript SDK

The official JavaScript SDK for HempData API. Works with Node.js (16+) and modern browsers.

Package: @hempdataapi/sdk

Installation

npm install @hempdataapi/sdk
yarn add @hempdataapi/sdk
pnpm add @hempdataapi/sdk

Quick Start

const { HempDataClient } = require('@hempdataapi/sdk');

const client = new HempDataClient({
  apiKey: process.env.HEMPDATA_API_KEY,
});

// Check if Delta-9 edibles are legal in Colorado
const regulations = await client.regulations.list({
  state: 'CO',
  substance: 'delta-9-thc',
  productType: 'edibles',
});

console.log(regulations.data[0].legal_status);
// "legal_with_restrictions"

TypeScript

The SDK is written in TypeScript and exports all types:

import { HempDataClient, Regulation, State, Webhook } from '@hempdataapi/sdk';

const client = new HempDataClient({
  apiKey: process.env.HEMPDATA_API_KEY!,
});

const result = await client.regulations.list({ state: 'CO' });
const regulation: Regulation = result.data[0];

Configuration

const client = new HempDataClient({
  apiKey: 'YOUR_API_KEY',       // Required
  baseUrl: 'https://api.hempdataapi.com', // Optional, defaults to production
  timeout: 30000,                // Request timeout in ms (default: 30000)
  retries: 3,                    // Retry failed requests (default: 3)
  retryDelay: 1000,              // Delay between retries in ms (default: 1000)
});

Regulations

List Regulations

const result = await client.regulations.list({
  state: 'CO',                    // optional
  substance: 'delta-9-thc',      // optional
  productType: 'edibles',        // optional
  legalStatus: 'legal_with_restrictions', // optional
  minConfidence: 0.8,            // optional
  verifiedAfter: '2026-01-01',   // optional
  includeChangelog: true,         // optional
  includeSources: true,           // optional
  includeBills: true,             // optional
  page: 1,                        // optional
  perPage: 25,                    // optional
});

console.log(result.data);   // Regulation[]
console.log(result.meta);   // { page, per_page, total, total_pages }

Get Single Regulation

const regulation = await client.regulations.get('reg_a1b2c3d4-5678-9012-abcd-ef3456789012');
console.log(regulation.data.summary);

Get Changelog

const changes = await client.regulations.changelog({
  state: 'TX',
  since: '2026-01-01T00:00:00Z',
  perPage: 50,
});

for (const change of changes.data) {
  console.log(`${change.state} — ${change.plain_english_summary}`);
}

Compare States

const comparison = await client.regulations.compare({
  states: ['CO', 'CA', 'TX', 'FL', 'NY'],
  substance: 'delta-9-thc',
  productType: 'edibles',
});

console.log(comparison.data.summary);
for (const state of comparison.data.comparison) {
  console.log(`${state.state}: ${state.legal_status}`);
}

States

List All States

const states = await client.states.list({
  sort: 'avg_confidence',
  order: 'desc',
});

for (const state of states.data) {
  console.log(`${state.name}: ${state.total_regulations} regulations, avg confidence ${state.avg_confidence}`);
}

Get State Profile

const colorado = await client.states.get('CO', {
  includeSources: true,
  includeBills: true,
});

console.log(colorado.data.key_highlights);
console.log(colorado.data.hr5371_impact_assessment);

Substances and Product Types

// List all tracked substances
const substances = await client.substances.list();
for (const sub of substances.data) {
  console.log(`${sub.name}: ${sub.federal_status} (${sub.total_state_regulations} state regulations)`);
}

// List all product types
const productTypes = await client.productTypes.list();
for (const pt of productTypes.data) {
  console.log(`${pt.name}: regulated in ${pt.states_with_regulations} states`);
}

Webhooks

Create Webhook

const webhook = await client.webhooks.create({
  endpointUrl: 'https://yourapp.com/webhooks/hempdata',
  filters: {
    states: ['CO', 'CA', 'TX'],
    substances: ['delta-9-thc'],
    eventTypes: ['legal_status_changed'],
  },
  description: 'Monitor THC regulation changes',
});

// IMPORTANT: Save the signing secret — it is only returned once
console.log('Signing secret:', webhook.data.signing_secret);

List Webhooks

const webhooks = await client.webhooks.list();
for (const wh of webhooks.data) {
  console.log(`${wh.id}: ${wh.status} — ${wh.total_deliveries} deliveries`);
}

Delete Webhook

await client.webhooks.delete('whk_a1b2c3d4e5f6');

Verify Webhook Signature

const { verifyWebhookSignature } = require('@hempdataapi/sdk');

// In your Express handler
app.post('/webhooks/hempdata', express.raw({ type: 'application/json' }), (req, res) => {
  const isValid = verifyWebhookSignature(
    req.body,
    req.headers['x-hempdata-signature'],
    process.env.HEMPDATA_WEBHOOK_SECRET
  );

  if (!isValid) return res.status(401).send('Invalid signature');

  const event = JSON.parse(req.body);
  // Process event...
  res.status(200).send('OK');
});

Widget Check

const result = await client.widget.check({
  substance: 'delta-9-thc',
  productType: 'edibles',
  state: 'CO',
});

console.log(result.data.badge_color);  // "yellow"
console.log(result.data.headline);     // "Legal with Restrictions"
console.log(result.data.restrictions); // ["Must be 21 or older...", ...]

Billing

// Create checkout session
const checkout = await client.billing.createCheckout({
  tier: 'professional',
  billingPeriod: 'annual',
  email: 'user@company.com',
  successUrl: 'https://yourapp.com/success?session_id={CHECKOUT_SESSION_ID}',
  cancelUrl: 'https://yourapp.com/cancel',
});
// Redirect user to checkout.data.checkout_url

// Create portal session
const portal = await client.billing.createPortal({
  returnUrl: 'https://yourapp.com/dashboard',
});
// Redirect user to portal.data.portal_url

CSV Export

// Get CSV as a string
const csv = await client.regulations.list({
  state: 'CO',
  format: 'csv',
  includeSources: true,
});

// Write to file
const fs = require('fs');
fs.writeFileSync('colorado-regulations.csv', csv);

Error Handling

const { HempDataError, RateLimitError, AuthenticationError } = require('@hempdataapi/sdk');

try {
  const result = await client.regulations.list({ state: 'XX' });
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.error('Invalid API key');
  } else if (error instanceof RateLimitError) {
    console.error(`Rate limited. Retry after ${error.retryAfter} seconds`);
  } else if (error instanceof HempDataError) {
    console.error(`API error: ${error.code} — ${error.message}`);
    console.error('Field:', error.field);
  } else {
    throw error;
  }
}

Pagination Helper

// Iterate through all pages automatically
for await (const regulation of client.regulations.paginate({ substance: 'delta-9-thc' })) {
  console.log(`${regulation.state}: ${regulation.legal_status}`);
}

Browser Usage

The SDK works in browsers via bundlers (webpack, Vite, esbuild). Use your public API key (pk_) for client-side code:

import { HempDataClient } from '@hempdataapi/sdk';

const client = new HempDataClient({
  apiKey: 'pk_live_your_public_key',
});

// Only widget.check is available with public keys
const result = await client.widget.check({
  substance: 'delta-9-thc',
  productType: 'edibles',
  state: 'CO',
});