Get Started

Introduction

Welcome to the Selley REST API. Build your own apps, scripts, and integrations on top of your Selley store. All endpoints return JSON and require a Bearer API key in the Authorization header.

Create and manage API keys in Dashboard → Settings → Security. Use the API base URL for your deployment (e.g. https://selley.io/api/v1 or your custom domain). All requests must use HTTPS.

API Root URL

https://selley.io/api/v1

Quick example

bash
curl https://selley.io/api/v1/products \
  -H "Authorization: Bearer YOUR_API_KEY"

Authentication

Every request must include your API secret key as a Bearer token in the Authorization header. Generate and manage keys in your dashboard under Settings → Security. All requests must be made over HTTPS.

Setup Authentication Header

curl https://selley.io/api/v1/products \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxx"

Multiple Shops

If your account has more than one shop, pass the X-Selley-Shop header with the shop's ID or slug on each request. Without this header the first (oldest) shop is used automatically.

bash
curl https://selley.io/api/v1/orders \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "X-Selley-Shop: my-shop-slug"

Rate limits

API requests may be rate-limited per API key. If you exceed the limit you will receive 429 Too Many Requests. Retry after the suggested delay. Webhook delivery has a 15-second timeout per request; failed deliveries are logged and can be retried from the dashboard.

Errors

Errors always return JSON with an error string. Validation errors may include an errors array with field-level details. Use the HTTP status code to determine the type of error.

StatusMeaning
400Bad Request – invalid parameters or missing required fields.
401Unauthorized – missing or invalid API key.
403Forbidden – the request is not allowed.
404Not Found – the resource does not exist.
409Conflict – e.g. duplicate coupon code.
429Too Many Requests – rate limit exceeded.
500Internal Server Error – retry later.
json
{
  "error": "Unauthorized"
}

// Validation error
{
  "error": "code: String must contain at least 1 character(s)"
}
Products

Endpoints: /api/v1/products

GET/products

Returns a paginated list of your Live products, sorted by creation date descending.

Query Parameters

NameTypeDescription
limitintegerMax items per page (default 100, max 250).
cursorstringPagination cursor from previous response.

Response

json
{
  "products": [
    {
      "id": "clxabc123",
      "productId": "rec_abc123",
      "name": "Pro License",
      "description": "One-year software license",
      "image": "https://cdn.selley.io/img.jpg",
      "type": "Serial",
      "price": 29.99,
      "currency": "USD",
      "stock": 50,
      "status": "Live",
      "sortOrder": 0,
      "unlisted": false,
      "createdAt": "2024-06-01T10:00:00.000Z",
      "updatedAt": "2024-06-01T10:00:00.000Z"
    }
  ],
  "nextCursor": "clxdef456"
}

Request Example

curl "https://selley.io/api/v1/products?limit=10" \
  -H "Authorization: Bearer YOUR_API_KEY"
GET/products/:id

Retrieve a single product by its internal ID or the shorter productId (e.g. rec_abc123).

URL Parameters

NameTypeDescription
idrequiredstringInternal ID or productId of the product.

Request Example

curl "https://selley.io/api/v1/products/rec_abc123" \
  -H "Authorization: Bearer YOUR_API_KEY"
POST/products

Create a new product. The product is created in Draft status by default. Set status to Live to make it visible on your storefront.

Request Body

NameTypeDescription
namerequiredstringProduct title.
pricerequirednumberPrice in the specified currency.
typerequiredstringService | Digital | Serial | Subscription | InfoCard | Dynamic
descriptionstringProduct description.
currencystring3-letter currency code (default USD).
stockinteger | nullStock count. null = unlimited.
statusstringLive | Draft | Archived. Default: Draft.
unlistedbooleanHide from storefront but accessible via direct link.

Request Example

curl -X POST "https://selley.io/api/v1/products" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Pro License",
    "price": 29.99,
    "type": "Serial",
    "currency": "USD",
    "status": "Live"
  }'
PUT/products/:id

Update any fields of an existing product. Only the fields you include will be changed.

Updatable Fields

NameTypeDescription
namestringNew product title.
pricenumberNew price.
statusstringLive | Draft | Archived
stockinteger | nullNew stock count.
descriptionstringNew description.
unlistedbooleanHide/show on storefront.

Request Example

curl -X PUT "https://selley.io/api/v1/products/rec_abc123" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"price": 39.99, "status": "Live"}'
DELETE/products/:id

