DEVELOPER PLATFORM

API Documentation

Everything you need to integrate with the SellStein platform

Base URL:https://api.sellstein.com
Version:v1

Getting Started

Learn how to authenticate and make your first API call.

Quickstart

1

Create Your Account

Create your account and set up your first business

2

Configure Your Store

Add products, configure payments, and customize your store

3

Launch & Sell

Launch your store and start accepting orders

bash
# Test your API key
curl -X GET "https://api.sellstein.com/business/:bizId/products" \
  -H "Authorization: Bearer sk_live_your_api_key" \
  -H "Content-Type: application/json"

Authentication

All API requests require a Bearer token sent via the Authorization header.

Bearer Token

Include your API key in the Authorization header of every request.

http
Authorization: Bearer sk_live_aBcDeFgHiJkLmNoPqRsT...

Security Warning

Never expose your API keys in client-side code. Always make API calls from your server.

API Key Types

PrefixEnvironmentDescription
sk_live_ProductionFor production use. Real transactions.
sk_test_SandboxFor development and testing. No real charges.

Products

Create, read, update, and delete products in your store.

GET/business/:bizId/products

Retrieve a paginated list of all products in your store. Supports filtering by status, category, and search query.

Parameters

ParameterTypeRequiredDescription
pageintegerOptionalPage number for pagination. Defaults to 1.
limitintegerOptionalNumber of results per page (max 100). Defaults to 25.
statusstringOptionalFilter by status: active, draft, archived.
searchstringOptionalSearch products by name or SKU.
categorystringOptionalFilter by category slug.

cURL

bash
curl -X GET "https://api.sellstein.com/business/biz_abc123/products?page=1&limit=25&status=active" \
  -H "Authorization: Bearer sk_live_your_api_key"

JavaScript

javascript
const response = await fetch(
  'https://api.sellstein.com/business/biz_abc123/products?page=1&limit=25',
  {
    headers: {
      'Authorization': 'Bearer sk_live_your_api_key',
      'Content-Type': 'application/json',
    },
  }
);
const data = await response.json();
console.log(data.products);

Response

json
{
  "products": [
    {
      "id": "prod_xK9mZq2",
      "name": "Premium License Key",
      "slug": "premium-license-key",
      "price": 29.99,
      "currency": "USD",
      "status": "active",
      "type": "digital",
      "stock": 142,
      "category": "software",
      "images": ["https://cdn.sellstein.com/img/prod_xK9mZq2/cover.webp"],
      "created_at": "2025-11-15T08:30:00Z",
      "updated_at": "2026-01-22T14:12:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 25,
    "total": 87,
    "total_pages": 4
  }
}
POST/business/:bizId/products

Create a new product in your store. Supports digital products, physical goods, subscriptions, and service listings.

Parameters

ParameterTypeRequiredDescription
namestringRequiredProduct name (max 200 characters).
pricenumberRequiredPrice in the store's default currency.
typestringRequiredProduct type: digital, physical, subscription, service.
descriptionstringOptionalProduct description (supports Markdown).
statusstringOptionalProduct status: active, draft. Defaults to draft.
stockintegerOptionalAvailable stock quantity. -1 for unlimited.
categorystringOptionalCategory slug to assign the product to.
variantsarrayOptionalArray of variant objects with name, price, and stock.

cURL

bash
curl -X POST "https://api.sellstein.com/business/biz_abc123/products" \
  -H "Authorization: Bearer sk_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Pro Toolkit License",
    "price": 49.99,
    "type": "digital",
    "description": "Lifetime access to all pro tools",
    "status": "active",
    "stock": -1
  }'

JavaScript

javascript
const response = await fetch(
  'https://api.sellstein.com/business/biz_abc123/products',
  {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer sk_live_your_api_key',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      name: 'Pro Toolkit License',
      price: 49.99,
      type: 'digital',
      description: 'Lifetime access to all pro tools',
      status: 'active',
      stock: -1,
    }),
  }
);
const product = await response.json();

Response

json
{
  "id": "prod_nW3pRt8",
  "name": "Pro Toolkit License",
  "slug": "pro-toolkit-license",
  "price": 49.99,
  "currency": "USD",
  "type": "digital",
  "status": "active",
  "stock": -1,
  "description": "Lifetime access to all pro tools",
  "created_at": "2026-03-03T10:15:00Z",
  "updated_at": "2026-03-03T10:15:00Z"
}
PUT/business/:bizId/products/:productId

Update an existing product. Only include the fields you want to change -- unspecified fields retain their current values.

Parameters

