Billing
Stripe Connect onboarding, SaaS subscription plans, and invoices
POST /billing/connect/onboard Create (or reuse) the org's Stripe connected account and return an onboarding link
#51 driver→CPO direct-charge opt-in. Creates an Express connected account for the org (the CPO stays merchant-of-record for driver payments), persists it, and returns a Stripe onboarding link. Idempotent — a repeat call reuses the existing account and mints a fresh link. Owner/admin only.
Responses
200 Onboarding link + current charges-enabled status
401 Missing or invalid API key application/problem+json
403 Authenticated but not authorized for this action (insufficient role) application/problem+json
Request example
curl -X POST "https://api.ampr.dev/v1/billing/connect/onboard" \
-H "Authorization: Bearer $AMPR_API_KEY"
const res = await fetch('https://api.ampr.dev/v1/billing/connect/onboard', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.AMPR_API_KEY}`,
},
});
const data = await res.json();
This endpoint requires an API key. Send it as a Bearer token in the Authorization header.
GET /billing/connect/status Read the org's connected-account charges-enabled status (the settlement gate)
Responses
401 Missing or invalid API key application/problem+json
403 Authenticated but not authorized for this action (insufficient role) application/problem+json
Request example
curl -X GET "https://api.ampr.dev/v1/billing/connect/status" \
-H "Authorization: Bearer $AMPR_API_KEY"
const res = await fetch('https://api.ampr.dev/v1/billing/connect/status', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.AMPR_API_KEY}`,
},
});
const data = await res.json();
This endpoint requires an API key. Send it as a Bearer token in the Authorization header.
POST /billing/setup-intent Create (or reuse) the org's Stripe Customer and return a SetupIntent secret
#52 SaaS billing. Creates a Stripe Customer on Ampr's platform account (Ampr is merchant-of-record for its subscription revenue), persists the customer id on the org, and returns a SetupIntent client secret so the org can attach a card off-session. Idempotent on the Customer. Owner/admin only.
Responses
200 SetupIntent client secret + customer id
401 Missing or invalid API key application/problem+json
403 Authenticated but not authorized for this action (insufficient role) application/problem+json
Request example
curl -X POST "https://api.ampr.dev/v1/billing/setup-intent" \
-H "Authorization: Bearer $AMPR_API_KEY"
const res = await fetch('https://api.ampr.dev/v1/billing/setup-intent', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.AMPR_API_KEY}`,
},
});
const data = await res.json();
This endpoint requires an API key. Send it as a Bearer token in the Authorization header.
PATCH /billing/plan Change the org's plan (creates/cancels the Stripe subscription)
#52 SaaS billing. `sandbox` is free (no subscription); `growth` and `enterprise` create a subscription with a base price plus a metered per-socket component. A move to a paid tier REQUIRES an attached payment method (a completed SetupIntent) — otherwise the request is rejected with 422 pointing to POST /v1/billing/setup-intent and the plan is not advanced. The plan advances only once the subscription is confirmed active. A move to `sandbox` cancels the subscription. Owner/admin only.
Request body
Responses
400 Invalid request parameters application/problem+json
401 Missing or invalid API key application/problem+json
403 Authenticated but not authorized for this action (insufficient role) application/problem+json
422 Request understood but cannot be processed (e.g., invalid state) application/problem+json
Request example
curl -X PATCH "https://api.ampr.dev/v1/billing/plan" \
-H "Authorization: Bearer $AMPR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"plan": "sandbox"
}'
const res = await fetch('https://api.ampr.dev/v1/billing/plan', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.AMPR_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"plan": "sandbox"
}),
});
const data = await res.json();
This endpoint requires an API key. Send it as a Bearer token in the Authorization header.
GET /billing/invoices List the org's SaaS invoices
Responses
200 Invoice list (amount in minor units, status, period, currency)
401 Missing or invalid API key application/problem+json
403 Authenticated but not authorized for this action (insufficient role) application/problem+json
Request example
curl -X GET "https://api.ampr.dev/v1/billing/invoices" \
-H "Authorization: Bearer $AMPR_API_KEY"
const res = await fetch('https://api.ampr.dev/v1/billing/invoices', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.AMPR_API_KEY}`,
},
});
const data = await res.json();
This endpoint requires an API key. Send it as a Bearer token in the Authorization header.