Permanently delete a product. This cannot be undone. Returns success: true on success.

json
{ "success": true }

Request Example

curl -X DELETE "https://selley.io/api/v1/products/rec_abc123" \
  -H "Authorization: Bearer YOUR_API_KEY"
Orders

Endpoints: /api/v1/orders

GET/orders

Returns orders for your shop(s), most recent first. Includes order items. Scoped by shop (use X-Selley-Shop for multi-shop).

Query Parameters

NameTypeDescription
limitintegerMax items (default 50, max 200).

Response

json
{
  "orders": [
    {
      "id": "clxabc123",
      "orderNumber": "ORD-12345",
      "status": "completed",
      "paymentStatus": "paid",
      "total": 29.99,
      "currency": "USD",
      "customerEmail": "[email protected]",
      "customerName": "Jane Smith",
      "paymentMethod": "Stripe",
      "createdAt": "2024-06-01T10:00:00.000Z",
      "paidAt": "2024-06-01T10:01:30.000Z",
      "items": [
        {
          "id": "item_123",
          "productId": "clx_prod",
          "productName": "Pro License",
          "quantity": 1,
          "price": 29.99,
          "total": 29.99
        }
      ]
    }
  ]
}

Request Example

curl "https://selley.io/api/v1/orders?limit=20" \
  -H "Authorization: Bearer YOUR_API_KEY"
GET/orders/:id

Retrieve a single order by its internal ID or the display orderNumber (e.g. ORD-12345). Includes full item list.

NameTypeDescription
idrequiredstringInternal ID or orderNumber.
curl "https://selley.io/api/v1/orders/ORD-12345" \
  -H "Authorization: Bearer YOUR_API_KEY"
PUT/orders/:id

Update the status of an order. Useful for manually marking orders as completed or cancelled.

NameTypeDescription
statusstringpending | processing | completed | cancelled | refunded
curl -X PUT "https://selley.io/api/v1/orders/ORD-12345" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status": "completed"}'
Coupons

Endpoints: /api/v1/coupons

GET/coupons

Returns all discount coupons for your account. Filter to only active coupons with active=true.

Query Parameters

NameTypeDescription
activebooleanPass true to only return active coupons.

Response

json
{
  "coupons": [
    {
      "id": "clxabc123",
      "code": "SAVE20",
      "type": "percentage",
      "value": 20,
      "usageLimit": 100,
      "usedCount": 3,
      "minAmount": 10,
      "expiresAt": "2025-12-31T23:59:59.000Z",
      "active": true,
      "createdAt": "2024-06-01T10:00:00.000Z",
      "updatedAt": "2024-06-01T10:00:00.000Z"
    }
  ]
}
curl "https://selley.io/api/v1/coupons?active=true" \
  -H "Authorization: Bearer YOUR_API_KEY"
GET/coupons/:id

Retrieve a single coupon by its ID.

NameTypeDescription
idrequiredstringCoupon ID.
curl "https://selley.io/api/v1/coupons/clxabc123" \
  -H "Authorization: Bearer YOUR_API_KEY"
POST/coupons

Create a new coupon code. Supports percentage or fixed discounts, usage limits, and optional expiry dates.

Request Body

NameTypeDescription
coderequiredstringCoupon code (e.g. SAVE20). Automatically uppercased.
typerequiredstringpercentage | fixed
valuerequirednumberDiscount amount (% or currency unit).
usageLimitinteger | nullMax redemptions. null = unlimited.
minAmountnumber | nullMinimum order total to apply coupon.
expiresAtstring | nullISO 8601 expiry date. null = no expiry.
activebooleanWhether the coupon is active. Default true.
curl -X POST "https://selley.io/api/v1/coupons" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "SAVE20",
    "type": "percentage",
    "value": 20,
    "usageLimit": 100,
    "minAmount": 10,
    "expiresAt": "2025-12-31T23:59:59.000Z"
  }'
PUT/coupons/:id

Update an existing coupon. Only the fields you provide will be modified.

NameTypeDescription
codestringNew coupon code.
typestringpercentage | fixed
valuenumberNew discount value.
usageLimitinteger | nullNew max redemptions.
activebooleanEnable or disable the coupon.
expiresAtstring | nullNew expiry date or null to remove.
curl -X PUT "https://selley.io/api/v1/coupons/clxabc123" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"active": false}'
DELETE/coupons/:id

