Store API — options & variants

Manage your Southbill Store catalogue, option groups, variants, orders and evidence with your secret API key.

Store API — options & variants

Your Southbill Store catalogue is reachable with the same secret API key you use for the rest of the REST API. Base URL:

https://api.southbill.com/v1/store

So GET https://api.southbill.com/v1/store returns the store itself, GET https://api.southbill.com/v1/store/products lists products.

Authenticate with Authorization: Bearer sk_live_… (server-side only — secret keys are rejected from a browser origin). Write calls accept an Idempotency-Key header.

Required scopes: store:read, products:read, products:write, orders:read, orders:write, files:write. Existing keys were upgraded automatically.

Why variants

A product is the catalogue item ("Runner 01"). A variant is the concrete thing a buyer picks — Size M, Colour Black. Variants are built from option groups (Size) and option values (S, M, L). Each variant references exactly one value per option group and may carry its own price, SKU and stock.

Product "Runner 01"
├─ Option group "Size"   → values S, M, L
├─ Option group "Colour" → values Black, White
└─ Variants: S/Black (SKU RUN-S-BLK), M/Black, …

Endpoints

Method Path Description
GET /store The merchant's store (slug, display name, status, logo/cover URLs).
GET /products List products.
GET /products/{id} Product incl. option_groups and variants.
POST /products Create a product.
PATCH /products/{id} Update a product.
DELETE /products/{id} Archive a product.
POST /products/{id}/prices Create a price (min 250 minor units).
GET POST /products/{id}/options List / create option groups.
PATCH DELETE /options/{id} Rename / delete an option group.
POST /options/{id}/values Add a value to a group.
DELETE /values/{id} Delete an option value.
GET POST /products/{id}/variants List / create variants.
PATCH DELETE /variants/{id} Update / delete a variant.
GET /orders, /orders/{id} Store orders (source store only).
PATCH /orders/{id} Fulfillment updates — shipped/completed need evidence.
POST /orders/{id}/evidence Attach delivery evidence.
POST /checkouts Create a Checkout session for a store product/variant.
POST /files Upload product images, documents or evidence (max 5 MB).

Create an option group

curl https://api.southbill.com/v1/store/products/PRODUCT_ID/options \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "name": "Size", "values": ["S", "M", "L"] }'
{
  "object": "option_group",
  "id": "8df0e320-…",
  "product": "019c72f4-…",
  "name": "Size",
  "values": [
    { "object": "option_value", "id": "9f7e71ab-…", "value": "S", "sort_order": 0 },
    { "object": "option_value", "id": "82170ba4-…", "value": "M", "sort_order": 1 }
  ]
}

Create a variant

curl https://api.southbill.com/v1/store/products/PRODUCT_ID/variants \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: variant-run01-s-blk" \
  -d '{
    "options": [{ "group": "8df0e320-…", "value": "9f7e71ab-…" }],
    "price": "6040da6b-…",
    "sku": "RUN-S-BLK",
    "track_inventory": true,
    "stock_qty": 12
  }'

Presentation fields

Variants accept the same presentation fields as the dashboard editor, on both POST /products/{id}/variants and PATCH /variants/{id}:

Field Type Notes
title string ≤80 Variant headline (falls back to the option combination).
description string ≤2000 Variant-specific description.
image_path string ≤300 or null Storage path from POST /v1/store/files.
features string[] Max 12 entries, each ≤120 chars, duplicates dropped.
delivery_days integer 0–3650 or null Delivery time shown in the storefront.
revisions integer 0–3650 or null Included revisions (service products).
highlight boolean Marks the variant as recommended.
sort_order integer Display order.

All of them are returned on every variant object.

Rules enforced by the API:

  • options must contain exactly one value per option group of the product.
  • A value must belong to the group it is sent with (invalid_options, 400).
  • The same combination cannot exist twice (variant_exists, 409).
  • price must be an active price on the same product; omit it to inherit the product's default price.
  • stock_qty is required when track_inventory is true.
  • The option combination is immutable — delete and recreate the variant to change it.

Deleting

Deletion is guarded so your storefront never ends up with dangling variants:

  • DELETE /values/{id} → 409 value_in_use while a variant uses that value.
  • DELETE /options/{id} → 409 variants_exist while the product still has variants.
  • DELETE /variants/{id} works at any time, except for the implicit default variant of a product.

Checkout for a store product

Create a hosted Checkout session for a catalogue product or variant. Price, currency and stock are resolved server-side from your catalogue — you only name the product.

curl https://api.southbill.com/v1/store/checkouts \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: checkout-run01-0001" \
  -d '{
    "product_id": "019c72f4-…",
    "variant_id": "b6f2b0e0-…",
    "quantity": 1,
    "success_url": "https://yourshop.com/thanks",
    "cancel_url": "https://yourshop.com/cart"
  }'
{
  "ok": true,
  "session_id": "cs_...",
  "checkout_url": "https://payments.southbill.com/c/cs_...?cs=...",
  "amount": 4900,
  "currency": "eur",
  "expires_at": "2026-01-01T12:30:00.000Z"
}

Details:

  • Scope: checkout:write. Secret keys only (never from a browser).
  • The store must be live and approved, the product active and store_visible.
  • Stock is reserved for the session and released automatically when it expires (30 min) or is cancelled.
  • Variant price wins, otherwise the product's default price is used. Recurring prices are rejected (unsupported_price).
  • success_url / cancel_url are optional and must be https; they default to your storefront.
  • The session is a normal Checkout session with source = store, so it produces store.* order events, not plain payment.* only.
  • Errors: product_unavailable (404), variant_unavailable (404), price_unavailable (409), out_of_stock (409), amount_too_small (400).

Sandbox

The identical routes exist in the sandbox through an installed app (App API, environment test). Sandbox writes never touch a payment provider — the catalogue, variants and orders live in isolated sandbox tables and are wiped on a sandbox reset.