Some checks failed
API CI / API Lint (push) Successful in 47s
API CI / API Type Check (push) Failing after 47s
API CI / API Test (push) Successful in 1m0s
API CI / API Build (push) Failing after 50s
API CI / Build Docker Image (push) Has been skipped
Build Crossplane Provider / build (push) Failing after 5m51s
CD Pipeline / Deploy to Staging (push) Failing after 29s
CI Pipeline / Lint and Type Check (push) Failing after 36s
CI Pipeline / Build (push) Has been skipped
CI Pipeline / Test Backend (push) Failing after 1m33s
CI Pipeline / Test Frontend (push) Failing after 30s
CI Pipeline / Security Scan (push) Failing after 1m16s
Crossplane Provider CI / Go Test (push) Failing after 3m23s
Crossplane Provider CI / Go Lint (push) Failing after 7m27s
Crossplane Provider CI / Go Build (push) Failing after 3m27s
Deploy to Staging / Deploy to Staging (push) Failing after 30s
Portal CI / Portal Lint (push) Failing after 21s
Portal CI / Portal Type Check (push) Failing after 21s
Portal CI / Portal Test (push) Failing after 21s
Portal CI / Portal Build (push) Failing after 22s
Test Suite / frontend-tests (push) Failing after 30s
Test Suite / api-tests (push) Failing after 49s
Test Suite / blockchain-tests (push) Failing after 30s
Type Check / type-check (map[directory:. name:root]) (push) Failing after 23s
Type Check / type-check (map[directory:api name:api]) (push) Failing after 21s
Type Check / type-check (map[directory:portal name:portal]) (push) Failing after 19s
Validate Configuration Files / validate (push) Failing after 1m52s
CD Pipeline / Deploy to Production (push) Has been skipped
Co-authored-by: Cursor <cursoragent@cursor.com>
23 KiB
23 KiB
Phoenix Operating Model - API Specification
Complete API specification for all five control planes
This document provides detailed API specifications for the Phoenix operating model, including GraphQL schemas, REST endpoints, and integration patterns.
Executive Summary
The Phoenix operating model exposes APIs for all five control planes:
- Commercial Plane API - Client and billing operations
- Tenancy Plane API - Tenant and identity operations
- Subscription Plane API - Subscription and quota operations
- Environment Plane API - Environment and deployment operations
- Content & DevOps Plane API - Content and Git operations
All APIs support:
- GraphQL interface (primary)
- REST interface (alternative)
- Authentication via Keycloak
- Authorization via RBAC
- Audit logging
- Multi-region support
I. Commercial Plane API
GraphQL Schema
# Client Management
type Client {
id: ID!
name: String!
legalEntity: LegalEntity!
contract: Contract
msa: MSA
invoicingConfig: InvoicingConfig!
paymentInstruments: [PaymentInstrument!]!
costCenters: [CostCenter!]!
tenants: [Tenant!]!
usageAggregation: UsageAggregation
chargebackRules: [ChargebackRule!]!
createdAt: DateTime!
updatedAt: DateTime!
metadata: JSON
}
type LegalEntity {
name: String!
registrationNumber: String
jurisdiction: String!
taxId: String
address: Address!
}
type InvoicingConfig {
format: InvoiceFormat!
frequency: InvoiceFrequency!
currency: String!
paymentTerms: String!
billingAddress: Address!
emailRecipients: [String!]!
}
enum InvoiceFormat {
PDF
XML
JSON
}
enum InvoiceFrequency {
MONTHLY
QUARTERLY
ANNUAL
}
# Queries
type Query {
client(id: ID!): Client
clients(filter: ClientFilter): [Client!]!
billing(clientId: ID!, timeRange: TimeRange!): BillingData!
invoices(clientId: ID!, filter: InvoiceFilter): [Invoice!]!
costCenters(clientId: ID!): [CostCenter!]!
}
# Mutations
type Mutation {
createClient(input: CreateClientInput!): Client!
updateClient(id: ID!, input: UpdateClientInput!): Client!
deleteClient(id: ID!): Boolean!
createInvoice(clientId: ID!, period: BillingPeriod!): Invoice!
processPayment(invoiceId: ID!, payment: PaymentInput!): Payment!
addPaymentInstrument(clientId: ID!, instrument: PaymentInstrumentInput!): PaymentInstrument!
removePaymentInstrument(clientId: ID!, instrumentId: ID!): Boolean!
createCostCenter(clientId: ID!, input: CreateCostCenterInput!): CostCenter!
updateCostCenter(clientId: ID!, costCenterId: ID!, input: UpdateCostCenterInput!): CostCenter!
deleteCostCenter(clientId: ID!, costCenterId: ID!): Boolean!
}
# Input Types
input CreateClientInput {
name: String!
legalEntity: LegalEntityInput!
invoicingConfig: InvoicingConfigInput!
contract: ContractInput
msa: MSAInput
}
input ClientFilter {
name: String
jurisdiction: String
status: ClientStatus
}
input TimeRange {
start: DateTime!
end: DateTime!
}
REST Endpoints
# Client Management
POST /api/v1/commercial/clients
GET /api/v1/commercial/clients
GET /api/v1/commercial/clients/{id}
PUT /api/v1/commercial/clients/{id}
DELETE /api/v1/commercial/clients/{id}
# Billing
GET /api/v1/commercial/clients/{id}/billing
GET /api/v1/commercial/clients/{id}/invoices
POST /api/v1/commercial/clients/{id}/invoices
GET /api/v1/commercial/invoices/{id}
POST /api/v1/commercial/invoices/{id}/payments
# Cost Centers
POST /api/v1/commercial/clients/{id}/cost-centers
GET /api/v1/commercial/clients/{id}/cost-centers
PUT /api/v1/commercial/clients/{id}/cost-centers/{costCenterId}
DELETE /api/v1/commercial/clients/{id}/cost-centers/{costCenterId}
Example Queries
Create Client
mutation {
createClient(input: {
name: "Government Agency A"
legalEntity: {
name: "Government Agency A"
jurisdiction: "Nation A"
address: {
street: "123 Main St"
city: "Capital City"
country: "Nation A"
}
}
invoicingConfig: {
format: PDF
frequency: MONTHLY
currency: "USD"
paymentTerms: "Net 30"
billingAddress: {
street: "123 Main St"
city: "Capital City"
country: "Nation A"
}
emailRecipients: ["billing@agency.gov"]
}
}) {
id
name
legalEntity {
name
jurisdiction
}
}
}
Get Billing Data
query {
billing(
clientId: "client-id"
timeRange: {
start: "2025-01-01T00:00:00Z"
end: "2025-01-31T23:59:59Z"
}
) {
totalCost
currency
bySubscription {
subscription {
id
name
}
cost
percentage
}
byCostCenter {
costCenter {
id
name
}
cost
percentage
}
}
}
II. Tenancy Plane API
GraphQL Schema
# Tenant Management
type Tenant {
id: ID!
name: String!
primaryDomains: [String!]!
identityProvider: IdentityProvider!
rbacNamespace: String!
dataResidencyFlags: [DataResidencyFlag!]!
complianceProfile: ComplianceProfile!
client: Client!
subscriptions: [Subscription!]!
environments: [Environment!]!
regions: [Region!]!
keycloakRealmId: String
multiRegionEnabled: Boolean!
regionalDataResidency: [RegionalDataResidency!]!
crossBorderGovernance: CrossBorderGovernance
createdAt: DateTime!
updatedAt: DateTime!
metadata: JSON
}
type IdentityProvider {
type: IdentityProviderType!
config: JSON!
ssoEnabled: Boolean!
mfaRequired: Boolean!
}
enum IdentityProviderType {
KEYCLOAK
AZURE_AD
OKTA
GOOGLE_WORKSPACE
CUSTOM_SAML
CUSTOM_OIDC
}
# Queries
type Query {
tenant(id: ID!): Tenant
tenants(filter: TenantFilter): [Tenant!]!
tenantByDomain(domain: String!): Tenant
identityProvider(tenantId: ID!): IdentityProvider
complianceProfile(tenantId: ID!): ComplianceProfile
}
# Mutations
type Mutation {
createTenant(input: CreateTenantInput!): Tenant!
updateTenant(id: ID!, input: UpdateTenantInput!): Tenant!
deleteTenant(id: ID!): Boolean!
configureIdentityProvider(tenantId: ID!, provider: IdentityProviderInput!): IdentityProvider!
syncKeycloakRealm(tenantId: ID!): KeycloakRealm!
updateComplianceProfile(tenantId: ID!, profile: ComplianceProfileInput!): ComplianceProfile!
addDataResidencyFlag(tenantId: ID!, flag: DataResidencyFlagInput!): DataResidencyFlag!
removeDataResidencyFlag(tenantId: ID!, flagId: ID!): Boolean!
}
# Input Types
input CreateTenantInput {
name: String!
clientId: ID!
primaryDomains: [String!]!
identityProvider: IdentityProviderInput!
rbacNamespace: String!
complianceProfile: ComplianceProfileInput!
dataResidencyFlags: [DataResidencyFlagInput!]
multiRegionEnabled: Boolean
}
REST Endpoints
# Tenant Management
POST /api/v1/tenancy/tenants
GET /api/v1/tenancy/tenants
GET /api/v1/tenancy/tenants/{id}
PUT /api/v1/tenancy/tenants/{id}
DELETE /api/v1/tenancy/tenants/{id}
GET /api/v1/tenancy/tenants/by-domain/{domain}
# Identity Provider
GET /api/v1/tenancy/tenants/{id}/identity-provider
PUT /api/v1/tenancy/tenants/{id}/identity-provider
POST /api/v1/tenancy/tenants/{id}/keycloak/sync
# Compliance
GET /api/v1/tenancy/tenants/{id}/compliance
PUT /api/v1/tenancy/tenants/{id}/compliance
Example Queries
Create Tenant
mutation {
createTenant(input: {
name: "agency-tenant"
clientId: "client-id"
primaryDomains: ["agency.gov", "agency.sankofa.nexus"]
identityProvider: {
type: KEYCLOAK
config: {}
ssoEnabled: true
mfaRequired: true
}
rbacNamespace: "agency-namespace"
complianceProfile: {
standards: [ISO_27001, SOC_2, FEDRAMP]
}
dataResidencyFlags: [{
region: "region-a"
requirement: REQUIRED
enforcement: HARD
}]
multiRegionEnabled: true
}) {
id
name
primaryDomains
keycloakRealmId
}
}
Configure Identity Provider
mutation {
configureIdentityProvider(
tenantId: "tenant-id"
provider: {
type: AZURE_AD
config: {
tenantId: "azure-tenant-id"
clientId: "azure-client-id"
clientSecret: "azure-client-secret"
}
ssoEnabled: true
mfaRequired: true
}
) {
type
ssoEnabled
mfaRequired
}
}
III. Subscription Plane API
GraphQL Schema
# Subscription Management
type Subscription {
id: ID!
name: String!
tenant: Tenant!
client: Client!
type: SubscriptionType!
serviceBundles: [ServiceBundle!]!
quotas: Quotas!
limits: Limits!
costTracking: CostTracking!
policyPacks: [PolicyPack!]!
featureEntitlements: [FeatureEntitlement!]!
environments: [Environment!]!
regions: [Region!]!
createdAt: DateTime!
updatedAt: DateTime!
metadata: JSON
}
enum SubscriptionType {
SHARED_PLATFORM
PRODUCT
SANDBOX
INNOVATION
}
type ServiceBundle {
service: ServiceType!
enabled: Boolean!
quotas: ServiceQuotas
limits: ServiceLimits
}
enum ServiceType {
COMPUTE
STORAGE
NETWORKING
DATABASE
AI_ML
ANALYTICS
SECURITY
MONITORING
BACKUP
}
# Queries
type Query {
subscription(id: ID!): Subscription
subscriptions(filter: SubscriptionFilter): [Subscription!]!
quotas(subscriptionId: ID!): Quotas!
checkQuota(subscriptionId: ID!, resource: ResourceType!): QuotaStatus!
}
# Mutations
type Mutation {
createSubscription(input: CreateSubscriptionInput!): Subscription!
updateSubscription(id: ID!, input: UpdateSubscriptionInput!): Subscription!
deleteSubscription(id: ID!): Boolean!
updateQuotas(subscriptionId: ID!, quotas: QuotasInput!): Quotas!
addServiceBundle(subscriptionId: ID!, bundle: ServiceBundleInput!): ServiceBundle!
removeServiceBundle(subscriptionId: ID!, service: ServiceType!): Boolean!
addPolicyPack(subscriptionId: ID!, pack: PolicyPackInput!): PolicyPack!
removePolicyPack(subscriptionId: ID!, packId: ID!): Boolean!
}
REST Endpoints
# Subscription Management
POST /api/v1/subscription/subscriptions
GET /api/v1/subscription/subscriptions
GET /api/v1/subscription/subscriptions/{id}
PUT /api/v1/subscription/subscriptions/{id}
DELETE /api/v1/subscription/subscriptions/{id}
# Quotas
GET /api/v1/subscription/subscriptions/{id}/quotas
PUT /api/v1/subscription/subscriptions/{id}/quotas
GET /api/v1/subscription/subscriptions/{id}/quotas/check
# Service Bundles
POST /api/v1/subscription/subscriptions/{id}/service-bundles
DELETE /api/v1/subscription/subscriptions/{id}/service-bundles/{service}
# Policy Packs
POST /api/v1/subscription/subscriptions/{id}/policy-packs
DELETE /api/v1/subscription/subscriptions/{id}/policy-packs/{packId}
Example Queries
Create Subscription
mutation {
createSubscription(input: {
name: "production-subscription"
tenantId: "tenant-id"
type: PRODUCT
serviceBundles: [{
service: COMPUTE
enabled: true
quotas: {
vcpu: 100
memory: 512
instances: 50
}
}, {
service: STORAGE
enabled: true
quotas: {
total: 10000
perInstance: 500
}
}]
quotas: {
compute: {
vcpu: 100
memory: 512
instances: 50
}
storage: {
total: 10000
perInstance: 500
}
}
policyPacks: [{
name: "security-policy"
type: SECURITY
policies: []
enforcement: HARD
}]
}) {
id
name
type
serviceBundles {
service
enabled
}
}
}
IV. Environment Plane API
GraphQL Schema
# Environment Management
type Environment {
id: ID!
name: String!
type: EnvironmentType!
subscription: Subscription!
networkIsolation: NetworkIsolation!
dataIsolation: DataIsolation!
deploymentPolicies: [DeploymentPolicy!]!
runtimeSecrets: [Secret!]!
complianceOverlays: [ComplianceOverlay!]!
region: Region
promotionFlow: PromotionFlow
createdAt: DateTime!
updatedAt: DateTime!
metadata: JSON
}
enum EnvironmentType {
DEV
INT
UAT
STAGING
PROD
REGULATED
SOVEREIGN
AIR_GAPPED
}
# Queries
type Query {
environment(id: ID!): Environment
environments(filter: EnvironmentFilter): [Environment!]!
promotionFlow(environmentId: ID!): PromotionFlow
deploymentPolicies(environmentId: ID!): [DeploymentPolicy!]!
}
# Mutations
type Mutation {
createEnvironment(input: CreateEnvironmentInput!): Environment!
updateEnvironment(id: ID!, input: UpdateEnvironmentInput!): Environment!
deleteEnvironment(id: ID!): Boolean!
promoteArtifact(input: PromoteArtifactInput!): PromotionResult!
approvePromotion(promotionId: ID!, approved: Boolean!): PromotionResult!
configurePromotionFlow(environmentId: ID!, flow: PromotionFlowInput!): PromotionFlow!
addDeploymentPolicy(environmentId: ID!, policy: DeploymentPolicyInput!): DeploymentPolicy!
removeDeploymentPolicy(environmentId: ID!, policyId: ID!): Boolean!
}
REST Endpoints
# Environment Management
POST /api/v1/environment/environments
GET /api/v1/environment/environments
GET /api/v1/environment/environments/{id}
PUT /api/v1/environment/environments/{id}
DELETE /api/v1/environment/environments/{id}
# Promotion
POST /api/v1/environment/promotions
GET /api/v1/environment/promotions/{id}
POST /api/v1/environment/promotions/{id}/approve
POST /api/v1/environment/promotions/{id}/reject
# Deployment Policies
POST /api/v1/environment/environments/{id}/deployment-policies
GET /api/v1/environment/environments/{id}/deployment-policies
DELETE /api/v1/environment/environments/{id}/deployment-policies/{policyId}
Example Queries
Create Environment
mutation {
createEnvironment(input: {
name: "production-env"
subscriptionId: "subscription-id"
type: PROD
networkIsolation: {
vpcId: "vpc-id"
subnetIds: ["subnet-1", "subnet-2"]
firewallRules: []
}
dataIsolation: {
encryptionAtRest: true
encryptionInTransit: true
accessControls: []
}
deploymentPolicies: [{
name: "production-policy"
type: POLICY_DRIVEN
approvalRequired: true
approvers: ["release-manager-1", "release-manager-2"]
}]
region: "region-a"
}) {
id
name
type
region {
id
name
}
}
}
Promote Artifact
mutation {
promoteArtifact(input: {
artifactId: "artifact-id"
fromEnvironmentId: "staging-env-id"
toEnvironmentId: "prod-env-id"
metadata: {
version: "1.2.3"
changelog: "Production release"
}
}) {
id
status
approvalRequired
approvers
}
}
V. Content & DevOps Plane API
GraphQL Schema
# Content Hierarchy
type Enterprise {
id: ID!
name: String!
portfolios: [Portfolio!]!
ownership: Ownership!
governance: Governance!
createdAt: DateTime!
updatedAt: DateTime!
metadata: JSON
}
type Portfolio {
id: ID!
name: String!
enterprise: Enterprise!
products: [Product!]!
ownership: Ownership!
governance: Governance!
createdAt: DateTime!
updatedAt: DateTime!
metadata: JSON
}
type Product {
id: ID!
name: String!
portfolio: Portfolio!
applications: [Application!]!
ownership: Ownership!
governance: Governance!
createdAt: DateTime!
updatedAt: DateTime!
metadata: JSON
}
type Application {
id: ID!
name: String!
product: Product!
components: [Component!]!
gitRepos: [GitRepo!]!
ownership: Ownership!
governance: Governance!
createdAt: DateTime!
updatedAt: DateTime!
metadata: JSON
}
type Component {
id: ID!
name: String!
application: Application!
contentType: ContentType!
content: Content!
ownership: Ownership!
governance: Governance!
version: String!
lineage: [LineageEntry!]!
createdAt: DateTime!
updatedAt: DateTime!
metadata: JSON
}
enum ContentType {
SOURCE_CODE
IAC
PIPELINE
CONFIG_TEMPLATE
DOCUMENTATION
DATA_SCHEMA
AI_MODEL
PROMPT
}
# Queries
type Query {
enterprise(id: ID!): Enterprise
enterprises: [Enterprise!]!
portfolio(id: ID!): Portfolio
product(id: ID!): Product
application(id: ID!): Application
component(id: ID!): Component
gitRepo(id: ID!): GitRepo
gitRepos(filter: GitRepoFilter): [GitRepo!]!
}
# Mutations
type Mutation {
createEnterprise(input: CreateEnterpriseInput!): Enterprise!
createPortfolio(input: CreatePortfolioInput!): Portfolio!
createProduct(input: CreateProductInput!): Product!
createApplication(input: CreateApplicationInput!): Application!
createComponent(input: CreateComponentInput!): Component!
createGitRepo(input: CreateGitRepoInput!): GitRepo!
configureBranchProtection(repoId: ID!, branch: String!, protection: BranchProtectionInput!): BranchProtection!
}
REST Endpoints
# Content Hierarchy
POST /api/v1/content/enterprises
GET /api/v1/content/enterprises
GET /api/v1/content/enterprises/{id}
POST /api/v1/content/portfolios
GET /api/v1/content/portfolios/{id}
POST /api/v1/content/products
GET /api/v1/content/products/{id}
POST /api/v1/content/applications
GET /api/v1/content/applications/{id}
POST /api/v1/content/components
GET /api/v1/content/components/{id}
# Git Integration
POST /api/v1/content/git-repos
GET /api/v1/content/git-repos
GET /api/v1/content/git-repos/{id}
POST /api/v1/content/git-repos/{id}/branch-protection
Example Queries
Create Application
mutation {
createApplication(input: {
name: "web-application"
productId: "product-id"
ownership: {
owner: "dev-team"
team: "engineering"
contact: "dev-team@agency.gov"
}
governance: {
approvalWorkflows: [{
name: "code-review"
steps: [{
approver: "tech-lead"
role: "TECH_LEAD"
}]
required: true
}]
complianceTags: ["HIPAA", "SOC_2"]
}
}) {
id
name
product {
id
name
}
}
}
Create Git Repository
mutation {
createGitRepo(input: {
name: "web-application-repo"
applicationId: "application-id"
url: "https://git.sankofa.nexus/web-application"
branchStrategy: {
main: "main"
develop: "develop"
protectedBranches: ["main", "release/*"]
}
}) {
id
name
url
application {
id
name
}
}
}
VI. Authentication and Authorization
Authentication
All APIs use Keycloak for authentication:
# Authentication via Keycloak
# Token obtained from Keycloak OAuth2/OIDC flow
# Include in Authorization header: Bearer <token>
Authorization
Authorization is enforced via RBAC:
# RBAC roles per plane:
# Commercial: Finance Admin, Billing Viewer, Cost Center Owner
# Tenancy: Tenant Owner, Security Admin, Identity Admin, Compliance Officer
# Subscription: Subscription Owner, Platform Admin, Service Operator, Auditor
# Environment: Environment Owner, Release Manager, Operator, Observer
# Content: Enterprise Architect, Portfolio Lead, Product Owner, Dev Lead, Contributor, Reviewer, Release Approver
Example: Authenticated Request
curl -X POST https://api.phoenix.sankofa.nexus/graphql \
-H "Authorization: Bearer <keycloak-token>" \
-H "Content-Type: application/json" \
-d '{
"query": "query { tenant(id: \"tenant-id\") { id name } }"
}'
VII. Error Handling
Error Response Format
{
"errors": [
{
"message": "Error message",
"extensions": {
"code": "ERROR_CODE",
"field": "fieldName",
"resource": "ResourceType",
"resourceId": "resource-id"
}
}
],
"data": null
}
Common Error Codes
UNAUTHORIZED- Authentication requiredFORBIDDEN- Insufficient permissionsNOT_FOUND- Resource not foundVALIDATION_ERROR- Input validation failedQUOTA_EXCEEDED- Quota limit exceededPOLICY_VIOLATION- Policy violationCONFLICT- Resource conflictINTERNAL_ERROR- Internal server error
VIII. Rate Limiting
Rate Limits
- GraphQL: 1000 requests per minute per tenant
- REST: 500 requests per minute per tenant
- Billing Queries: 100 requests per minute per client
- Promotion Operations: 50 requests per minute per environment
Rate Limit Headers
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 950
X-RateLimit-Reset: 1640995200
IX. Pagination
GraphQL Pagination
type Query {
tenants(
filter: TenantFilter
pagination: PaginationInput
): TenantConnection!
}
type TenantConnection {
edges: [TenantEdge!]!
pageInfo: PageInfo!
totalCount: Int!
}
type TenantEdge {
node: Tenant!
cursor: String!
}
type PageInfo {
hasNextPage: Boolean!
hasPreviousPage: Boolean!
startCursor: String
endCursor: String
}
input PaginationInput {
first: Int
after: String
last: Int
before: String
}
REST Pagination
GET /api/v1/tenancy/tenants?page=1&pageSize=50
Response:
{
"data": [...],
"pagination": {
"page": 1,
"pageSize": 50,
"totalPages": 10,
"totalCount": 500,
"hasNext": true,
"hasPrevious": false
}
}
X. Webhooks and Subscriptions
GraphQL Subscriptions
type Subscription {
clientUpdated(clientId: ID!): Client!
tenantUpdated(tenantId: ID!): Tenant!
subscriptionUpdated(subscriptionId: ID!): Subscription!
environmentUpdated(environmentId: ID!): Environment!
promotionStatusChanged(promotionId: ID!): PromotionResult!
quotaExceeded(subscriptionId: ID!): QuotaAlert!
}
REST Webhooks
POST /api/v1/webhooks
GET /api/v1/webhooks
PUT /api/v1/webhooks/{id}
DELETE /api/v1/webhooks/{id}
Webhook Events:
client.createdclient.updatedtenant.createdtenant.updatedsubscription.createdsubscription.updatedenvironment.createdenvironment.updatedpromotion.startedpromotion.approvedpromotion.rejectedquota.exceeded
XI. Multi-Region Support
Regional API Endpoints
# Primary region
https://api.phoenix.sankofa.nexus
# Regional endpoints
https://api-region-a.phoenix.sankofa.nexus
https://api-region-b.phoenix.sankofa.nexus
https://api-region-c.phoenix.sankofa.nexus
Cross-Region Operations
mutation {
createCrossRegionSubscription(input: {
name: "multi-region-sub"
tenantId: "tenant-id"
regions: ["region-a", "region-b"]
regionalQuotas: {
"region-a": {
compute: { vcpu: 50, memory: 256 }
}
"region-b": {
compute: { vcpu: 50, memory: 256 }
}
}
}) {
id
name
regions {
id
name
}
}
}
References
- Operating Model - Complete operating model documentation
- MVP Control Plane - MVP API requirements
- Architecture Diagrams - API integration diagrams
Last Updated: 2025-01-09
Version: 1.0
Status: Complete API Specification