Permanently delete a coupon. Returns success: true.

json
{ "success": true }
curl -X DELETE "https://selley.io/api/v1/coupons/clxabc123" \
  -H "Authorization: Bearer YOUR_API_KEY"
Blacklists

Endpoints: /api/v1/blacklists — shop-scoped

GET/blacklists

List all blacklist entries (IP, country, email) for your shop. Blocked visitors are prevented from viewing your storefront.

json
{
  "blacklists": [
    {
      "id": "clxabc123",
      "type": "IP",
      "value": "192.168.1.1",
      "reason": "Fraud attempt",
      "createdAt": "2024-06-01T10:00:00.000Z"
    },
    {
      "id": "clxdef456",
      "type": "COUNTRY",
      "value": "RU",
      "reason": null,
      "createdAt": "2024-06-02T09:00:00.000Z"
    }
  ]
}
curl "https://selley.io/api/v1/blacklists" \
  -H "Authorization: Bearer YOUR_API_KEY"
GET/blacklists/:id

Retrieve a single blacklist entry by ID.

NameTypeDescription
idrequiredstringBlacklist entry ID.
curl "https://selley.io/api/v1/blacklists/clxabc123" \
  -H "Authorization: Bearer YOUR_API_KEY"
POST/blacklists

Add a new entry to your shop's blacklist. type must be one of IP, COUNTRY, or EMAIL.

NameTypeDescription
typerequiredstringIP | COUNTRY | EMAIL
valuerequiredstringThe IP address, 2-letter country code, or email.
reasonstringOptional internal note.
curl -X POST "https://selley.io/api/v1/blacklists" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "IP",
    "value": "1.2.3.4",
    "reason": "Chargeback fraud"
  }'
PUT/blacklists/:id

Update an existing blacklist entry's type, value, or reason.

NameTypeDescription
typestringIP | COUNTRY | EMAIL
valuestringNew blocked value.
reasonstringNew reason note.
curl -X PUT "https://selley.io/api/v1/blacklists/clxabc123" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"reason": "Updated reason"}'
DELETE/blacklists/:id

Remove an entry from your blacklist. The visitor will no longer be blocked.

json
{ "success": true }
curl -X DELETE "https://selley.io/api/v1/blacklists/clxabc123" \
  -H "Authorization: Bearer YOUR_API_KEY"
Categories

Endpoints: /api/v1/categories

GET/categories

List all categories for your account, sorted by sortOrder then creation date. Includes bound products and groups.

json
{
  "categories": [
    {
      "id": "clxabc123",
      "name": "Software",
      "sortOrder": 1,
      "unlisted": false,
      "products": [
        { "id": "...", "name": "Pro License", "productId": "rec_123" }
      ],
      "groups": [
        { "id": "...", "name": "Starter Bundle" }
      ],
      "createdAt": "2024-06-01T10:00:00.000Z"
    }
  ]
}
curl "https://selley.io/api/v1/categories" \
  -H "Authorization: Bearer YOUR_API_KEY"
GET/categories/:id

Retrieve a single category with its bound products and groups.

NameTypeDescription
idrequiredstringCategory ID.
bash
curl "https://selley.io/api/v1/categories/clxabc123" \
  -H "Authorization: Bearer YOUR_API_KEY"
POST/categories

Create a new category and optionally bind products and/or groups to it.

NameTypeDescription
namerequiredstringCategory title.
sortOrderintegerDisplay order (lower = first). Default 0.
unlistedbooleanHide from storefront. Default false.
productIdsstring[]Array of product IDs to bind.
groupIdsstring[]Array of group IDs to bind.
curl -X POST "https://selley.io/api/v1/categories" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Software",
    "sortOrder": 1,
    "productIds": ["clxprod1", "clxprod2"]
  }'
PUT/categories/:id

Update category fields. Passing productIds or groupIds replaces the full bound list.

NameTypeDescription
namestringNew category name.
sortOrderintegerNew sort position.
unlistedbooleanShow or hide the category.
productIdsstring[]Replaces all bound products.
groupIdsstring[]Replaces all bound groups.
bash
curl -X PUT "https://selley.io/api/v1/categories/clxabc123" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Digital Goods", "sortOrder": 0}'
DELETE/categories/:id

Delete a category. Products and groups in the category are not deleted.

