MisarMisar Docs
MisarMailMisar.BlogMisarReachMisarPostMisar.DevMisarSEOMisar PlatformMisar SSO
API Reference

Billing API

Read subscription/usage/plan data and create Stripe checkout & billing-portal sessions — api.misar.io/reach/api/billing.

Reach's plan catalog lives in the shared subscription_plans table (product='reach'), independent of any MisarMail subscription — see Cross-Product Contracts. The credits wallet is shared with MisarMail.

Base URL: https://api.misar.io/reach

Get subscription

GET/api/billing/subscription

Returns the authenticated user's product='reach' subscription row, joined with plan name/pricing.

curl "https://api.misar.io/reach/api/billing/subscription" \
  -H "Authorization: Bearer msr_your_key_here"
{
  "success": true,
  "subscription": {
    "planSlug": "pro", "planName": "Pro", "priceMonthly": 79, "priceYearly": null,
    "status": "active", "renewalDate": "2026-08-11T00:00:00Z", "cancelAtPeriodEnd": false,
    "hasStripeSubscription": true, "hasStripeCustomer": true,
    "isTrialing": false, "trialDaysRemaining": null, "trialEndAt": null, "trialPlanSlug": null
  }
}

Get usage

GET/api/billing/usage

Reach's primary metered resource is leads found this billing period (not emails — contrast with MisarMail's equivalent route). Sourced from lead_finder_usage via the get_lead_usage RPC.

leadsLimit is null (unlimited/unset) until per-plan numeric lead caps are configured on the product='reach' subscription_plans rows — today those limits only exist as description text (e.g. "5,000 leads/month"), not a structured column the API can enforce/compare against.

curl "https://api.misar.io/reach/api/billing/usage" \
  -H "Authorization: Bearer msr_your_key_here"
{ "success": true, "leadsUsed": 1240, "leadsLimit": 5000, "periodStart": "2026-07-01" }

List plans

GET/api/billing/plans

Returns the active product='reach' rows from subscription_plans, ordered by sort_order — the same data source the /pricing page and Settings → Billing tab render from.

curl "https://api.misar.io/reach/api/billing/plans"
{ "success": true, "plans": [{ "id": "free", "name": "Free", "monthlyPrice": 0, "priceDisplay": "Free", "features": ["1 active channel (email via mail plan)", "50 leads/month", "1 sequence", "Basic CRM pipeline"], "cta": { "label": "Get started", "href": "/signup" } }] }

Wallet balance

GET/api/billing/wallet/balance

Returns the shared Misar wallet credit balance (1 credit = $1). See Wallet — Central API.

{ "success": true, "credits": 42 }

Create checkout session

POST/api/billing/checkout

Creates a Stripe Checkout session to subscribe/upgrade to a paid reach plan.

Body parameters

planSlugstringrequired

One of "starter" | "pro" | "business".

billingPeriodstring

"monthly" (default) or "yearly".

Returns 503 { error: "Plan pricing not configured" } for any plan whose subscription_plans.stripe_price_id is unset. As of this writing, no reach plan has a Stripe price ID configured yet — that's a separate, pending operational task (creating the reach Stripe product catalog), not a bug in this endpoint.

curl -X POST "https://api.misar.io/reach/api/billing/checkout" \
  -H "Authorization: Bearer msr_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "planSlug": "pro" }'
{ "success": true, "url": "https://checkout.stripe.com/c/pay/..." }

Create billing-portal session

POST/api/billing/portal

Creates a Stripe billing-portal session for managing payment method / invoices / cancellation. Auto-creates a Stripe customer on first call if none exists yet.

{ "success": true, "url": "https://billing.stripe.com/session/..." }