The machine that builds machines — multi-tenant infrastructure for SaaS companies
The Platform Block is the orchestration layer that provisions and manages every 23blocks platform, account, app, and block. It provides a complete API for building multi-tenant SaaS products, white-label platforms, developer ecosystems, and marketplace infrastructure.
Key Features
- Multi-Tenant Provisioning - Create platforms, accounts, apps, and API keys with a single API call
- Account & App Management - Full CRUD with deployment models, domain verification, branding, and storage
- Block Licensing - License any of the 17 ecosystem blocks to accounts and provision them to individual apps
- API Key Infrastructure - Environment-aware keys (test/live), scoped permissions, rate limiting, IP/origin restrictions
- User Access Control - Grant, revoke, suspend, and reactivate user access across apps and accounts
- Subscription Management - Billing cycles, Stripe integration, trial periods, auto-renewal
- Investor Data Room - Built-in reporting: MRR, ARR, ARPA, churn, growth, engagement, platform breakdowns
- Data Transfer Portal - Secure data export with agreement acceptance and audit trail
- Domain Verification - SPF, DKIM validation for custom email domains
- Slack Notifications - Webhook integration for account events
API Endpoint
| Service | URL |
|---|
| Platform | https://platform.api.us.23blocks.com |
Authentication
All endpoints (except Health and Data Transfers) require:
Authorization: Bearer <jwt_token>
X-Platform: <platform_code>
Scopes: platform:admin, platform:manage, platform:read
Platform (your SaaS product)
└── Account (your customer)
└── App (a product within the account)
├── API Keys (test/live, scoped, rate-limited)
└── Block Instances (Auth, CRM, Files, AI, etc.)
Quick Start
1. Create an Account
curl -X POST https://platform.api.us.23blocks.com/accounts \
-H "Authorization: Bearer $TOKEN" \
-H "X-Platform: your-platform" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme Corp",
"code": "acme",
"deployment_model": "shared_cloud",
"preferred_domain": "acme.yourplatform.com"
}'
2. Create an App
curl -X POST https://platform.api.us.23blocks.com/accounts/acme/apps \
-H "Authorization: Bearer $TOKEN" \
-H "X-Platform: your-platform" \
-H "Content-Type: application/json" \
-d '{
"name": "Main App",
"description": "Primary application",
"app_type": "web",
"purpose": "production"
}'
3. Generate API Keys
curl -X POST https://platform.api.us.23blocks.com/accounts/acme/apps/$APP_ID/api_keys \
-H "Authorization: Bearer $TOKEN" \
-H "X-Platform: your-platform" \
-H "Content-Type: application/json" \
-d '{
"name": "Production Key",
"key_type": "publishable",
"environment": "live",
"scopes": ["read", "write"]
}'
4. Provision Blocks
curl -X POST https://platform.api.us.23blocks.com/accounts/acme/apps/$APP_ID/blocks \
-H "Authorization: Bearer $TOKEN" \
-H "X-Platform: your-platform" \
-H "Content-Type: application/json" \
-d '{
"block_unique_id": "auth-block-id"
}'
Health Checks
No authentication required.
| Endpoint | Description |
|---|
GET /health | Basic service health |
GET /health/ready | Database connectivity check |
GET /health/detailed | Extended health with component statuses |
| Endpoint | Method | Description |
|---|
/platforms | GET | List all platforms |
/platforms/:unique_id | GET | Show single platform |
/platforms | POST | Create a new platform |
/platforms/:unique_id | PUT | Update a platform |
/platforms/:unique_id | DELETE | Delete a platform |
| Field | Type | Description |
|---|
unique_id | string | Unique identifier |
url_id | string | URL-safe identifier |
code | string | Platform code |
name | string | Platform name |
description | string | Platform description |
email | string | Contact email |
website | string | Website URL |
status | string | Platform status |
enabled | boolean | Whether platform is active |
schema_name | string | Database schema name |
settings | object | Platform configuration |
metadata | object | Custom metadata |
Accounts
| Endpoint | Method | Description |
|---|
/platforms/:pid/accounts | GET | List accounts in a platform |
/platforms/:pid/accounts/:id | GET | Show single account |
/platforms/:pid/accounts | POST | Create account in platform |
/platforms/:pid/accounts/:id | PUT | Update account |
/platforms/:pid/accounts/:id | DELETE | Delete account |
/accounts | GET | List accounts in current platform context |
/accounts/:url_id | GET | Show single account |
/accounts | POST | Create account |
/accounts/:url_id | PUT | Update account |
/accounts/:url_id | DELETE | Delete account (soft delete) |
/global/accounts | GET | Aggregates accounts across ALL platforms |
Account Attributes
| Field | Type | Description |
|---|
unique_id | string | Unique identifier |
name | string | Account name |
code | string | Account code |
url_id | string | URL-safe identifier |
status | string | Account status |
preferred_domain | string | Custom domain |
preferred_language | string | Preferred language |
deployment_model | string | Deployment type |
capabilities | object | Computed capabilities from deployment model |
Deployment Models
| Model | Description |
|---|
shared_cloud | Instant provisioning on shared infrastructure |
dedicated_cloud | Isolated infrastructure with SLA guarantees |
self_hosted | Run on your own AWS account |
partner_cloud | Managed by a 23blocks partner |
Capabilities (computed from deployment_model)
{
"capabilities": {
"can_export_data": true,
"can_export_terraform": false,
"can_view_monitoring": true,
"can_instant_provision": true,
"has_dedicated_support": false,
"has_sla_guarantee": false,
"can_customize_infra": false,
"requires_vpn": false,
"data_residency_configurable": false
}
}
Apps
| Endpoint | Method | Description |
|---|
/accounts/:url_id/apps | GET | List apps for an account |
/accounts/:url_id/apps | POST | Create app |
/accounts/:url_id/apps/:id | PUT | Update app |
/accounts/:url_id/apps/:id | DELETE | Delete app |
/accounts/:url_id/apps/:id/verify_domain | POST | Verify domain ownership |
/accounts/:url_id/apps/:id/check_domain | GET | Check domain verification status |
App Attributes
| Field | Type | Description |
|---|
unique_id | string | Unique identifier |
name | string | App name |
app_type | string | Application type |
purpose | string | App purpose |
status | string | App status |
oauth_enabled | boolean | OAuth support enabled |
rate_limit_per_minute | integer | Rate limit |
webhook_url | string | Webhook endpoint |
allowed_origins | array | CORS origins |
preferred_domain | string | Custom domain |
domain_verified | boolean | Domain verification status |
API Keys
| Endpoint | Method | Description |
|---|
/accounts/:url_id/apps/:app_id/api_keys | GET | List API keys |
/accounts/:url_id/apps/:app_id/api_keys | POST | Create API key |
/accounts/:url_id/apps/:app_id/api_keys/:id/regenerate | POST | Regenerate key |
/accounts/:url_id/apps/:app_id/api_keys/:id/rotate_secret | POST | Rotate secret |
pk_live_sh_xxxx (publishable key)
sk_live_sh_xxxx (secret key)
Tier codes embedded in key: sh (shared), ent (dedicated/self-hosted), byok (partner).
API Key Attributes
| Field | Type | Description |
|---|
key_id | string | The API key value |
name | string | Key name |
key_type | string | publishable or secret |
environment | string | test or live |
scopes | array | Permission scopes |
rate_limit_per_minute | integer | Rate limit |
allowed_ips | array | IP whitelist |
allowed_origins | array | Origin whitelist |
expires_at | datetime | Expiration date |
usage_count | integer | Total usage |
Block Licensing
Account Blocks (licensing)
| Endpoint | Method | Description |
|---|
/accounts/:url_id/blocks | GET | List licensed blocks |
/accounts/:url_id/blocks | POST | License a block |
/accounts/:url_id/blocks/:id | DELETE | Remove block license |
App Blocks (provisioning)
| Endpoint | Method | Description |
|---|
/accounts/:url_id/apps/:app_id/blocks | GET | List provisioned blocks |
/accounts/:url_id/apps/:app_id/blocks | POST | Provision block to app |
/accounts/:url_id/apps/:app_id/blocks/:block_id | DELETE | Deprovision block |
Available Blocks (17)
Auth, CRM, Content, Files, Forms, Geolocation, Jarvis (AI), Messaging, Notifications, Onboarding, Products, Rewards, Sales, Search, Social, University, Wallet
Subscriptions
| Endpoint | Method | Description |
|---|
/accounts/:url_id/subscriptions | GET | List subscriptions |
/accounts/:url_id/subscriptions | POST | Create subscription |
/accounts/:url_id/subscriptions/:id/cancel | POST | Cancel subscription |
/accounts/:url_id/subscriptions/:id/reactivate | POST | Reactivate |
/accounts/:url_id/subscriptions/:id/suspend | POST | Suspend |
/subscription_models | GET | List subscription model catalog |
User Access Control
| Endpoint | Method | Description |
|---|
/users/:user_id/apps | GET | List apps a user can access |
/users/:user_id/accounts | GET | List accounts a user belongs to |
/users/:user_id/accesses | GET | List all access records |
/user_accesses | POST | Grant user access |
/user_accesses/:id/revoke | POST | Revoke access |
/user_accesses/:id/suspend | POST | Suspend access |
/user_accesses/:id/reactivate | POST | Reactivate access |
Account Services
| Endpoint | Method | Description |
|---|
/accounts/:url_id/keys | CRUD | AWS/third-party credentials |
/accounts/:url_id/exchange | CRUD | RabbitMQ configuration |
/accounts/:url_id/details | GET/POST/PUT | Address, contact, branding |
/accounts/:url_id/storage | POST | Provision S3 storage |
/accounts/:url_id/domain/verify | POST | Initiate domain verification |
/accounts/:url_id/domain/check | GET | Check domain verification (SPF, DKIM) |
/accounts/:url_id/logo/presign | POST | Get presigned URL for logo upload |
/accounts/:url_id/logo/publish | POST | Publish uploaded logo |
/accounts/:url_id/settings/notifications | PATCH | Slack webhook settings |
Data Transfers
Public endpoints — no JWT authentication required.
| Endpoint | Method | Description |
|---|
/data_transfers/:code | GET | Show transfer details |
/data_transfers/:code/request_access | POST | Request access |
/data_transfers/:code/verify_access | POST | Verify access credentials |
/data_transfers/:code/accept | POST | Accept transfer agreement |
/data_transfers/:code/decline | POST | Decline transfer |
/data_transfers/:code/events | POST | Record transfer event |
Reporting (Investor Data Room)
Scope: platform:admin
| Endpoint | Method | Description |
|---|
/reporting/dashboard | GET | Dashboard overview across all platforms |
/reporting/revenue | GET | MRR, ARR, ARPA, by tier/block/platform |
/reporting/customers | GET | Customer metrics, trials, churn, health |
/reporting/growth | GET | New accounts, MRR movement, expansion |
/reporting/engagement | GET | API usage, active accounts, block adoption |
/reporting/platforms | GET | Platform breakdown |
/reporting/platforms/:code | GET | Single platform detail |
Query parameters: period (7d, 30d, 90d, all_time), platform (code), force_refresh (true/false)
All responses follow JSON:API format:
{
"data": {
"id": "<unique_id>",
"type": "<resource_type>",
"attributes": { }
},
"meta": { }
}
Error responses:
{
"error": "<error_type>",
"message": "<human-readable message>",
"status": 422
}