json
{ "success": true }
bash
curl -X DELETE "https://selley.io/api/v1/categories/clxabc123" \
  -H "Authorization: Bearer YOUR_API_KEY"
Groups

Endpoints: /api/v1/groups

GET/groups

List all product groups (bundles) for your account, including the products inside each group.

json
{
  "groups": [
    {
      "id": "clxabc123",
      "name": "Starter Bundle",
      "description": "Best value pack",
      "discountPercent": 15,
      "sortOrder": 0,
      "unlisted": false,
      "products": [
        { "id": "...", "name": "...", "productId": "rec_1", "price": 9.99 }
      ],
      "createdAt": "2024-06-01T10:00:00.000Z",
      "updatedAt": "2024-06-01T10:00:00.000Z"
    }
  ]
}
curl "https://selley.io/api/v1/groups" \
  -H "Authorization: Bearer YOUR_API_KEY"
GET/groups/:id

Retrieve a single group by ID, including its products.

NameTypeDescription
idrequiredstringGroup ID.
bash
curl "https://selley.io/api/v1/groups/clxabc123" \
  -H "Authorization: Bearer YOUR_API_KEY"
POST/groups

Create a new product group with an optional bundle discount. Bind products by passing productIds.

NameTypeDescription
namerequiredstringGroup name.
descriptionstringOptional description.
discountPercentnumberBundle discount percentage 0–100.
imagestringGroup image URL.
sortOrderintegerDisplay order. Default 0.
unlistedbooleanHide from storefront.
productIdsstring[]Product IDs to include in the group.
curl -X POST "https://selley.io/api/v1/groups" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Starter Bundle",
    "discountPercent": 15,
    "productIds": ["clxprod1", "clxprod2"]
  }'
PUT/groups/:id

Update group fields. Passing productIds replaces the group's product list.

NameTypeDescription
namestringNew name.
discountPercentnumberNew discount percentage.
sortOrderintegerNew display order.
unlistedbooleanShow/hide.
productIdsstring[]Replaces the full product list.
bash
curl -X PUT "https://selley.io/api/v1/groups/clxabc123" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"discountPercent": 20}'
DELETE/groups/:id

Delete a group. Products in the group are not deleted.

json
{ "success": true }
bash
curl -X DELETE "https://selley.io/api/v1/groups/clxabc123" \
  -H "Authorization: Bearer YOUR_API_KEY"
Customers

Endpoints: /api/v1/customers — shop-scoped, read-only

GET/customers

List all customers who have placed orders in your shop. Sorted by creation date descending.

json
{
  "customers": [
    {
      "id": "clxabc123",
      "email": "[email protected]",
      "name": "Jane Smith",
      "phone": "+1234567890",
      "country": "US",
      "city": "New York",
      "totalOrders": 5,
      "totalSpent": 149.95,
      "lastOrderAt": "2024-06-10T15:00:00.000Z",
      "createdAt": "2024-01-05T08:00:00.000Z",
      "updatedAt": "2024-06-10T15:00:00.000Z"
    }
  ]
}
curl "https://selley.io/api/v1/customers?limit=50" \
  -H "Authorization: Bearer YOUR_API_KEY"
GET/customers/:id

Retrieve a single customer by their ID including order stats and notes.

NameTypeDescription
idrequiredstringCustomer ID.
curl "https://selley.io/api/v1/customers/clxabc123" \
  -H "Authorization: Bearer YOUR_API_KEY"
Subscriptions

Endpoints: /api/v1/subscriptions — shop-scoped, read-only

GET/subscriptions

List all recurring subscriptions for your shop. Includes product and customer details.

json
{
  "subscriptions": [
    {
      "id": "clxabc123",
      "productId": "clx_prod",
      "productName": "Pro Plan",
      "productProductId": "rec_pro",
      "customerId": "clx_cust",
      "customerEmail": "[email protected]",
      "status": "ACTIVE",
      "stripeSubscriptionId": "sub_xxxxxxxxxx",
      "stripeCustomerId": "cus_xxxxxxxxxx",
      "currentPeriodEnd": "2024-07-01T00:00:00.000Z",
      "createdAt": "2024-06-01T10:00:00.000Z",
      "canceledAt": null
    }
  ]
}
curl "https://selley.io/api/v1/subscriptions" \
  -H "Authorization: Bearer YOUR_API_KEY"
GET/subscriptions/:id

Retrieve a single subscription by ID including Stripe IDs and period end date.

