API Reference

This page documents the API families used by the current DartStream app. DartStream is microservice-based, so production uses separate service hosts instead of one monolithic API.

Authentication Headers

Protected dashboard API calls use Firebase ID token bearer authentication.

Authorization: Bearer <Firebase ID token>
Content-Type: application/json
X-Tenant-ID: <active tenant ID>

X-Tenant-ID is required for tenant-scoped calls. Auth bootstrap endpoints may not require it because they establish tenant context.

Server-to-server integrations use OAuth2 client credentials. This is the confidential integration path for backends, CLIs, CI jobs, and server-rendered apps. Do not embed a clientSecret in a browser, Flutter app, mobile binary, public sample app, or any other client-side bundle.

Connect Your Project With Client Credentials

  1. Sign up and complete checkout in the DartStream app so the tenant has an active subscription.

  2. Open Settings → Applications and create a client with a name, project, scopes, and optional expiry. Client creation is a paid capability and is capped at 10 retained clients per tenant.

  3. Save the clientId and clientSecret when the app shows them. The secret is shown once and is stored only as a hash.

  4. Exchange the credentials for a short-lived access token through the billing API.

curl -u '<client_id>:<client_secret>' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=client_credentials&scope=projects:read flags:read' \
  https://apibilling.dartstream.io/api/v1/oauth2/token

Response:

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 300,
  "scope": "flags:read projects:read"
}
  1. Use the returned token for scoped platform API calls. The token carries tenant context, so a separate Firebase user session is not required for server integrations.

Authorization: Bearer <OAuth2 access token>
Content-Type: application/json

Supported scopes include auth:read, auth:write, projects:read, projects:write, flags:read, flags:write, experience:read, experience:write, reactive:read, reactive:write, persistence:read, persistence:write, platform:read, and platform:write. Feature-flag evaluation is client-side after a flags:read fetch; there is no separate evaluation endpoint or scope. Requested scopes must be a subset of the scopes saved on the OAuth2 client.

Disable a client to stop new token exchanges while keeping the row visible for audit and re-enable. Revoke a client when it should no longer be usable. Platform, reactive, and persistence services check client status on each OAuth2 request, so disabled or revoked clients are rejected on the next protected resource call. Experience tokens use the same short issuer lifetime and shared JWT secret; a revoked token can remain valid there only until its five-minute access-token expiry.

Auth API

Base host:

POST /api/v1/auth/signup

Bootstrap a newly created Firebase account.

{
  "idToken": "firebase_id_token",
  "email": "user@example.com",
  "password": "optional_password_context"
}

POST /api/v1/auth/login

Bootstrap an existing Firebase session.

{
  "idToken": "firebase_id_token"
}

POST /api/v1/auth/signin/google

Bootstrap a federated Firebase session.

{
  "idToken": "firebase_id_token",
  "providerName": "google"
}

Successful responses include user, active tenant, role, subscription, and memberships.

POST /api/v1/auth/logout

Log out the current backend session. The frontend also clears local Firebase and browser storage.

Billing API

Base host:

GET /api/v1/billing/subscription

Returns the active tenant billing snapshot and entitlement limits.

Example response shape:

{
  "tenantId": "tenant-id",
  "tenantName": "Workspace",
  "subscription": {
    "plan": "standard",
    "status": "active",
    "billingCycle": "annual",
    "customerId": "cus_...",
    "externalId": "sub_..."
  },
  "limits": {
    "auth_providers": 1,
    "database_connections": 1,
    "storage_gb": 5,
    "feature_flags": 25,
    "projects": 1,
    "environments": 2,
    "team_members": 3,
    "flutter_apps": 2,
    "game_projects": 1,
    "telemetry_events_monthly": 100000,
    "ai_runtime": 0
  },
  "features": {
    "auth_providers": true,
    "database_connections": true,
    "feature_flags": true,
    "ai_runtime": false
  }
}

GET /api/v1/billing/features/{feature}/check

Checks whether the active tenant can use a feature.

Example:

GET /api/v1/billing/features/auth_providers/check

Example response:

{
  "isValid": true,
  "failureReason": null,
  "hasWarning": false,
  "warningMessage": null,
  "used": 0,
  "limit": 1,
  "percentUsed": 0.0
}

POST /api/v1/billing/checkout

Creates a Stripe Checkout session for a subscription or routes an existing Stripe subscription to a targeted portal flow when applicable.

{
  "type": "subscription",
  "planId": "standard",
  "successUrl": "https://app.dartstream.io/membership/membership-paid?checkout=success&plan=standard",
  "cancelUrl": "https://app.dartstream.io/membership"
}

Response:

{
  "checkoutUrl": "https://checkout.stripe.com/c/pay/...",
  "type": "subscription"
}

POST /api/v1/billing/portal

Creates a Stripe Billing Portal session.

{
  "returnUrl": "https://app.dartstream.io/settings/billing"
}

Response:

{
  "portalUrl": "https://billing.stripe.com/p/session/..."
}

Enterprise API

Base host:

POST /api/v1/enterprise/enterprise-signup

Submits an Enterprise request from the membership flow.

The form captures use cases such as Flutter app runtime, Flame game backend, live-ops telemetry, Unity/native bridge planning, Dart FFI, AI runtime integration, private deployment, governance, security, compliance, and SLA needs.

Data Streaming API

Base host:

Use an OAuth2 token with reactive:write to create channels and publish messages. Use reactive:read to pull messages and metrics. Every operation is scoped to the tenant in the token.

POST /api/v1/reactive/streaming/channels/{channelId}/publish

Publishes a JSON message to an active channel and returns the persisted event.

{
  "event_type": "order.created",
  "payload": {
    "order_id": "order-123"
  },
  "attributes": {
    "partition_key": "customer-456"
  }
}

GET /api/v1/reactive/streaming/channels/{channelId}/subscribe

Pulls up to 100 channel messages. Pass an ISO-8601 since value to poll for newer messages and an optional limit from 1 through 100. /messages is an equivalent alias.

GET /api/v1/reactive/streaming/channels/<channel-id>/subscribe?since=2026-08-26T12:00:00Z&limit=100

GET /api/v1/reactive/streaming/channels/{channelId}/metrics

Returns persisted publish count, failure count, payload bytes, and the latest publish time. An optional ISO-8601 since value limits the metrics window.

Platform Health

GET /health

Each backend service exposes a health endpoint. Example:

GET https://apiplatform.dartstream.io/health

Status Values

Subscription status values include:

  • active

  • trialing

  • pendingCancel

  • cancelled

  • incomplete

  • inactive

Notes

Feature flag authoring and OpenFeature provider details belong primarily to IntelliToggle documentation. DartStream documents the feature and entitlement checks that the DartStream app uses.

Streaming beta scope

Beta topics run on DartStream Core and persist published events in its event log. Create and edit expose only the topic name and description. Third-party brokers, configurable region, partitions, replication, retention, delivery guarantees, message-size limits and dead-letter queues are not supported beta options. Legacy vendor metadata did not establish a third-party connection. The dashboard identifies those channels as Core. Publish, subscribe, messages and metrics keep their existing /api/v1/reactive/streaming/channels/{id} routes.