ParameterTypeRequiredDescription
namestringOptionalUpdated product name.
pricenumberOptionalUpdated price.
statusstringOptionalUpdated status: active, draft, archived.
stockintegerOptionalUpdated stock quantity.
descriptionstringOptionalUpdated description.

cURL

bash
curl -X PUT "https://api.sellstein.com/business/biz_abc123/products/prod_nW3pRt8" \
  -H "Authorization: Bearer sk_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"price": 39.99, "status": "active"}'

JavaScript

javascript
const response = await fetch(
  'https://api.sellstein.com/business/biz_abc123/products/prod_nW3pRt8',
  {
    method: 'PUT',
    headers: {
      'Authorization': 'Bearer sk_live_your_api_key',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      price: 39.99,
      status: 'active',
    }),
  }
);
const updated = await response.json();

Response

json
{
  "id": "prod_nW3pRt8",
  "name": "Pro Toolkit License",
  "slug": "pro-toolkit-license",
  "price": 39.99,
  "currency": "USD",
  "type": "digital",
  "status": "active",
  "stock": -1,
  "updated_at": "2026-03-03T11:45:00Z"
}
DELETE/business/:bizId/products/:productId

Permanently delete a product from your store. This action cannot be undone. Associated orders are preserved but the product reference is removed.

cURL

bash
curl -X DELETE "https://api.sellstein.com/business/biz_abc123/products/prod_nW3pRt8" \
  -H "Authorization: Bearer sk_live_your_api_key"

JavaScript

javascript
const response = await fetch(
  'https://api.sellstein.com/business/biz_abc123/products/prod_nW3pRt8',
  {
    method: 'DELETE',
    headers: {
      'Authorization': 'Bearer sk_live_your_api_key',
    },
  }
);
// 204 No Content on success

Response

json
{
  "success": true,
  "message": "Product deleted successfully"
}

Orders

Retrieve and manage customer orders.

GET/business/:bizId/orders

Retrieve a paginated list of orders. Supports filtering by status, date range, customer email, and payment provider.

Parameters

ParameterTypeRequiredDescription
pageintegerOptionalPage number. Defaults to 1.
limitintegerOptionalResults per page (max 100). Defaults to 25.
statusstringOptionalFilter: pending, completed, refunded, cancelled, disputed.
fromstringOptionalStart date (ISO 8601). e.g. 2026-01-01T00:00:00Z.
tostringOptionalEnd date (ISO 8601).
emailstringOptionalFilter by customer email address.

cURL

bash
curl -X GET "https://api.sellstein.com/business/biz_abc123/orders?status=completed&limit=10" \
  -H "Authorization: Bearer sk_live_your_api_key"

JavaScript

javascript
const response = await fetch(
  'https://api.sellstein.com/business/biz_abc123/orders?status=completed&limit=10',
  {
    headers: {
      'Authorization': 'Bearer sk_live_your_api_key',
    },
  }
);
const data = await response.json();

Response

json
{
  "orders": [
    {
      "id": "ord_Qw7mNp3",
      "order_number": 1042,
      "status": "completed",
      "customer_email": "jane@example.com",
      "customer_name": "Jane Doe",
      "total": 49.99,
      "currency": "USD",
      "payment_provider": "stripe",
      "items": [
        {
          "product_id": "prod_xK9mZq2",
          "product_name": "Premium License Key",
          "quantity": 1,
          "unit_price": 49.99
        }
      ],
      "created_at": "2026-02-28T16:30:00Z",
      "completed_at": "2026-02-28T16:30:05Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 10,
    "total": 356,
    "total_pages": 36
  }
}
PATCH/business/:bizId/orders/:orderId

Update an order's status or add internal notes. Commonly used to mark orders as shipped, add tracking numbers, or process refunds.

Parameters

ParameterTypeRequiredDescription
statusstringOptionalNew status: completed, shipped, refunded, cancelled.
tracking_numberstringOptionalShipping tracking number.
tracking_urlstringOptionalURL for shipment tracking.
internal_notestringOptionalPrivate note visible only to staff.

cURL

bash
curl -X PATCH "https://api.sellstein.com/business/biz_abc123/orders/ord_Qw7mNp3" \
  -H "Authorization: Bearer sk_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "shipped",
    "tracking_number": "1Z999AA10123456784",
    "tracking_url": "https://track.ups.com/1Z999AA10123456784"
  }'

JavaScript

