Billing & Credits
Endpoints for subscriptions, checkout, plan changes, invoices, and credit management.
Billing & Credits Endpoints
Technical Debt Radar supports both Stripe and PayPal for subscription billing. Credits are used for AI-powered features (scan summaries, cross-file analysis, AI fix suggestions).
Subscriptions
POST /billing/checkout
Create a Stripe checkout session. Redirects the user to Stripe's hosted payment page.
Request
curl -X POST https://api.radar.dev/v1/billing/checkout \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"orgId": "org_x1y2z3",
"planId": "pro",
"billingCycle": "annual"
}'
const response = await fetch("https://api.radar.dev/v1/billing/checkout", {
method: "POST",
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
orgId: "org_x1y2z3",
planId: "pro",
billingCycle: "annual",
}),
});
const { checkoutUrl } = await response.json();
// Redirect user to checkoutUrl
window.location.href = checkoutUrl;
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
orgId | string | Yes | Organization to subscribe |
planId | string | Yes | solo, pro, team, or enterprise |
billingCycle | string | Yes | monthly or annual |
Response 200 OK
{
"checkoutUrl": "https://checkout.stripe.com/c/pay/cs_live_..."
}
POST /billing/paypal/checkout
Create a PayPal subscription checkout. Returns an approval URL for PayPal's hosted flow.
Request
curl -X POST https://api.radar.dev/v1/billing/paypal/checkout \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"orgId": "org_x1y2z3",
"planId": "pro",
"billingCycle": "monthly"
}'
Response 200 OK
{
"approvalUrl": "https://www.paypal.com/webapps/billing/subscriptions?ba_token=..."
}
POST /billing/portal
Open a Stripe customer portal session for managing payment methods and viewing invoices.
Request
curl -X POST https://api.radar.dev/v1/billing/portal \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"orgId": "org_x1y2z3"
}'
Response 200 OK
{
"portalUrl": "https://billing.stripe.com/p/session/..."
}
GET /billing/subscription/:orgId
Get the current subscription status for an organization.
Request
curl https://api.radar.dev/v1/billing/subscription/org_x1y2z3 \
-H "Authorization: Bearer $TOKEN"
const response = await fetch(
"https://api.radar.dev/v1/billing/subscription/org_x1y2z3",
{ headers: { Authorization: `Bearer ${accessToken}` } }
);
const subscription = await response.json();
Response 200 OK
{
"planId": "pro",
"planName": "Pro",
"status": "active",
"provider": "stripe",
"billingCycle": "annual",
"currentPeriodStart": "2026-03-01T00:00:00.000Z",
"currentPeriodEnd": "2027-03-01T00:00:00.000Z",
"cancelAtPeriodEnd": false,
"priceMonthly": 49,
"priceAnnual": 468,
"limits": {
"maxRepos": -1,
"maxMembers": -1,
"aiCreditsPerMonth": 500,
"maxOrgs": 3
}
}
POST /billing/cancel
Cancel the subscription. The subscription remains active until the end of the current billing period.
Request
curl -X POST https://api.radar.dev/v1/billing/cancel \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"orgId": "org_x1y2z3"
}'
Response 200 OK
{
"status": "cancelling",
"cancelAtPeriodEnd": true,
"currentPeriodEnd": "2027-03-01T00:00:00.000Z"
}
POST /billing/reactivate
Reactivate a subscription that was cancelled but has not yet reached its period end.
Request
curl -X POST https://api.radar.dev/v1/billing/reactivate \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"orgId": "org_x1y2z3"
}'
Response 200 OK
{
"status": "active",
"cancelAtPeriodEnd": false
}
POST /billing/change-plan
Change to a different plan. Proration is applied automatically by the payment provider.
Request
curl -X POST https://api.radar.dev/v1/billing/change-plan \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"orgId": "org_x1y2z3",
"planId": "team",
"billingCycle": "annual"
}'
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
orgId | string | Yes | Organization ID |
planId | string | Yes | Target plan: solo, pro, team, or enterprise |
billingCycle | string | Yes | monthly or annual |
Response 200 OK
{
"previousPlan": "pro",
"newPlan": "team",
"effectiveImmediately": true,
"proratedAmount": 42.50
}
POST /billing/preview-change
Preview what a plan change would cost without making changes. Shows prorated amounts and new pricing.
Request
curl -X POST https://api.radar.dev/v1/billing/preview-change \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"orgId": "org_x1y2z3",
"planId": "team",
"billingCycle": "annual"
}'
Response 200 OK
{
"currentPlan": "pro",
"newPlan": "team",
"currentPrice": 468,
"newPrice": 948,
"proratedCredit": 234.00,
"amountDue": 714.00,
"billingCycle": "annual"
}
Invoices
GET /billing/invoices/:orgId
List invoices for an organization.
Request
curl "https://api.radar.dev/v1/billing/invoices/org_x1y2z3?limit=5" \
-H "Authorization: Bearer $TOKEN"
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | number | 10 | Maximum invoices to return |
Response 200 OK
[
{
"id": "inv_stripe_abc123",
"date": "2026-03-01T00:00:00.000Z",
"amount": 468.00,
"currency": "usd",
"status": "paid",
"planName": "Pro (Annual)",
"pdfUrl": "https://pay.stripe.com/invoice/acct_.../pdf"
},
{
"id": "inv_stripe_def456",
"date": "2026-02-01T00:00:00.000Z",
"amount": 49.00,
"currency": "usd",
"status": "paid",
"planName": "Pro (Monthly)",
"pdfUrl": "https://pay.stripe.com/invoice/acct_.../pdf"
}
]
Credits
AI credits are included with paid plans and consumed by AI-powered features.
| Plan | Monthly Credits |
|---|---|
| Free | 0 |
| Solo | 50 |
| Pro | 500 |
| Team | 2,000 |
| Enterprise | Unlimited |
GET /credits/org/:orgId
Get the current credit balance for an organization.
Request
curl https://api.radar.dev/v1/credits/org/org_x1y2z3 \
-H "Authorization: Bearer $TOKEN"
const response = await fetch(
"https://api.radar.dev/v1/credits/org/org_x1y2z3",
{ headers: { Authorization: `Bearer ${accessToken}` } }
);
const credits = await response.json();
Response 200 OK
{
"balance": 342,
"monthlyAllocation": 500,
"used": 158,
"resetsAt": "2026-04-01T00:00:00.000Z"
}
GET /credits/org/:orgId/transactions
List credit transactions (consumption and grants).
Request
curl "https://api.radar.dev/v1/credits/org/org_x1y2z3/transactions?limit=20&month=2026-03" \
-H "Authorization: Bearer $TOKEN"
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | number | 20 | Maximum transactions to return |
offset | number | 0 | Offset for pagination |
month | string | -- | Filter by month (YYYY-MM) |
Response 200 OK
{
"transactions": [
{
"id": "txn_abc123",
"type": "consumption",
"operation": "ai_scan_summary",
"amount": -5,
"balance": 342,
"description": "AI scan summary for acme/api#142",
"createdAt": "2026-03-18T09:15:00.000Z"
},
{
"id": "txn_def456",
"type": "consumption",
"operation": "ai_cross_file",
"amount": -12,
"balance": 347,
"description": "Cross-file analysis for acme/api#141",
"createdAt": "2026-03-17T14:22:00.000Z"
},
{
"id": "txn_ghi789",
"type": "grant",
"operation": "monthly_allocation",
"amount": 500,
"balance": 500,
"description": "Monthly credit allocation (Pro plan)",
"createdAt": "2026-03-01T00:00:00.000Z"
}
],
"total": 47
}
GET /credits/org/:orgId/usage-by-operation
Get a breakdown of credit usage by AI operation type.
Request
curl https://api.radar.dev/v1/credits/org/org_x1y2z3/usage-by-operation \
-H "Authorization: Bearer $TOKEN"
Response 200 OK
{
"operations": [
{ "operation": "ai_scan_summary", "creditsUsed": 65, "count": 13 },
{ "operation": "ai_cross_file", "creditsUsed": 48, "count": 4 },
{ "operation": "ai_fix_suggestion", "creditsUsed": 30, "count": 10 },
{ "operation": "ai_pr_comment", "creditsUsed": 15, "count": 3 }
],
"totalUsed": 158,
"period": "2026-03"
}
Plans
GET /plans
List all available plans with pricing and feature details.
Request
curl https://api.radar.dev/v1/plans
Response 200 OK
[
{
"id": "free",
"name": "Free",
"description": "For trying Radar on personal projects",
"priceMonthly": 0,
"priceAnnual": 0,
"priceMonthlyIfAnnual": 0,
"limits": {
"maxRepos": 2,
"maxMembers": 1,
"aiCreditsPerMonth": 0,
"maxOrgs": 1
},
"features": {
"cliScan": true,
"prGate": false,
"dashboard": true,
"architectureGraph": false,
"aiCrossFile": false
}
}
]
GET /plans/:planId
Get details for a specific plan.
curl https://api.radar.dev/v1/plans/pro
GET /plans/org/:orgId/usage
Get plan usage statistics for an organization (repos used, members count, credits consumed).
curl https://api.radar.dev/v1/plans/org/org_x1y2z3/usage \
-H "Authorization: Bearer $TOKEN"
GET /plans/org/:orgId/can-use/:feature
Check whether an organization's current plan allows a specific feature.
curl https://api.radar.dev/v1/plans/org/org_x1y2z3/can-use/architectureGraph \
-H "Authorization: Bearer $TOKEN"
Response 200 OK
{
"allowed": true,
"currentPlan": "pro"
}
GET /plans/org/:orgId/enforcement
Get the enforcement summary showing which features and limits are active.
curl https://api.radar.dev/v1/plans/org/org_x1y2z3/enforcement \
-H "Authorization: Bearer $TOKEN"