TBBNMerchantDocs
Available

Billing

post/v1/billing/subscriptions

Create a Business's SaaS subscription

curl -X POST https://api.tbbnetwork.com/v1/billing/subscriptions \
  -H "Authorization: Bearer <session access token>" \
  -H "Idempotency-Key: 5f2f...b91" \
  -H "Content-Type: application/json" \
  -d '{
  "businessId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
  "billingEmail": "you@example.com",
  "tier": "SANDBOX"
}'

Parameters

Request body

FieldTypeRequired
businessIdstring (uuid)yes
billingEmailstring (email)—
tierSANDBOX | STARTER | GROWTH | ENTERPRISE | PAY_AS_YOU_GOyes

Response (201)

FieldTypeRequired
idstring (uuid)—
businessIdstring (uuid)—
tierSANDBOX | STARTER | GROWTH | ENTERPRISE | PAY_AS_YOU_GO—
stripeSubscriptionIdstringnull—
stripeCustomerIdstringnull—
statusstring—
currentPeriodStartstring,null (date-time)—
currentPeriodEndstring,null (date-time)—
stripePaymentMethodIdstringnull—
paymentMethodSetupAtstring,null (date-time)—
lastWeeklyChargeAtstring,null (date-time)—
waivedUntilstring,null (date-time)—
waivedReasonstringnull—
Example 201 response
{
  "id": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
  "businessId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
  "tier": "SANDBOX",
  "stripeSubscriptionId": null,
  "stripeCustomerId": null,
  "status": "status",
  "currentPeriodStart": "2026-07-01T12:00:00Z",
  "currentPeriodEnd": "2026-07-01T12:00:00Z",
  "stripePaymentMethodId": null,
  "paymentMethodSetupAt": "2026-07-01T12:00:00Z",
  "lastWeeklyChargeAt": "2026-07-01T12:00:00Z",
  "waivedUntil": "2026-07-01T12:00:00Z",
  "waivedReason": null
}

Possible errors

Any other failure (validation, auth, rate limiting, a resource that doesn't exist) returns this same envelope with a non-2xx status — error.code is stable and safe to branch on; error.requestId is worth logging and including in a support request.

Example error response
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "A human-readable description of what went wrong.",
    "requestId": "req_01hxyz..."
  }
}
get/v1/billing/subscriptions/{businessId}

Get a Business's current active SaaS subscription

curl -X GET https://api.tbbnetwork.com/v1/billing/subscriptions/{businessId} \
  -H "Authorization: Bearer <session access token>" \

Parameters

businessIdpathrequired

Response (200)

FieldTypeRequired
idstring (uuid)—
businessIdstring (uuid)—
tierSANDBOX | STARTER | GROWTH | ENTERPRISE | PAY_AS_YOU_GO—
stripeSubscriptionIdstringnull—
stripeCustomerIdstringnull—
statusstring—
currentPeriodStartstring,null (date-time)—
currentPeriodEndstring,null (date-time)—
stripePaymentMethodIdstringnull—
paymentMethodSetupAtstring,null (date-time)—
lastWeeklyChargeAtstring,null (date-time)—
waivedUntilstring,null (date-time)—
waivedReasonstringnull—
Example 200 response
{
  "id": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
  "businessId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
  "tier": "SANDBOX",
  "stripeSubscriptionId": null,
  "stripeCustomerId": null,
  "status": "status",
  "currentPeriodStart": "2026-07-01T12:00:00Z",
  "currentPeriodEnd": "2026-07-01T12:00:00Z",
  "stripePaymentMethodId": null,
  "paymentMethodSetupAt": "2026-07-01T12:00:00Z",
  "lastWeeklyChargeAt": "2026-07-01T12:00:00Z",
  "waivedUntil": "2026-07-01T12:00:00Z",
  "waivedReason": null
}

Possible errors

Any other failure (validation, auth, rate limiting, a resource that doesn't exist) returns this same envelope with a non-2xx status — error.code is stable and safe to branch on; error.requestId is worth logging and including in a support request.

Example error response
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "A human-readable description of what went wrong.",
    "requestId": "req_01hxyz..."
  }
}
post/v1/billing/subscriptions/{businessId}/change-tier

Change a Business's subscription tier

