docs
/
AppEngine API

Platform operations

Usage metering and token balances, monitoring and analytics dashboards, vendor connections, upstream integrations and cluster management.

The modules that keep the platform running rather than serve a business domain — UsageModule, MonitoringModule, ConnectModule, UpstreamModule and K8sManagementModule. Most orgs never call these directly; the ones that do are billing, ops and integration teams.

Usage

Metering is off by default and governed by two environment flags:

FlagEffect
ENABLE_TOKENIZATIONThe master switch. Unless it is true, nothing is metered or deducted
TRACK_USAGE_WHEN_DISABLEDRecords usage for analytics without deducting anything

Both are logged at boot, so the startup output tells you which mode a deployment is in.

What gets metered

Only endpoints with a declared cost. Everything else passes through untouched:

EndpointCost
/ai/chat2 × multiplier
/ai/agent/chat3 × multiplier
/ai/agent/stream5 × multiplier

The multiplier is 0.0001, so cost is a dollar figure derived from complexity. API key operations — update, delete, regenerate — are recorded at zero.

How a request is charged

UsageMiddleware runs on the way in and settles on the way out:

  1. No orgid header → pass through. Metering is per organization.
  2. Endpoint has no declared cost → pass through.
  3. Tokenization off, tracking on → record usage with trackingOnly: true and deduct nothing.
  4. Tokenization off → pass through.
  5. Org has a subscription → pass through without deduction. Subscriptions are not metered.
  6. No subscription, insufficient balance → 402 with required and available.
  7. Otherwise the response is intercepted, and only a 2xx deducts tokens and records usage.

Two consequences worth knowing: a failed request is never charged, and deduction happens asynchronously after the response — an error while deducting is logged, not surfaced to the caller. The middleware also fails open; if it throws, the request proceeds.

Balances and history

GET/usage/balanceJWT
GET/usage/statsJWT
GET/usage/:orgId/current/:type?JWT
GET/usage/history/:type?JWT
POST/usage/giftJWT

gift credits an org without a payment — trials, goodwill and support credits.

GET/usage/endpointsJWT
POST/usage/endpointsJWT
DELETE/usage/endpoints/:endpointJWT

The cost table is editable at runtime, so a new metered endpoint does not need a deploy.

GET/usage/ai/modelsJWT
GET/usage/ai/provider-keyJWT
POST/usage/ai/chargeJWT

ai/charge books AI spend that did not arrive through a metered HTTP endpoint — background jobs and agent runs.

Service pricing

Per-service rates, separate from AI token costs.

GET/service-pricing/listJWT
GET/service-pricing/activeJWT
GET/service-pricing/catalogJWT
GET/service-pricing/:serviceJWT
GET/service-pricing/check-balance/:serviceJWT
POST/service-pricingJWT
POST/service-pricing/initializeJWT
PUT/service-pricing/:nameJWT
DELETE/service-pricing/:nameJWT
DELETE/service-pricing/allJWT

check-balance/:service is the pre-flight an app should make before starting something billable — buying a phone number, sending a broadcast.

Datatypes: usage, service_pricing, wallet, wallet_transaction.

Monitoring

Platform health. These endpoints are public — they back status pages and external probes, so treat what they expose accordingly.

GET/monitoring/healthNo auth
GET/monitoring/overviewNo auth
GET/monitoring/historicalNo auth
GET/monitoring/system-metricsNo auth
GET/monitoring/alertsNo auth
GET/monitoring/alert-notificationsNo auth
GET/monitoring/queuesNo auth
GET/monitoring/queues/:queueNameNo auth

Queue depth is the first place to look when automations, escalations or broadcasts run late — all three are queue-driven.

GET/monitoring/usageNo auth
GET/monitoring/user-activityNo auth
GET/monitoring/web-activityNo auth
GET/monitoring/company-creationNo auth
GET/monitoring/domain-mappingsNo auth

Analytics, stats and overviews

