Overview
ScaiControl is the centralised management, provisioning, and billing platform for the ScaiLabs ecosystem. It is the single point of entry for customers to discover, subscribe to, provision, use, and pay for ScaiLabs services — and the single point of orchestration for the operator running the platform.
What ScaiControl does#
| Capability | Purpose |
|---|---|
| Catalog & subscriptions | A unified product catalog of every ScaiLabs service, with plans, packs (bundles), trials, and the full subscription lifecycle |
| Provisioning | DAG-driven workflow engine that activates services across multiple service backends with compensating rollback on failure |
| Metering & usage | Per-tenant usage ingestion, aggregation, quota enforcement, and billable-event roll-ups |
| Billing & invoicing | EU-compliant invoicing (VAT determination, reverse-charge for intra-EU B2B, immutable finalised invoices with gap-free numbering), credit notes, dunning, and a GrapesJS template designer |
| Payments | Pluggable payment provider architecture supporting Stripe, Mollie, and crypto (Coinbase Commerce) |
| Service registry | First-class registration, approval, heartbeating, and health monitoring for every ScaiLabs service |
| Outbound webhooks | Durable event-outbox dispatch of 14 lifecycle topics (subscriptions, packs, billing) with HMAC signing, retries, and replay tooling |
| Multi-tenant RBAC | Tenancy isolation enforced at the ORM layer; role + scope authorisation via ScaiKey JWTs |
What sits next to it#
ScaiControl is one node in the ScaiLabs network:
- ScaiKey issues JWTs that ScaiControl validates via JWKS.
- ScaiVault holds secrets — every
*_VAULT_PATHenv var resolves through it. - ScaiSend dispatches operator email (invoices, dunning, lifecycle notifications).
- Subscriber services (ScaiCRM, ScaiCMS, etc.) register with ScaiControl, heartbeat, accept provisioning calls, and consume outbound webhooks.
Architecture in one paragraph#
ScaiControl is a FastAPI backend (Python 3.12, SQLAlchemy 2.0 async on MariaDB Galera, Redis + arq for queues, S3 for PDFs and assets) with a SolidJS portal frontend (Tailwind 4 + DaisyUI 5, Vite). Multi-tenancy is enforced via a SQLAlchemy do_orm_execute hook that auto-filters every query on TenantScopedModel subclasses. Authorisation uses ScaiKey-signed JWTs validated against rotating JWKS, with role+scope checks via require_permission("scope:action") and a super_admin bypass. The provisioning engine is a topologically-ordered DAG of sync/async-callback/async-poll steps with reverse-order compensation on failure. The billing system snapshots buyer + seller at finalisation, runs a deterministic VAT determination (4 rules covering domestic, intra-EU B2B with reverse charge, intra-EU B2C, and non-EU export), and emits gap-free invoice numbers via SELECT … FOR UPDATE. Outbound events flow through a two-pass dispatcher (fan-out → deliver) with (subscription, idempotency_key) uniqueness guaranteeing at-least-once delivery with subscriber-side dedup.
How to read this documentation#
- Quickstart — get a local ScaiControl running and make your first API call.
- Concepts — read these to understand WHY the system is shaped this way:
- Reference — read these to look up specific endpoints, schemas, or config values:
- API reference (auto-generated per tag from the OpenAPI spec)
- Events: overview · Events: catalog · Webhooks
- Configuration · CLI · State machines
- Troubleshooting — read these when something's wrong:
Audiences#
- Service integrators — building a new service that subscribes to ScaiControl events or registers itself in the catalog. Start with Concepts: webhooks → Events overview → Catalog.
- Operators — running ScaiControl in production. Start with Configuration → CLI → the troubleshooting pages.
- Frontend / portal developers — wiring up tenant-facing flows. Start with Architecture → Authentication & RBAC → relevant API reference pages.
- Auditors & compliance — reviewing EU invoicing and tenancy isolation. Start with Multi-tenancy → Invoice lifecycle → VAT & reverse charge.
Status#
ScaiControl is at v1.x. Major recent milestones:
- EU-compliant invoicing (VAT determination, immutable finalised invoices, credit notes).
- GrapesJS template designer for invoice + email templates.
- Outbound webhook system with 14 lifecycle topics.
- Service packs (bundled subscriptions with shared lifecycle).
See Changelog for the running release notes.
Conventions used in this documentation#
- Code paths are relative to the project root (e.g.
backend/src/scaicontrol/services/billing/invoice.py). - API examples use
curlagainsthttp://localhost:8000— substitute your deployment's base URL. - IDs are shown abbreviated (
tnt_abc…) — actual IDs are longer alphanumerics. UUID-format fields are explicitly noted. - Timestamps are RFC 3339 UTC (
2026-05-18T09:30:00+00:00); databaseDATETIMEcolumns are UTC by convention. - All monetary amounts are integer cents in the currency named in the same row.