curl -X POST https://api.tbbnetwork.com/v1/billing/subscriptions/{businessId}/change-tier \
  -H "Authorization: Bearer <session access token>" \
  -H "Idempotency-Key: 5f2f...b91" \
  -H "Content-Type: application/json" \
  -d '{
  "tier": "SANDBOX"
}'

Parameters

businessIdpathrequired

Request body

FieldTypeRequired
tierSANDBOX | STARTER | GROWTH | ENTERPRISE | PAY_AS_YOU_GOyes

Response (201)

FieldTypeRequired
idstring (uuid)—
businessIdstring (uuid)—
tierSANDBOX | STARTER | GROWTH | ENTERPRISE | PAY_AS_YOU_GO—
stripeSubscriptionIdstringnull—
stripeCustomerIdstringnull—
statusstring—
currentPeriodStartstring,null (date-time)—
currentPeriodEndstring,null (date-time)—
stripePaymentMethodIdstringnull—
paymentMethodSetupAtstring,null (date-time)—
lastWeeklyChargeAtstring,null (date-time)—
waivedUntilstring,null (date-time)—
waivedReasonstringnull—
Example 201 response
{
  "id": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
  "businessId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
  "tier": "SANDBOX",
  "stripeSubscriptionId": null,
  "stripeCustomerId": null,
  "status": "status",
  "currentPeriodStart": "2026-07-01T12:00:00Z",
  "currentPeriodEnd": "2026-07-01T12:00:00Z",
  "stripePaymentMethodId": null,
  "paymentMethodSetupAt": "2026-07-01T12:00:00Z",
  "lastWeeklyChargeAt": "2026-07-01T12:00:00Z",
  "waivedUntil": "2026-07-01T12:00:00Z",
  "waivedReason": null
}

Possible errors

Any other failure (validation, auth, rate limiting, a resource that doesn't exist) returns this same envelope with a non-2xx status — error.code is stable and safe to branch on; error.requestId is worth logging and including in a support request.

Example error response
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "A human-readable description of what went wrong.",
    "requestId": "req_01hxyz..."
  }
}
post/v1/billing/subscriptions/{businessId}/cancel

Cancel a Business's subscription

curl -X POST https://api.tbbnetwork.com/v1/billing/subscriptions/{businessId}/cancel \
  -H "Authorization: Bearer <session access token>" \
  -H "Idempotency-Key: 5f2f...b91" \

Parameters

businessIdpathrequired

Response (201)

FieldTypeRequired
idstring (uuid)—
businessIdstring (uuid)—
tierSANDBOX | STARTER | GROWTH | ENTERPRISE | PAY_AS_YOU_GO—
stripeSubscriptionIdstringnull—
stripeCustomerIdstringnull—
statusstring—
currentPeriodStartstring,null (date-time)—
currentPeriodEndstring,null (date-time)—
stripePaymentMethodIdstringnull—
paymentMethodSetupAtstring,null (date-time)—
lastWeeklyChargeAtstring,null (date-time)—
waivedUntilstring,null (date-time)—
waivedReasonstringnull—
Example 201 response
{
  "id": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
  "businessId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
  "tier": "SANDBOX",
  "stripeSubscriptionId": null,
  "stripeCustomerId": null,
  "status": "status",
  "currentPeriodStart": "2026-07-01T12:00:00Z",
  "currentPeriodEnd": "2026-07-01T12:00:00Z",
  "stripePaymentMethodId": null,
  "paymentMethodSetupAt": "2026-07-01T12:00:00Z",
  "lastWeeklyChargeAt": "2026-07-01T12:00:00Z",
  "waivedUntil": "2026-07-01T12:00:00Z",
  "waivedReason": null
}

Possible errors

Any other failure (validation, auth, rate limiting, a resource that doesn't exist) returns this same envelope with a non-2xx status — error.code is stable and safe to branch on; error.requestId is worth logging and including in a support request.

Example error response
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "A human-readable description of what went wrong.",
    "requestId": "req_01hxyz..."
  }
}
post/v1/billing/subscriptions/{businessId}/confirm-payment-method

Pay-As-You-Go card capture, step 2 — save the payment method Stripe.js resolved the SetupIntent to

curl -X POST https://api.tbbnetwork.com/v1/billing/subscriptions/{businessId}/confirm-payment-method \
  -H "Authorization: Bearer <session access token>" \
  -H "Idempotency-Key: 5f2f...b91" \
  -H "Content-Type: application/json" \
  -d '{
  "stripePaymentMethodId": "stripePaymentMethodId"
}'