NameTypeDescription
idrequiredstringSubscription ID.
curl "https://selley.io/api/v1/subscriptions/clxabc123" \
  -H "Authorization: Bearer YOUR_API_KEY"
Webhooks

Receive HTTP POST requests when events happen in your store

Overview

Webhooks send a POST request to a URL you provide whenever certain events occur (e.g. order paid, product updated, subscription renewed). Configure webhooks in the dashboard under Developers → Webhooks: add your endpoint URL and select which events to subscribe to. At least one event must be selected per webhook.

Each request includes a JSON body with event, data (detailed payload), timestamp, and source. Your endpoint should respond with 2xx to acknowledge receipt. Non-2xx responses are logged and may be retried.

Event types

Events are grouped by category. Select the events you need when creating a webhook. The data object structure depends on the event category (see Payload structure below).

Order

  • order:created · order:updated · order:partial · order:paid · order:paid:product
  • order:cancelled · order:disputed · order:cancelled:product · order:disputed:product
  • order:created:product · order:partial:product · order:updated:product

Query

  • query:created · query:replied

Feedback

  • feedback:received

Product

  • product:created · product:edited · product:stock · product:dynamic

Subscription

  • subscription:trial:started · subscription:trial:started:product · subscription:created · subscription:created:product
  • subscription:renewed · subscription:renewed:product · subscription:updated · subscription:updated:product
  • subscription:cancelled · subscription:cancelled:product · subscription:trial:ended · subscription:trial:ended:product
  • subscription:upcoming · subscription:upcoming:product

Request format

Every webhook is sent as POST to your URL with the following headers and body.

Headers

HeaderValue
Content-Typeapplication/json
User-AgentSelley-Webhook/1.0

Top-level body fields

NameTypeDescription
eventrequiredstringEvent identifier (e.g. order:paid, subscription:renewed).
datarequiredobjectEvent-specific payload. Structure described in Payload structure sections below.
timestampstringISO 8601 time when the webhook was sent.
sourcestringAlways "selley".

Your endpoint should respond with HTTP 200299 to acknowledge receipt. Timeout is 15 seconds. Failed or non-2xx deliveries are logged in Developers → Webhook Logs where you can retry or view the payload.

Payload structure

The data object in each webhook is detailed and depends on the event category. Below are the full structures for Order, Subscription, Product, Query, and Feedback. All monetary values use the order/product currency; timestamps are Unix seconds unless noted.

json
{
  "event": "order:paid",
  "data": { /* see Order data below */ },
  "timestamp": "2024-06-15T14:32:00.000Z",
  "source": "selley"
}

Order data

For all order:* events, data includes order details, customer, product, gateway, fees, IP/location, status history, delivery info, and nested product block.

Identifiers & type: id, uniqid, type (PRODUCT), subtype, origin (e.g. EMBED).

Amounts: total, total_display, currency, exchange_rate, discount, fee_percentage, fee_breakdown, discount_breakdown.

Shop & customer: shop_id, name (shop name), customer_email, customer_id.

Product: product_id, product_title, product_type, quantity, subscription_id (null for one-time), subscription_time.

Gateway: gateway (STRIPE, PAYPAL, etc.), gateway_data, stripe_id / paypal_order_id etc.

Location & IP: country, location, ip, is_vpn_or_proxy, ip_info (ISP, city, region, device, browser, proxy/vpn/tor flags).

Status: status (e.g. COMPLETED), status_history, status_history_raw, created_at, updated_at.

Nested: product (full product object), products (array of line items), delivery_info, delivery, total_conversions (multi-currency/crypto).

json
{
  "id": 238987,
  "uniqid": "593fe6-bd6c461fa4-f713f6",
  "type": "PRODUCT",
  "origin": "EMBED",
  "total": 45.77,
  "total_display": "33.99",
  "currency": "USD",
  "shop_id": 5436,
  "customer_email": "[email protected]",
  "customer_id": "cst_xxx",
  "product_id": "6894accbf05b6",
  "product_title": "Semi-Annual Alpha Package",
  "product_type": "SERVICE",
  "quantity": 1,
  "subscription_id": null,
  "gateway": "STRIPE",
  "status": "COMPLETED",
  "discount": 0,
  "fee_percentage": 4,
  "country": "GB",
  "ip": "2a00:23c7:...",
  "ip_info": { "country_code": "GB", "city": "London", "ISP": "...", "vpn": 0, "proxy": 0 },
  "created_at": 1772131826,
  "updated_at": 1772131943,
  "status_history": [...],
  "gateway_data": { "type": "STRIPE", "label": "Stripe", "payment_reference": "pi_xxx" },
  "product": { "uniqid": "...", "title": "...", "price_display": "...", "currency": "...", ... },
  "products": [{ "uniqid": "...", "title": "...", "quantity": 1, ... }],
  "delivery_info": { "downloads": [], "license_keys": [], "external_urls": [...], "tracking_codes": [] },
  "total_conversions": { "USD": 45.77, "EUR": "39.38", "crypto": { "BTC": "...", "ETH": "..." } }
}

