Billing
Manage your team's subscription, view available plans, check your SMS credit balance, and access the Stripe billing portal for payment management.
Pricing model
Email is included up to your plan's daily limit. SMS uses a dollar-denominated monthly credit bundle: each send is debited at the destination's zone rate (Zone 1 $0.02 — US/CA, Zone 2 $0.08 — standard markets, Zone 3 $0.25 — premium). When the bundle is exhausted, further sends bill via Stripe Billing Meters at the same per-zone rate. See SMS pricing zones for the full rate card.
List plans
/v1/billing/plansList all available plans with pricing, daily limits, and SMS bundle. Indicates which plan the team is currently on.
{
"data": [
{
"name": "Free",
"plan": "free",
"monthlyPrice": 0,
"dailyEmailLimit": 100,
"dailySmsLimit": 0,
"monthlySmsCreditCents": 0,
"current": true
},
{
"name": "Pro",
"plan": "pro",
"monthlyPrice": 29,
"dailyEmailLimit": 5000,
"dailySmsLimit": 10000,
"monthlySmsCreditCents": 200,
"current": false
},
{
"name": "Scale",
"plan": "scale",
"monthlyPrice": 99,
"dailyEmailLimit": 20000,
"dailySmsLimit": 100000,
"monthlySmsCreditCents": 2000,
"current": false
},
{
"name": "Enterprise",
"plan": "enterprise",
"monthlyPrice": 499,
"dailyEmailLimit": 100000,
"dailySmsLimit": 500000,
"monthlySmsCreditCents": 8000,
"current": false
}
]
}monthlySmsCreditCentsis the bundle size in cents (AUD). For example, Pro's 200 = $2.00, which covers roughly 25 sends to Australia (Zone 2 at $0.08) or 100 sends to the US (Zone 1 at $0.02).
Get subscription
/v1/billing/subscriptionGet the current team's subscription details including plan, status, billing period, and SMS credit balance.
{
"plan": "pro",
"status": "active",
"stripeSubscriptionId": "sub_1234567890",
"currentPeriodStart": "2026-04-21T00:00:00Z",
"currentPeriodEnd": "2026-05-21T00:00:00Z",
"cancelAtPeriodEnd": false,
"smsCreditCentsRemaining": 144,
"monthlySmsCreditCents": 200
}smsCreditCentsRemaining resets to monthlySmsCreditCents at the start of each billing period (when Stripe fires invoice.payment_succeeded). Unused credit does not roll over.
Create checkout session
/v1/billing/checkoutCreate a Stripe Checkout session to subscribe to a paid plan. Returns a URL to redirect the user to.
Request body
| Parameter | Type | Description |
|---|---|---|
planrequired | string | Target plan: 'pro', 'scale', or 'enterprise'. |
curl -X POST https://api.txtly.com.au/v1/billing/checkout \
-H "Authorization: Bearer tx_your_api_key" \
-H "Content-Type: application/json" \
-d '{"plan": "pro"}'{
"url": "https://checkout.stripe.com/c/pay/cs_..."
}The Checkout session attaches the base plan price plus three metered line items — one per SMS pricing zone. Metered items don't bill at checkout; they accumulate usage over the billing period via Stripe Billing Meters and bill at invoice time.
Create billing portal session
/v1/billing/portalCreate a Stripe Billing Portal session for self-service subscription management (upgrade, downgrade, cancel, payment method updates).
Request body
| Parameter | Type | Description |
|---|---|---|
returnUrl | string | URL to redirect back to after leaving the portal. Defaults to the dashboard settings page. |
{
"url": "https://billing.stripe.com/p/session/..."
}Webhook
/v1/webhooks/stripeStripe webhook endpoint. Configure this URL in your Stripe Dashboard webhook settings; signature verification is enforced via Stripe-Signature header.
The webhook handles these Stripe events to keep your team's plan + SMS credit in sync:
| Parameter | Type | Description |
|---|---|---|
checkout.session.completed | event | Activates the subscription, upgrades the plan, anchors the period start, and refills the SMS credit bundle to the plan default. |
customer.subscription.updated | event | Syncs plan changes when the subscription is upgraded, downgraded, or set to cancel at period end. |
customer.subscription.deleted | event | Reverts the team to the Free plan and zeroes the SMS credit balance when the subscription is fully cancelled. |
invoice.payment_succeeded | event | Refills the SMS credit bundle to the plan default at the start of each billing period. |
invoice.payment_failed | event | Logged for monitoring. Stripe retries automatically; on final failure, subscription.deleted fires. |
Configuration
Set these environment variables to enable Stripe billing. In production these are sourced from AWS Secrets Manager (txtly/stripe).
| Parameter | Type | Description |
|---|---|---|
Stripe__SecretKeyrequired | string | Stripe secret API key (sk_live_... or sk_test_...). |
Stripe__WebhookSecretrequired | string | Webhook signing secret from Stripe (whsec_...). |
Stripe__Prices__Prorequired | string | Stripe Price ID for the Pro plan base subscription. |
Stripe__Prices__Scalerequired | string | Stripe Price ID for the Scale plan base subscription. |
Stripe__Prices__Enterpriserequired | string | Stripe Price ID for the Enterprise plan base subscription. |
Stripe__Prices__SmsZone1Overagerequired | string | Stripe metered Price ID linked to the Zone 1 (US/CA) Billing Meter (event_name: sms_zone1_send). |
Stripe__Prices__SmsZone2Overagerequired | string | Stripe metered Price ID linked to the Zone 2 (Standard) Billing Meter (event_name: sms_zone2_send). |
Stripe__Prices__SmsZone3Overagerequired | string | Stripe metered Price ID linked to the Zone 3 (Premium) Billing Meter (event_name: sms_zone3_send). |
Dashboard__Url | string | Dashboard base URL for checkout redirect. Defaults to http://localhost:3000. |