One module, AnalyticsModule (src/analytics), serves three route families.

Analytics dashboards — per-surface aggregates, one endpoint each. Every one takes startDate / endDate; GET /analytics takes type (website, blog, workflow, storefront, tickets, leads, automation, users, email) or returns them all.

GET/analyticsJWT
GET/analytics/websiteJWT
GET/analytics/blogJWT
GET/analytics/workflowJWT
GET/analytics/storefrontJWT
POST/analytics/storefront/ordersJWT
GET/analytics/ticketsJWT
GET/analytics/attributionJWT
GET/analytics/leadsJWT
GET/analytics/automationJWT
GET/analytics/usersJWT
GET/analytics/emailJWT
GET/analytics/filter-optionsJWT
GET/analytics/live-viewJWT
GET/analytics/live-view/:deviceId/journeyJWT
POST/analytics/exportJWT

Aggregations run against a secondary read and are briefly cached. live-view is visitors in the last minutes (default 15); attribution is revenue by source, medium and campaign.

Engagement stats — /stats/:datatype/:id/{like,dislike,bookmark,follow,favorite,rating,reaction,view,share}, GET /stats/:datatype/:id, /stats/by-resource/… and /stats/by-customer/…. See Engagement and search.

Studio overviews — the figures behind each Studio section's dashboard, computed on the server so the screen only renders them.

GET/studio-overview/:sectionJWT

section is one of home, account, config, database, build-studio, dam, crm, store, events, community, finance, logistics, ai-automation; anything else is 404. The response is { section, generatedAt, … }.

Connect

Third-party credentials, OAuth handshakes and inbound webhooks. Every vendor callback lands here.

POST/connect/webhook/:vendor/:serviceId?No auth
GET/connect/webhook/:vendor/:serviceId?No auth
GET/connect/oauth2callback/:vendorNo auth

Public by necessity — the caller is a vendor, not a user — so each vendor adapter verifies its own signature.

POST/connect/automation/:id/:stepId/:entity/:activity/No auth
GET/connect/automation/:id/:stepId/:entity/:activity/No auth

The resume path for automations parked waiting on an external event.

Vendor adapters cover payments (Stripe, PayPal, Helcim), email (Mailgun, SendGrid, SES), telephony (Twilio), shipping (EasyPost), design (Figma), and the social networks (Facebook, Instagram via Threads, LinkedIn, X, TikTok, Pinterest, Mastodon, WhatsApp, Google).

Upstream

Calls out to those integrations, with configuration and a test harness.

GET/upstream/integration-types/:type?JWT
GET/upstream/integration-use-cases/:useCaseJWT
GET/upstream/get-config/:type?/:configId?JWT
GET/upstream/active/:type?JWT
GET/upstream/active/detail/:id?JWT
POST/upstream/get-integrationJWT
POST/upstream/save-integrationJWT
POST/upstream/shutdown/:idJWT
POST/upstream/call/:integration/:operationJWT
GET/upstream/call/:integration/:operationJWT
POST/upstream/service/:serviceName/:operationJWT
GET/upstream/service/:serviceName/:operationJWT
POST/upstream/test/:integration/:operationJWT

test exercises an operation with the saved credentials without committing the result — the way to validate a connection before an automation depends on it.

Cluster management

Namespace and workload control for tenant infrastructure. Destructive by design; restrict it accordingly.

GET/k8/namespacesJWT
GET/k8/namespaces/:namespaceNameJWT
GET/k8/namespaces/:namespaceName/podsJWT
GET/k8/check-status/:namespace/:kind/:resourceJWT
POST/k8/apply-serviceJWT
POST/k8/scale-upJWT
POST/k8/scale-downJWT
POST/k8/cleanup-resourcesJWT
DELETE/k8/delete-service/:namespace/:kind/:nameJWT
DELETE/k8/namespaces/:nameJWT

scale-down to zero is how idle tenant environments stop costing anything; apply-service is what brings one back.