javascript
const response = await fetch(
  'https://api.sellstein.com/business/biz_abc123/orders/ord_Qw7mNp3',
  {
    method: 'PATCH',
    headers: {
      'Authorization': 'Bearer sk_live_your_api_key',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      status: 'shipped',
      tracking_number: '1Z999AA10123456784',
      tracking_url: 'https://track.ups.com/1Z999AA10123456784',
    }),
  }
);

Response

json
{
  "id": "ord_Qw7mNp3",
  "order_number": 1042,
  "status": "shipped",
  "tracking_number": "1Z999AA10123456784",
  "tracking_url": "https://track.ups.com/1Z999AA10123456784",
  "updated_at": "2026-03-01T09:15:00Z"
}

Customers

Manage your customer database.

GET/business/:bizId/customers

Retrieve a paginated list of customers. Includes purchase history summary, lifetime value, and segmentation data.

Parameters

ParameterTypeRequiredDescription
pageintegerOptionalPage number. Defaults to 1.
limitintegerOptionalResults per page (max 100). Defaults to 25.
searchstringOptionalSearch by name or email.
sortstringOptionalSort by: created_at, total_spent, order_count. Defaults to created_at.

cURL

bash
curl -X GET "https://api.sellstein.com/business/biz_abc123/customers?limit=10&sort=total_spent" \
  -H "Authorization: Bearer sk_live_your_api_key"

JavaScript

javascript
const response = await fetch(
  'https://api.sellstein.com/business/biz_abc123/customers?limit=10&sort=total_spent',
  {
    headers: {
      'Authorization': 'Bearer sk_live_your_api_key',
    },
  }
);
const data = await response.json();

Response

json
{
  "customers": [
    {
      "id": "cust_Rt5mWq9",
      "email": "jane@example.com",
      "name": "Jane Doe",
      "country": "US",
      "total_spent": 349.94,
      "order_count": 7,
      "first_order_at": "2025-06-12T10:00:00Z",
      "last_order_at": "2026-02-28T16:30:00Z",
      "created_at": "2025-06-12T09:55:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 10,
    "total": 1243,
    "total_pages": 125
  }
}
POST/business/:bizId/customers

Manually add a customer to your store. Useful for importing customers from other platforms or adding offline customers.

Parameters

ParameterTypeRequiredDescription
emailstringRequiredCustomer email address. Must be unique per store.
namestringOptionalFull name of the customer.
countrystringOptionalISO 3166-1 alpha-2 country code (e.g. US, DE, JP).
notesstringOptionalInternal notes about the customer.

cURL

bash
curl -X POST "https://api.sellstein.com/business/biz_abc123/customers" \
  -H "Authorization: Bearer sk_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "alex@example.com",
    "name": "Alex Rivera",
    "country": "DE"
  }'

JavaScript

javascript
const response = await fetch(
  'https://api.sellstein.com/business/biz_abc123/customers',
  {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer sk_live_your_api_key',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      email: 'alex@example.com',
      name: 'Alex Rivera',
      country: 'DE',
    }),
  }
);

Response

json
{
  "id": "cust_Zp4nLm7",
  "email": "alex@example.com",
  "name": "Alex Rivera",
  "country": "DE",
  "total_spent": 0,
  "order_count": 0,
  "created_at": "2026-03-03T12:00:00Z"
}
PUT/business/:bizId/customers/:customerId

Update a customer's information. Only the provided fields will be changed.

Parameters

ParameterTypeRequiredDescription
namestringOptionalUpdated name.
countrystringOptionalUpdated country code.
notesstringOptionalUpdated internal notes.

cURL

bash
curl -X PUT "https://api.sellstein.com/business/biz_abc123/customers/cust_Zp4nLm7" \
  -H "Authorization: Bearer sk_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"name": "Alexander Rivera", "notes": "VIP customer"}'

JavaScript

javascript
const response = await fetch(
  'https://api.sellstein.com/business/biz_abc123/customers/cust_Zp4nLm7',
  {
    method: 'PUT',
    headers: {
      'Authorization': 'Bearer sk_live_your_api_key',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      name: 'Alexander Rivera',
      notes: 'VIP customer',
    }),
  }
);

Response

json
{
  "id": "cust_Zp4nLm7",
  "email": "alex@example.com",
  "name": "Alexander Rivera",
  "country": "DE",
  "notes": "VIP customer",
  "updated_at": "2026-03-03T12:30:00Z"
}

Webhooks

Receive real-time notifications when events happen in your store.

Webhook Setup

Configure webhook endpoints from your dashboard under Settings > Webhooks.

http
POST https://your-server.com/webhooks/sellstein
Content-Type: application/json
X-SellStein-Signature: sha256=5d7861...

