Skip to main content

JavaScript / Node.js Examples

Complete code examples for using the TakeTheme API with JavaScript and Node.js.

Setup

Using Fetch (Node.js 18+)

const API_KEY = process.env.TAKETHEME_API_KEY;
const BASE_URL = "https://api.taketheme.com/api/v1";

async function apiRequest(endpoint, options = {}) {
const response = await fetch(`${BASE_URL}${endpoint}`, {
...options,
headers: {
tt-api-key: ` ${API_KEY}`,
"Content-Type": "application/json",
...options.headers,
},
body: options.body ? JSON.stringify(options.body) : undefined,
});

if (!response.ok) {
const error = await response.json();
throw new Error(`API Error: ${error.error.message}`);
}

return response.json();
}

Products

List All Products

// Using fetch
const { data: products, pagination } = await apiRequest("/products?limit=25");

console.log(`Found ${pagination.total_count} products`);
products.forEach((product) => {
console.log(`- ${product.title} ($${product.price})`);
});

Get a Single Product

// Using fetch
const { data: product } = await apiRequest("/products/prod_abc123");
console.log(product.title, product.variants);

Create a Product

// Using fetch
const { data: newProduct } = await apiRequest("/products", {
method: "POST",
body: {
title: "Premium T-Shirt",
description: "Comfortable cotton t-shirt",
price: 29.99,
currency: "USD",
status: "active",
variants: [
{
title: "Small",
sku: "TSHIRT-S",
price: 29.99,
inventory_quantity: 100,
},
{
title: "Medium",
sku: "TSHIRT-M",
price: 29.99,
inventory_quantity: 150,
},
{ title: "Large", sku: "TSHIRT-L", price: 29.99, inventory_quantity: 75 },
],
images: [{ src: "https://example.com/tshirt.jpg", alt: "Premium T-Shirt" }],
},
});

console.log(`Created product: ${newProduct.id}`);

Update a Product

// Using fetch
const { data: updated } = await apiRequest("/products/prod_abc123", {
method: "PATCH",
body: {
price: 34.99,
status: "active",
},
});

Delete a Product

// Using fetch
await apiRequest("/products/prod_abc123", { method: "DELETE" });

Orders

List Orders

// Fetch recent orders
const { data: orders } = await apiRequest("/orders?status=pending&limit=50");

// With date filtering
const { data: recentOrders } = await apiRequest(
"/orders?created_at_min=2024-01-01T00:00:00Z"
);

Create an Order

const { data: order } = await apiRequest("/orders", {
method: "POST",
body: {
customer: {
email: "customer@example.com",
first_name: "John",
last_name: "Doe",
},
line_items: [
{
variant_id: "var_abc123",
quantity: 2,
price: 29.99,
},
],
shipping_address: {
first_name: "John",
last_name: "Doe",
address1: "123 Main Street",
city: "New York",
province: "NY",
postal_code: "10001",
country: "US",
phone: "+1-555-123-4567",
},
shipping_line: {
title: "Standard Shipping",
price: 5.99,
},
},
});

console.log(`Order created: ${order.order_number}`);

Fulfill an Order

const { data: fulfillment } = await apiRequest(
`/orders/${orderId}/fulfillments`,
{
method: "POST",
body: {
line_items: [{ id: "li_abc123", quantity: 2 }],
tracking_number: "1Z999AA10123456784",
tracking_company: "UPS",
tracking_url:
"https://www.ups.com/track?loc=en_US&tracknum=1Z999AA10123456784",
notify_customer: true,
},
}
);

Cancel an Order

const { data: cancelled } = await apiRequest(`/orders/${orderId}/cancel`, {
method: "POST",
body: {
reason: "customer_request",
restock: true,
notify_customer: true,
},
});

Customers

Search Customers

const { data: customers } = await apiRequest(
"/customers?email=john@example.com"
);

// Search by multiple criteria
const { data: vipCustomers } = await apiRequest(
"/customers?tags=vip&orders_count_min=10"
);

Create a Customer

const { data: customer } = await apiRequest("/customers", {
method: "POST",
body: {
email: "newcustomer@example.com",
first_name: "Jane",
last_name: "Smith",
phone: "+1-555-987-6543",
addresses: [
{
address1: "456 Oak Avenue",
city: "Los Angeles",
province: "CA",
postal_code: "90001",
country: "US",
default: true,
},
],
tags: ["newsletter", "loyalty-program"],
accepts_marketing: true,
},
});

Inventory

Update Stock Levels

