REST API
Products

Products

Products are marketplace listings — physical goods, digital downloads, services. Each product has a sku (stable per-community id), price + currency, and optional images. Pricing can vary by member tier (see Segments).

Base URL: https://api.cobuntu.com/api/v1

Every endpoint requires an X-API-Key header. See Authentication for scope details.

GET /communities/{communityTag}/products — List products

Scope: READ_PUBLIC

Path parameters:

ParamTypeDescription
communityTagstringYour community's tag (e.g. your-community, acme).

Query parameters:

ParamTypeDefaultDescription
limitinteger20Page size. Default 20, max 100.
offsetinteger0Zero-based offset for pagination. Use either offset or cursor — not both.

Response (200):

[
  {
      "id": "…",
      "sku": "…",
      "name": "…",
      "description": "…"  // nullable,
      "priceCents": 0,
      "currency": "…",
      "imageUrl": "…"  // nullable,
      "isActive": false,
      "sellerId": "…",
    }
]
FieldTypeDescription
idstringStable product identifier (uuid).
skustringStable per-community SKU; use this for deep-links and inventory keys.
namestringDisplay name on product cards + detail pages.
descriptionstring (nullable)Long-form description (markdown).
priceCentsintegerPrice in the smallest currency unit.
currencystringISO 4217 code.
imageUrlstring (nullable)Primary image (or null).
isActivebooleanWhether the product accepts new orders.
sellerIdstringUser id of the member who listed the product (when the community has user-seller stack enabled).

Example:

curl https://api.cobuntu.com/api/v1/communities/my-community/products \
  -H "X-API-Key: pk_live_..."

GET /communities/{communityTag}/products/{sku} — Get product by SKU

Scope: READ_PUBLIC

Path parameters:

ParamTypeDescription
communityTagstringYour community's tag (e.g. your-community, acme).
skustringProduct SKU from GET /products.

Response (200):

{
  "id": "…",
  "sku": "…",
  "name": "…",
  "description": "…"  // nullable,
  "priceCents": 0,
  "currency": "…",
  "imageUrl": "…"  // nullable,
  "isActive": false,
  "sellerId": "…",
}
FieldTypeDescription
idstringStable product identifier (uuid).
skustringStable per-community SKU; use this for deep-links and inventory keys.
namestringDisplay name on product cards + detail pages.
descriptionstring (nullable)Long-form description (markdown).
priceCentsintegerPrice in the smallest currency unit.
currencystringISO 4217 code.
imageUrlstring (nullable)Primary image (or null).
isActivebooleanWhether the product accepts new orders.
sellerIdstringUser id of the member who listed the product (when the community has user-seller stack enabled).

Example:

curl https://api.cobuntu.com/api/v1/communities/my-community/products/EXAMPLE_ID \
  -H "X-API-Key: pk_live_..."

POST /communities/{communityTag}/products/{sku}/donate — Donate without buying a product

Creates a Stripe Checkout session for a standalone donation. No product purchase happens; the seller receives the donation through the regular payout cycle. Requires the WRITE_SALES scope.

Useful for "Support the maker" affordances on creator product pages, where a fan wants to contribute without taking a copy of the product.

The endpoint validates the amount against product.donationConfig and rejects when donations aren't enabled. PWYW configs enforce Stripe's minimum charge (50 smallest currency units) since the donation is the entire session total.

Rate limit: 30 donations per IP per hour. Exceeded limits return 429 Too Many Requests.

Idempotency: the optional X-Idempotency-Key request header is forwarded to Stripe's session-create call. Re-submitting with the same key returns the same Checkout session instead of creating a duplicate.

Request body:

{
  "donation": { "amount": 500 },
  "customer": { "email": "donor@example.com" },
  "successUrl": "https://your-site.com/store/{SKU}?donate=success&session={CHECKOUT_SESSION_ID}",
  "cancelUrl": "https://your-site.com/store/{SKU}?donate=cancel"
}
FieldTypeDescription
donationobjectRequired. { amount } — positive integer in the donation currency's smallest unit. Validated against product.donationConfig.
customerobject (optional){ email }. Required for anonymous donors; ignored when an identified member is forwarded via the auth headers below.
successUrlstringRequired. Absolute URL to redirect to on success. Supports Stripe's {CHECKOUT_SESSION_ID} placeholder.
cancelUrlstringRequired. Absolute URL to redirect to on cancellation.

Headers (optional, member attribution): X-Cobuntu-Auth-Token (the value of the cobuntu_auth cookie) and X-Cobuntu-Member-Token (SSO) attribute the donation to a known member, matching /checkout's precedence.

Response (200):

{
  "checkoutUrl": "https://checkout.stripe.com/c/pay/…",
  "sessionId": "cs_…"
}

Common errors: 400 (INVALID_DONATION_AMOUNT, donations not configured, amount below Stripe's 50-smallest-unit minimum, amount not in the fixed-mode list, missing customer.email for anonymous donors), 404 (product not found), 429 (rate-limited).

Example:

curl -X POST \
  https://api.cobuntu.com/api/v1/communities/my-community/products/EXAMPLE_SKU/donate \
  -H "X-API-Key: pk_live_..." \
  -H "Content-Type: application/json" \
  -H "X-Idempotency-Key: $(uuidgen)" \
  -d '{
    "donation": { "amount": 500 },
    "customer": { "email": "fan@example.com" },
    "successUrl": "https://your-site.com/store/EXAMPLE_SKU?donate=success",
    "cancelUrl": "https://your-site.com/store/EXAMPLE_SKU?donate=cancel"
  }'

GET /communities/{communityTag}/products/{sku}/donations/summary — Aggregated donation totals

Mirror of the event variant (events). Returns running totals for all donations attached to this product. Requires the READ_PUBLIC scope. Anonymized at this scope.

Response (200):

{
  "total": 7800,
  "count": 12,
  "currency": "EUR"
}
FieldTypeDescription
totalintegerSum of donation amounts in the currency's smallest unit. 0 when no donations exist yet.
countintegerNumber of donation rows attached to the product.
currencystring | nullISO 4217 code. Null when no donations exist yet.

Example:

curl https://api.cobuntu.com/api/v1/communities/my-community/products/EXAMPLE_SKU/donations/summary \
  -H "X-API-Key: pk_live_..."