Billing API
Drei Endpunkte erlauben es Agenten und Integrationen, mit dem Abrechnungsstatus zu arbeiten, den Ihr Dashboard verwaltet.
Alle Endpunkte erfordern einen Bearer-API-Key (siehe Authentifizierung).
GET /me/billing/state
Gibt eine Momentaufnahme des Abonnements Ihres Tenants zurück.
curl https://api.saiku.bi/me/billing/state \ -H "Authorization: Bearer $SAIKU_API_KEY"Antwort:
{ "tenantId": "81e301f2-…", "tier": "team", "stripeCustomerId": "cus_…", "subscriptionStatus": "active", "currentPeriodEnd": "2026-06-23T00:00:00Z", "trialEndsAt": null, "billedFeaturesActive": true}Felder:
tier—starter,team,businessoderenterprise.subscriptionStatus— der Status von Stripe wortwörtlich. Die Werte, die Sie in der Praxis sehen, sindtrialing,active,past_due,unpaid,canceledoder leer (free / pre-billing).currentPeriodEnd— wann Ihre aktuelle Abrechnungsperiode endet. Bei aktivem Abo erfolgt zu diesem Zeitpunkt die Verlängerung.trialEndsAt— nur gesetzt, solangesubscriptionStatus = trialing.billedFeaturesActive—true, solange Sie Zugriff auf abgerechnete Features haben. Andernfallsfalse. Verwenden Sie dies, um Ihr eigenes UI zu gaten.
POST /me/billing/checkout-session
Erzeugt eine einmalige URL zum von Stripe gehosteten Checkout, um eine Testphase zu starten oder einen Plan zu abonnieren.
curl -X POST https://api.saiku.bi/me/billing/checkout-session \ -H "Authorization: Bearer $SAIKU_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "tier": "team", "email": "alice@acme.com", "name": "Acme Corp", "successUrl": "https://app.acme.com/billing/success", "cancelUrl": "https://app.acme.com/billing/cancel" }'Antwort:
{ "url": "https://checkout.stripe.com/c/pay/cs_test_a1…", "sessionId": "cs_test_a1…"}Senden Sie den Browser des Benutzers per 303-Redirect an url. Die URL
ist einmalig und verfällt nach wenigen Minuten — nicht cachen.
successUrl und cancelUrl sind absolute URLs, an die Stripe den
Benutzer nach Abschluss oder Abbruch des Checkouts zurücksendet. Beide
müssen HTTPS sein.
POST /me/billing/portal-session
Erzeugt eine einmalige URL zum Stripe Customer Portal. Das Portal ist die von Stripe gehostete Seite zur Verwaltung des Abonnements: Karte aktualisieren, Plan ändern, Rechnungen herunterladen, kündigen.
curl -X POST https://api.saiku.bi/me/billing/portal-session \ -H "Authorization: Bearer $SAIKU_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "returnUrl": "https://app.acme.com/billing" }'Antwort:
{ "url": "https://billing.stripe.com/p/session/test_…" }Liefert 409 no_customer, wenn der Tenant noch nie ein Checkout
abgeschlossen hat — es gibt keinen Stripe-Kunden zu verwalten. Führen
Sie zuerst POST /me/billing/checkout-session aus.
Ein durchgängiges Beispiel — eingebetteter Abonnementstatus
Wenn Sie ein Admin-UI bauen, das Saiku Cloud umschließt, und Ihren Benutzern den aktuellen Plan inline anzeigen möchten:
// pseudocodeconst state = await fetch('https://api.saiku.bi/me/billing/state', { headers: { Authorization: `Bearer ${saikuApiKey}` }}).then(r => r.json());
if (!state.billedFeaturesActive) { // user has no active subscription or trial — show "upgrade" CTA const session = await fetch( 'https://api.saiku.bi/me/billing/checkout-session', { method: 'POST', headers: { Authorization: `Bearer ${saikuApiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ tier: 'team', email: user.email, name: org.name, successUrl: `${window.location.origin}/billing/success`, cancelUrl: `${window.location.origin}/billing/cancel` }) } ).then(r => r.json()); window.location.href = session.url;} else { // user has access — show current plan + manage button renderPlan(state.tier, state.currentPeriodEnd); const portal = await fetch( 'https://api.saiku.bi/me/billing/portal-session', { method: 'POST', headers: { Authorization: `Bearer ${saikuApiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ returnUrl: `${window.location.origin}/billing` }) } ).then(r => r.json()); renderManageButton(portal.url);}