// Set absolute quantity
await apiRequest("/inventory/var_abc123", {
method: "POST",
body: {
location_id: "loc_main",
available: 100,
},
});

// Adjust by delta
await apiRequest("/inventory/var_abc123/adjust", {
method: "POST",
body: {
location_id: "loc_main",
adjustment: -5,
reason: "Damaged stock",
},
});

Webhooks

Register a Webhook

const { data: webhook } = await apiRequest("/webhooks", {
method: "POST",
body: {
topic: "orders/created",
address: "https://your-app.com/webhooks/orders",
format: "json",
},
});

console.log(`Webhook registered: ${webhook.id}`);

Verify Webhook Signatures

import crypto from "crypto";

function verifyWebhook(payload, signature, secret) {
const hmac = crypto.createHmac("sha256", secret);
hmac.update(payload);
const digest = hmac.digest("base64");

return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(digest));
}

// Express.js middleware
app.post(
"/webhooks/orders",
express.raw({ type: "application/json" }),
(req, res) => {
const signature = req.headers["x-taketheme-signature"];

if (!verifyWebhook(req.body, signature, WEBHOOK_SECRET)) {
return res.status(401).send("Invalid signature");
}

const event = JSON.parse(req.body);
console.log("Order created:", event.data.order_number);

res.status(200).send("OK");
}
);

Pagination Helper

async function* paginate(endpoint, params = {}) {
let cursor = null;

do {
const url = new URL(`${BASE_URL}${endpoint}`);
Object.entries(params).forEach(([key, value]) => {
url.searchParams.set(key, value);
});
url.searchParams.set("limit", "100");
if (cursor) url.searchParams.set("cursor", cursor);

const response = await fetch(url, {
headers: { tt-api-key: ` ${API_KEY}` },
});
const { data, pagination } = await response.json();

for (const item of data) {
yield item;
}

cursor = pagination.next_cursor;
} while (cursor);
}

// Usage
for await (const product of paginate("/products")) {
console.log(product.title);
}

// Collect all
const allProducts = [];
for await (const product of paginate("/products")) {
allProducts.push(product);
}

Error Handling

class TakeThemeError extends Error {
constructor(error) {
super(error.message);
this.code = error.code;
this.status = error.status;
this.details = error.details;
this.requestId = error.request_id;
}
}

async function apiRequest(endpoint, options = {}) {
const response = await fetch(`${BASE_URL}${endpoint}`, {
...options,
headers: {
tt-api-key: ` ${API_KEY}`,
"Content-Type": "application/json",
...options.headers,
},
body: options.body ? JSON.stringify(options.body) : undefined,
});

const data = await response.json();

if (!response.ok) {
throw new TakeThemeError(data.error);
}

return data;
}

// Usage
try {
await apiRequest("/products", {
method: "POST",
body: { title: "" }, // Invalid: empty title
});
} catch (error) {
if (error instanceof TakeThemeError) {
if (error.code === "VALIDATION_FAILED") {
error.details.forEach((d) => console.log(`${d.field}: ${d.message}`));
} else if (error.status === 429) {
console.log("Rate limited, retry later");
} else {
console.log(`Error ${error.code}: ${error.message}`);
}
}
}

Complete Example: Sync Products

import fs from "fs/promises";

const API_KEY = process.env.TAKETHEME_API_KEY;
const BASE_URL = "https://api.taketheme.com/api/v1";

async function syncProducts() {
console.log("Starting product sync...");

// Read local product data
const localProducts = JSON.parse(
await fs.readFile("./products.json", "utf-8")
);

// Fetch existing products
const existingProducts = new Map();
for await (const product of paginate("/products")) {
existingProducts.set(product.sku, product);
}

console.log(`Found ${existingProducts.size} existing products`);

// Sync each product
for (const local of localProducts) {
const existing = existingProducts.get(local.sku);

try {
if (existing) {
// Update existing
await apiRequest(`/products/${existing.id}`, {
method: "PATCH",
body: {
title: local.title,
price: local.price,
inventory_quantity: local.stock,
},
});
console.log(`Updated: ${local.sku}`);
} else {
// Create new
await apiRequest("/products", {
method: "POST",
body: local,
});
console.log(`Created: ${local.sku}`);
}
} catch (error) {
console.error(`Failed to sync ${local.sku}:`, error.message);
}

// Rate limit safety
await new Promise((r) => setTimeout(r, 100));
}

console.log("Sync complete!");
}

syncProducts().catch(console.error);