commerce-kit
commerce-kit
TypeScript SDK for the Your Next Store API.
Installation
bun add commerce-kit
# or
npm install commerce-kitQuick Start
import { Commerce } from 'commerce-kit';
const commerce = Commerce();That's it! The SDK reads YNS_API_KEY from environment and auto-detects the correct store and API base URL: https://yns.store
Products
// List products
const { data, meta } = await commerce.productBrowse({
limit: 10,
offset: 0,
category: 'shoes',
query: 'running',
active: true,
orderBy: 'createdAt',
orderDirection: 'desc',
});
// Get single product by ID or slug
const product = await commerce.productGet({ idOrSlug: 'running-shoes' });Cart
// Create or update cart
const cart = await commerce.cartUpsert({
cartId: 'cart_123', // optional, creates new if omitted
variantId: 'variant_456',
quantity: 2,
});
// Get cart
const cart = await commerce.cartGet({ cartId: 'cart_123' });
// Remove item from cart
await commerce.cartRemoveItem({
cartId: 'cart_123',
variantId: 'variant_456',
});Orders
// List orders
const { data, meta } = await commerce.orderBrowse({
limit: 10,
offset: 0,
});
// Get single order
const order = await commerce.orderGet({ id: 'order_789' });
// Orders with event-ticket lines carry a buyer access code: order.ticketCode (string | null)Events
An event is a product flagged as an event (with a date, location, and capacity) plus a single non-shippable ticket variant. Requires the store's Events tool to be enabled.
// List events (with live ticketsSold counts)
const { data, total } = await commerce.eventBrowse({ limit: 10, offset: 0 });
// Get one event by id or slug
const { event } = await commerce.eventGet({ idOrSlug: 'summer-fest' });
// Create an event (ticket price is a decimal string)
const { event } = await commerce.eventCreate({
name: 'Summer Fest',
price: '29.99',
startsAt: '2026-07-01T18:00:00Z',
location: 'Berlin',
capacity: 500,
});
// Update event metadata (partial; send null to clear a field).
// Does not change the ticket price/variants — use the products API for those.
await commerce.eventUpdate({ idOrSlug: 'summer-fest' }, { capacity: 600, status: 'published' });
// Attendee rollup (buyers and ticket quantities, from paid orders)
const { attendees, totalTickets } = await commerce.eventAttendeesBrowse({ idOrSlug: 'summer-fest' });Tickets
No-login access to purchased event tickets. The buyer gets a 6-character access code on the
order (order.ticketCode, also in the confirmation email) and manages all attendee details
with it plus the purchase email. Each seat carries its own shareable token — a view-only
link for the attendee; attendee details can only be edited by the buyer.
// Buyer lookup: access code + purchase email.
// Returns null on any mismatch (the API answers a uniform 404).
const bundle = await commerce.ticketsGet({ code: 'K7M3PA', email: 'buyer@example.com' });
// bundle.lines[].event — startsAt, location, guestLabel, guest
// bundle.lines[].seats[] — { token, name, email } per ticket
// Buyer bulk-edit of attendee names/emails.
// Throws on mismatch (404) or when the order is cancelled/refunded (409).
const updated = await commerce.ticketsUpdate(
{ code: 'K7M3PA' },
{
email: 'buyer@example.com',
seats: [{ token: bundle.lines[0].seats[0].token, name: 'Ada Lovelace', email: null }],
},
);
// View-only attendee ticket by seat token (null for unknown tokens)
const ticket = await commerce.ticketAttendeeGet({ token: 'a1b2c3...' });Collections & Categories
Full CRUD for product collections, product categories, and blog categories. Mutations are
partial (send only the fields you want to change; pass null to clear an optional field).
// Collections — create, partially update, delete
const collection = await commerce.collectionCreate({ name: 'Summer', filter: { type: 'manual' }, active: true });
await commerce.collectionUpdate({ idOrSlug: 'summer' }, { name: 'Summer 2026', active: false });
await commerce.collectionDelete({ idOrSlug: 'summer' }); // { ok: true, deleted: 1 }
// Group related collections under a free-form key and fetch them together
await commerce.collectionUpdate({ idOrSlug: 'floral' }, { group: 'fragrances' });
const fragrances = await commerce.collectionBrowse({ group: 'fragrances' });
await commerce.collectionUpdate({ idOrSlug: 'floral' }, { group: null }); // clear
// Categories — delete (create/update already supported)
await commerce.categoryUpdate({ idOrSlug: 'shoes' }, { name: 'Footwear' });
await commerce.categoryDelete({ idOrSlug: 'footwear' }); // 409 if still referenced by products
// Blog categories — full CRUD
const blogCategory = await commerce.blogCategoryCreate({ name: 'Guides' });
await commerce.blogCategoryUpdate({ idOrSlug: 'guides' }, { description: null });
await commerce.blogCategoryDelete({ idOrSlug: 'guides' });Raw API Requests
For endpoints not yet implemented in the SDK, use the request() method:
// GET request
const webhooks = await commerce.request<Webhook[]>('/webhooks');
// POST with body
const webhook = await commerce.request<Webhook, CreateWebhookBody>('/webhooks', {
method: 'POST',
body: { url: 'https://example.com/hook', events: ['order.created'] },
});
// GET with query parameters
const results = await commerce.request<SearchResult>('/search', {
query: { q: 'shoes', limit: 5 },
});
// Path parameters via template literals
const variant = await commerce.request<Variant>(`/products/${productId}/variants/${variantId}`);TypeScript
All API types are exported:
import type {
APIProductsBrowseResult,
APIProductGetByIdResult,
APICartCreateBody,
APIOrderGetByIdResult,
CommerceConfig,
} from 'commerce-kit';License
AGPL-3.0-only