Parameters

businessIdpathrequired

Request body

FieldTypeRequired
stripePaymentMethodIdstringyes

Response (201)

FieldTypeRequired
idstring (uuid)—
businessIdstring (uuid)—
tierSANDBOX | STARTER | GROWTH | ENTERPRISE | PAY_AS_YOU_GO—
stripeSubscriptionIdstringnull—
stripeCustomerIdstringnull—
statusstring—
currentPeriodStartstring,null (date-time)—
currentPeriodEndstring,null (date-time)—
stripePaymentMethodIdstringnull—
paymentMethodSetupAtstring,null (date-time)—
lastWeeklyChargeAtstring,null (date-time)—
waivedUntilstring,null (date-time)—
waivedReasonstringnull—
Example 201 response
{
  "id": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
  "businessId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
  "tier": "SANDBOX",
  "stripeSubscriptionId": null,
  "stripeCustomerId": null,
  "status": "status",
  "currentPeriodStart": "2026-07-01T12:00:00Z",
  "currentPeriodEnd": "2026-07-01T12:00:00Z",
  "stripePaymentMethodId": null,
  "paymentMethodSetupAt": "2026-07-01T12:00:00Z",
  "lastWeeklyChargeAt": "2026-07-01T12:00:00Z",
  "waivedUntil": "2026-07-01T12:00:00Z",
  "waivedReason": null
}

Possible errors

Any other failure (validation, auth, rate limiting, a resource that doesn't exist) returns this same envelope with a non-2xx status — error.code is stable and safe to branch on; error.requestId is worth logging and including in a support request.

Example error response
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "A human-readable description of what went wrong.",
    "requestId": "req_01hxyz..."
  }
}
get/v1/billing/pricing/{businessId}

What TBBN charges this Business, in its billing currency

curl -X GET https://api.tbbnetwork.com/v1/billing/pricing/{businessId} \
  -H "Authorization: Bearer <session access token>" \

Parameters

businessIdpathrequired

Response (200)

FieldTypeRequired
countrystringnull—
currencystring—
localboolean—
currencyFixedboolean—
pricesobject—
Example 200 response
{
  "country": null,
  "currency": "USD",
  "local": false,
  "currencyFixed": false,
  "prices": null
}

Possible errors

Any other failure (validation, auth, rate limiting, a resource that doesn't exist) returns this same envelope with a non-2xx status — error.code is stable and safe to branch on; error.requestId is worth logging and including in a support request.

Example error response
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "A human-readable description of what went wrong.",
    "requestId": "req_01hxyz..."
  }
}
get/v1/billing/merchant/summary

Your Merchant's plan — its Business's — and this period's usage: for each service, your own count (rawCount), your Business's total across its Merchants (businessCount, what the allowance is measured against) and the plan's allowance (included; null means unlimited). Works with an API key or a merchant dashboard session whose role can see billing or analytics. Without a paid plan, the tier is SANDBOX and the period is the calendar month.

curl -X GET https://api.tbbnetwork.com/v1/billing/merchant/summary \
  -H "Authorization: Bearer sk_sandbox_..." \

Response (200)

FieldTypeRequired
merchantIdstring (uuid)—
businessIdstring,null (uuid)—
businessNamestringnull—
currencystring—
tierSANDBOX | STARTER | GROWTH | PAY_AS_YOU_GO | ENTERPRISE—
billingIntervalMONTH | YEAR | —
statusstringnull—
basePriceUsdnumbernull—
windowStartstring (date-time)—
windowEndstring (date-time)—
lineItemsobject[]—
Example 200 response
{
  "merchantId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
  "businessId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
  "businessName": null,
  "currency": "USD",
  "tier": "SANDBOX",
  "billingInterval": "MONTH",
  "status": null,
  "basePriceUsd": null,
  "windowStart": "2026-07-01T12:00:00Z",
  "windowEnd": "2026-07-01T12:00:00Z",
  "lineItems": [
    {
      "eventType": "eventType",
      "rawCount": 1,
      "businessCount": 1,
      "included": null,
      "overageCost": 1
    }
  ]
}

Possible errors

Any other failure (validation, auth, rate limiting, a resource that doesn't exist) returns this same envelope with a non-2xx status — error.code is stable and safe to branch on; error.requestId is worth logging and including in a support request.

Example error response
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "A human-readable description of what went wrong.",
    "requestId": "req_01hxyz..."
  }
}
get/v1/billing/usage/{businessId}