{
  "event": "order.created",
  "data": { ... },
  "timestamp": "2026-03-03T10:15:00Z",
  "webhook_id": "whk_Mn4pQr8"
}

Webhook Events

EventDescription
order.createdFired when a new order is placed.
order.updatedFired when an order status changes (shipped, refunded, etc.).
order.completedFired when an order is marked as completed.
order.refundedFired when an order is fully or partially refunded.
product.createdFired when a new product is created.
product.updatedFired when a product is updated.
product.deletedFired when a product is deleted.
customer.createdFired when a new customer is added.
subscription.createdFired when a new subscription begins.
subscription.renewedFired when a subscription payment succeeds.
subscription.cancelledFired when a subscription is cancelled.
dispute.createdFired when a chargeback/dispute is opened.

Signature Verification

Verify webhook signatures to ensure requests are from SellStein.

javascript
import crypto from 'crypto';

function verifyWebhookSignature(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload, 'utf8')
    .digest('hex');

  const sig = signature.replace('sha256=', '');

  return crypto.timingSafeEqual(
    Buffer.from(sig, 'hex'),
    Buffer.from(expected, 'hex')
  );
}

// Express example
app.post('/webhooks/sellstein', (req, res) => {
  const signature = req.headers['x-sellstein-signature'];
  const isValid = verifyWebhookSignature(
    JSON.stringify(req.body),
    signature,
    process.env.WEBHOOK_SECRET
  );

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

  const { event, data } = req.body;
  switch (event) {
    case 'order.created':
      handleNewOrder(data);
      break;
    case 'order.refunded':
      handleRefund(data);
      break;
  }

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

Rate Limits

Understand API rate limiting and how to handle it.

120
120 requests per minute per IP
Per IP
Rate Limit Scope
60s
Rate Limit Window

Rate Limit Headers

HeaderDescription
X-RateLimit-LimitMaximum number of requests allowed per window (120).
X-RateLimit-RemainingNumber of requests remaining in the current window.
X-RateLimit-ResetUnix timestamp (seconds) when the rate limit window resets.

Handling Rate Limits

javascript
async function fetchWithRetry(url, options, retries = 3) {
  for (let i = 0; i < retries; i++) {
    const response = await fetch(url, options);

    if (response.status === 429) {
      const resetAt = response.headers.get('X-RateLimit-Reset');
      const waitMs = resetAt
        ? (parseInt(resetAt) * 1000) - Date.now()
        : 1000 * Math.pow(2, i); // Exponential backoff

      console.log(`Rate limited. Retrying in ${waitMs}ms...`);
      await new Promise(r => setTimeout(r, Math.max(waitMs, 100)));
      continue;
    }

    return response;
  }

  throw new Error('Max retries exceeded');
}

Errors

Standard error codes and response format.

Error Response Format

All errors follow a consistent JSON format.

json
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "The 'price' field must be a positive number.",
    "status": 400,
    "details": [
      {
        "field": "price",
        "issue": "Must be greater than 0"
      }
    ]
  }
}
StatusCodeDescription
400VALIDATION_ERRORThe request body is malformed or missing required fields. Check the details array for specifics.
401UNAUTHORIZEDNo valid API key provided. Ensure your Authorization header is set correctly.
403FORBIDDENThe API key does not have permission for this action. Check your key scopes and business access.
404NOT_FOUNDThe requested resource does not exist. Verify the ID and business context.
429RATE_LIMITEDToo many requests. Back off and retry after the X-RateLimit-Reset timestamp.
500INTERNAL_ERRORAn unexpected server error occurred. If this persists, contact support.

SDKs & Libraries

Official and community SDKs for popular languages.

{}

Node.js / TypeScript

npm install @sellstein/sdk
#

Python

pip install sellstein
$

PHP

composer require sellstein/sdk
>

Go

go get github.com/sellstein/go-sdk
!

Ruby

gem install sellstein
$

cURL

No installation needed

SDK Usage Example

javascript
import { SellStein } from '@sellstein/sdk';

const client = new SellStein({
  apiKey: 'sk_live_your_api_key',
  businessId: 'biz_abc123',
});

// List products
const products = await client.products.list({
  status: 'active',
  limit: 25,
});

// Create an order
const order = await client.orders.create({
  customer_email: 'buyer@example.com',
  items: [
    { product_id: 'prod_xK9mZq2', quantity: 1 },
  ],
});

// Listen to webhooks
client.webhooks.on('order.created', (event) => {
  console.log('New order:', event.data.id);
});

Need Help?

Our developer support team is here to help you integrate.