Subscription data

For subscription:* events, data includes which product, amount, billing interval, subscription and Stripe IDs, period dates, trial info, and customer.

NameTypeDescription
id / uniqidstringSubscription identifier.
shop_id, shop_namenumber / stringShop context.
product_id, product_uniqid, product_title, product_typestringProduct the subscription is for.
customer_id, customer_emailstringSubscriber.
subscription_id, stripe_subscription_id, stripe_price_idstringSubscription and Stripe references.
subscription_statusstringACTIVE, TRIALING, CANCELLED, etc.
amount, amount_display, currency, quantitynumber / stringRecurring amount and quantity.
billing_interval, recurring_interval_countstring / numbere.g. MONTH, 1.
current_period_start, current_period_endnumberUnix timestamps for current period.
trial_start, trial_endnumber | nullTrial period (if applicable).
gateway, country, ip, ip_infostring / objectPayment gateway and location.
created_at, updated_at, canceled_atnumber | nullTimestamps.
productobjectFull product block.

Product data

For product:created, product:edited, product:stock, product:dynamic, data includes product details, pricing, stock, gateways, and metadata.

NameTypeDescription
id, uniqidstringProduct identifier.
shop_id, title, description, product_typestringShop and product info.
price, price_display, currencynumber / stringPricing.
quantity_min, quantity_max, stock, stock_warningnumberQuantity and stock.
gatewaysstring[]Enabled gateways (e.g. STRIPE, PAYPAL).
image_name, image_storage, unlisted, sort_prioritystring / number / booleanMedia and visibility.
volume_discountsarraye.g. [{ type: PERCENTAGE, value: 5, quantity: 10 }].
created_at, updated_atnumberUnix timestamps.

Query & Feedback data

Query (query:created, query:replied): data includes id, ticket_id, shop_id, customer_email, customer_id, subject, message, status, reply_count, created_at, updated_at.

Feedback (feedback:received): data includes id, shop_id, product_id, product_title, order_id, customer_email, rating, comment, created_at.

Logs & Simulator

In the dashboard, Developers → Webhook Logs shows every delivery attempt: URL, event, response status, retry count, and created time. You can Send again to retry a failed delivery or open Payload to view the exact JSON that was sent.

Use the Simulator to send a test webhook to a configured URL: choose a webhook and an event, then trigger a delivery. The payload will match the structure documented above (with sample data). This helps verify your endpoint and payload handling without creating real orders or subscriptions.

Open Webhook Logs & Simulator
Embed

Add buy buttons and checkout to any site

Overview

The Embed lets you place a product or bundle (group) checkout on any external website. Customers see your product, choose quantity, and complete payment without leaving the host site. The flow is a modal that opens from your embed script; checkout and payment happen inside the modal.

Generate your embed code in the dashboard under Developers → Embed: select a product or group, optionally set button text and styles, then copy the script and HTML snippet. Add them to your site where you want the button to appear.

Open Embed generator

Usage

Include the Selley embed script on your page, then add a button or link with data-selley-store, and for a single product data-selley-product (product ID from your store), or for a bundle data-selley-group (group ID). When the user clicks, a modal opens with the product/group details and a gateway selection that leads to full checkout. No redirect to Selley is required; the flow stays in the modal.

Example: single product

html
<script src="https://your-domain.com/embed.js" async></script>
<button data-selley-store="your-store" data-selley-product="rec_abc123">
  Buy now
</button>

Example: bundle (group)

html
<button data-selley-store="your-store" data-selley-group="group_xyz">
  Buy bundle
</button>

Your store subdomain (e.g. your-store.myselley.com) or custom domain is used as the base. The embed script and CSS URL are shown in the dashboard Embed page.

Selley API · selley.io