A Business's current (or specified) billing-period metered usage, aggregated across every Merchant linked to it, including the cross-merchant multiplier breakdown and priced overage per event type. See the Pricing reference.

curl -X GET https://api.tbbnetwork.com/v1/billing/usage/{businessId} \
  -H "Authorization: Bearer <session access token>" \

Parameters

businessIdpathrequired
billingPeriodRefqueryoptional

Response (200)

FieldTypeRequired
businessIdstring (uuid)—
merchantIdsstring[]—
tierSANDBOX | STARTER | GROWTH | ENTERPRISE | PAY_AS_YOU_GO—
billingPeriodRefstring—
basePriceUsdnumbernull—
lineItemsobject[]—
totalOverageUsdnumber—
waivedboolean—
waivedUntilstring,null (date-time)—
amountDueUsdnumber—
Example 200 response
{
  "businessId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
  "merchantIds": [
    "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d"
  ],
  "tier": "SANDBOX",
  "billingPeriodRef": "billingPeriodRef",
  "basePriceUsd": null,
  "lineItems": [
    {
      "eventType": "LISTING_SYNC",
      "rawCount": 1,
      "meteredUnits": 1,
      "included": null,
      "overageUnits": 1,
      "overageCost": 1
    }
  ],
  "totalOverageUsd": 1,
  "waived": false,
  "waivedUntil": "2026-07-01T12:00:00Z",
  "amountDueUsd": 1
}

Possible errors

Any other failure (validation, auth, rate limiting, a resource that doesn't exist) returns this same envelope with a non-2xx status — error.code is stable and safe to branch on; error.requestId is worth logging and including in a support request.

Example error response
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "A human-readable description of what went wrong.",
    "requestId": "req_01hxyz..."
  }
}
get/v1/billing/invoices/{businessId}

A Business's invoices

curl -X GET https://api.tbbnetwork.com/v1/billing/invoices/{businessId} \
  -H "Authorization: Bearer <session access token>" \

Parameters

businessIdpathrequired
statusqueryoptional
kindqueryoptional
fromqueryoptional
toqueryoptional
cursorqueryoptional
limitqueryoptional

Possible errors

Any other failure (validation, auth, rate limiting, a resource that doesn't exist) returns this same envelope with a non-2xx status — error.code is stable and safe to branch on; error.requestId is worth logging and including in a support request.

Example error response
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "A human-readable description of what went wrong.",
    "requestId": "req_01hxyz..."
  }
}
get/v1/billing/statements/{businessId}

Consolidated Business billing statement — merchantPlan (owed) and spaceEarnings (already paid out, net of commission) as two separate sections, never merged into one number.

curl -X GET https://api.tbbnetwork.com/v1/billing/statements/{businessId} \
  -H "Authorization: Bearer <session access token>" \

Parameters

businessIdpathrequired
billingPeriodRefqueryoptional

Response (200)

FieldTypeRequired
businessIdstring (uuid)—
merchantPlanUsageSummary—
spaceEarningsobject—
Example 200 response
{
  "businessId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
  "merchantPlan": {
    "businessId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
    "merchantIds": [
      "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d"
    ],
    "tier": "SANDBOX",
    "billingPeriodRef": "billingPeriodRef",
    "basePriceUsd": null,
    "lineItems": [
      {
        "eventType": "LISTING_SYNC",
        "rawCount": 1,
        "meteredUnits": 1,
        "included": null,
        "overageUnits": 1,
        "overageCost": 1
      }
    ],
    "totalOverageUsd": 1,
    "waived": false,
    "waivedUntil": "2026-07-01T12:00:00Z",
    "amountDueUsd": 1
  },
  "spaceEarnings": {
    "currency": "USD",
    "totalPaidOut": 1,
    "byBranch": [
      {
        "branchId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
        "branchName": "branchName",
        "totalPaidOut": 1,
        "payoutCount": 1
      }
    ]
  }
}

Possible errors

Any other failure (validation, auth, rate limiting, a resource that doesn't exist) returns this same envelope with a non-2xx status — error.code is stable and safe to branch on; error.requestId is worth logging and including in a support request.

Example error response
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "A human-readable description of what went wrong.",
    "requestId": "req_01hxyz..."
  }
}