All documentation

Reseller API

Use one normal SP Cambo package catalogue. Paid packages bought by an active reseller become reseller inventory automatically; the reseller then sells part of a package to managed customers.

Current flow

  1. Active reseller buys a normal SP Cambo package.
  2. The paid package automatically becomes RESELLER_STOCK.
  3. GET /inventory returns one row per package lot.
  4. Sell from that exact package with inventory_lot_id.
  5. The customer's allocation inherits all models included in that package.
  6. The allocation is one shared balance across those models, not one balance per model.
  7. Issue the customer an sk- inference key scoped to the funded models.
Keep the management key server-side
An sk-spm- management key controls customers, allocations and keys. Never put it in browser JavaScript, a public repository or a mobile app.

Credentials

  • sk-spm-... — reseller management API only.
  • sk-... — customer inference API only.
  • A signed-in browser session manages the reseller's own management keys.

1. Check reseller inventory

Requires allocations:read. Each returned row is one real package lot and contains allowed_model_aliases, remaining units and expiry.

bash
curl "https://sp-cambo.store/api/v1/reseller-management/inventory" \
  -H "Authorization: Bearer sk-spm-your-management-key" \
  -H "Accept: application/json"

2. List customers

bash
curl "https://sp-cambo.store/api/v1/reseller-management/customers" \
  -H "Authorization: Bearer sk-spm-your-management-key" \
  -H "Accept: application/json"

3. Create a customer

Requires customers:write.

bash
curl -X POST "https://sp-cambo.store/api/v1/reseller-management/customers" \
  -H "Authorization: Bearer sk-spm-your-management-key" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Demo Customer",
    "email": "customer@example.com",
    "label": "API customer",
    "password": "ChangeMe123!Strong",
    "password_confirmation": "ChangeMe123!Strong"
  }'

4. Sell package quota

Requires allocations:write. Use the exact id returned by GET /inventory. Do not select one model here.

bash
curl -X POST "https://sp-cambo.store/api/v1/reseller-management/customers/4/allocations" \
  -H "Authorization: Bearer sk-spm-your-management-key" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "inventory_lot_id": "01EXAMPLE_RESELLER_LOT",
    "units": 1000000,
    "idempotency_key": "seller-order-10001",
    "reason": "Customer purchased one million package tokens."
  }'

If a Claude package contains 9 Claude aliases and you sell 1,000,000 units, the customer gets one 1,000,000-unit shared balance usable across those 9 aliases.

5. Check sales history and remaining customer balance

Requires allocations:read. Package sales return their model scope and current customer_balance, including original, remaining, used, reserved, status and expiry.

bash
curl "https://sp-cambo.store/api/v1/reseller-management/customers/4/allocations?limit=50" \
  -H "Authorization: Bearer sk-spm-your-management-key" \
  -H "Accept: application/json"

6. Issue customer inference key

Requires keys:write. Send the model aliases funded for that customer. The secret is returned on creation; store/deliver it securely.

bash
curl -X POST "https://sp-cambo.store/api/v1/reseller-management/customers/4/api-keys" \
  -H "Authorization: Bearer sk-spm-your-management-key" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "label": "Customer production API",
    "allowed_model_aliases": [
      "claude-sonnet-5",
      "claude-haiku-4-5"
    ]
  }'

7. Check customer key

bash
curl -X POST "https://sp-cambo.store/api/v1/keys/check" \
  -H "Content-Type: application/json" \
  -d '{
    "api_key": "sk-your-customer-key"
  }'

8. Make an inference request

The customer sk- key calls the inference gateway. The sk-spm- management key cannot make model requests.

bash
curl -X POST "https://sp-cambo.store/v1/messages" \
  -H "x-api-key: sk-your-customer-key" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-sonnet-5",
    "max_tokens": 100,
    "messages": [
      {
        "role": "user",
        "content": "Say hello from SP Cambo reseller API."
      }
    ]
  }'

Optional management operations

Revoke a customer key

bash
curl -X POST "https://sp-cambo.store/api/v1/reseller-management/customers/4/api-keys/KEY_ID/revoke" \
  -H "Authorization: Bearer sk-spm-your-management-key" \
  -H "Accept: application/json"

Suspend a managed customer

bash
curl -X PATCH "https://sp-cambo.store/api/v1/reseller-management/customers/4/status" \
  -H "Authorization: Bearer sk-spm-your-management-key" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "SUSPENDED",
    "reason": "Customer requested a temporary suspension."
  }'

What remains intentionally available

  • GET /customers/{id}/usage remains available for reseller automation/reporting even though the website customer page no longer shows the usage block.
  • The old single-model allocation format remains accepted for backward compatibility, but new integrations should use inventory_lot_id.
  • Admin/manual stock-grant tools remain available for support and recovery; normal reseller purchases do not need them.

Important behavior

  • Paid package units become reseller stock automatically for an active reseller.
  • Promotion, referral, redeem-code and Playground balances do not become reseller stock.
  • Package allocations inherit the source package expiry.
  • Allocation is idempotent; reuse the same idempotency key only when retrying the same sale.
  • There is no automatic un-allocation/refund route after quota has been transferred.