Skip to main content

Overview

The Control Plane API provides programmatic access to SO1’s orchestration layer, allowing you to execute agents, manage workflows, trigger automations, and monitor system health.
Base URL: https://api.so1.io/v1/control-planeAll Control Plane endpoints require authentication via Bearer token.

API Architecture

The Control Plane API is organized into four main categories:

Quick Start

Execute an Agent

curl -X POST https://api.so1.io/v1/control-plane/agents/execute \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agentId": "mintlify-author",
    "taskType": "create-agent-reference",
    "context": {
      "agentName": "workflow-architect",
      "sourcePath": "/agents/automation/workflow-architect.md"
    },
    "forge": {
      "stage": "IMPLEMENT",
      "validateGates": true
    }
  }'

Trigger a Workflow

curl -X POST https://api.so1.io/v1/control-plane/workflows/trigger \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "workflowId": "deployment-pipeline",
    "environment": "production",
    "payload": {
      "service": "api-gateway",
      "version": "v2.4.1"
    }
  }'

Check Orchestration Status

curl -X GET https://api.so1.io/v1/control-plane/orchestration/status/orch-abc123 \
  -H "Authorization: Bearer YOUR_API_KEY"

Authentication

All Control Plane API requests require a valid API key passed as a Bearer token:
Authorization: Bearer so1_key_abc123xyz789
Keep Your API Keys Secret: Never commit API keys to version control or expose them in client-side code.
See Authentication for detailed API key management.

Common Request Patterns

Synchronous vs Asynchronous Execution

Most Control Plane operations are asynchronous by default, returning immediately with a task ID:
const response = await fetch('https://api.so1.io/v1/control-plane/agents/execute', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${API_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    agentId: 'hono-backend',
    taskType: 'implement-endpoint',
    context: { endpoint: '/api/users', method: 'POST' }
  })
});

const { taskId, status } = await response.json();
// Returns immediately with taskId: "task-xyz789"
// Poll /tasks/{taskId} for completion
Timeout Limits: Synchronous requests have a maximum timeout of 5 minutes (300 seconds). For long-running operations, use asynchronous mode.

Polling for Results

For asynchronous operations, poll the task status endpoint:
async function waitForCompletion(taskId: string): Promise<any> {
  const maxAttempts = 60; // 5 minutes with 5s intervals
  
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
    const response = await fetch(
      `https://api.so1.io/v1/control-plane/tasks/${taskId}`,
      { headers: { 'Authorization': `Bearer ${API_KEY}` } }
    );
    
    const task = await response.json();
    
    if (task.status === 'completed') {
      return task.result;
    } else if (task.status === 'failed') {
      throw new Error(task.error.message);
    }
    
    // Still running, wait and retry
    await new Promise(resolve => setTimeout(resolve, 5000));
  }
  
  throw new Error('Task timeout after 5 minutes');
}

const taskId = 'task-xyz789';
const result = await waitForCompletion(taskId);

Webhooks for Completion Notifications

Instead of polling, register a webhook to receive completion notifications:
const response = await fetch('https://api.so1.io/v1/control-plane/agents/execute', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${API_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    agentId: 'railway-deployer',
    taskType: 'deploy-service',
    context: { service: 'api', environment: 'production' },
    webhook: {
      url: 'https://your-app.com/webhooks/so1',
      events: ['task.completed', 'task.failed'],
      secret: 'whsec_abc123xyz789'
    }
  })
});
Your webhook endpoint will receive:
{
  "event": "task.completed",
  "taskId": "task-xyz789",
  "agentId": "railway-deployer",
  "timestamp": "2024-03-10T15:30:00Z",
  "result": {
    "deploymentId": "dep-abc123",
    "status": "live",
    "url": "https://api-production.railway.app"
  }
}
See Webhook Security for signature verification.

Response Format

All Control Plane API responses follow a consistent format:

Success Response

{
  "success": true,
  "data": {
    "taskId": "task-xyz789",
    "status": "running",
    "createdAt": "2024-03-10T15:30:00Z"
  },
  "meta": {
    "requestId": "req-abc123",
    "timestamp": "2024-03-10T15:30:00.123Z"
  }
}

Error Response

{
  "success": false,
  "error": {
    "code": "AGENT_NOT_FOUND",
    "message": "Agent 'invalid-agent' does not exist",
    "details": {
      "agentId": "invalid-agent",
      "availableAgents": ["mintlify-author", "hono-backend", "..."]
    }
  },
  "meta": {
    "requestId": "req-abc123",
    "timestamp": "2024-03-10T15:30:00.123Z"
  }
}

Rate Limits

Control Plane API endpoints have tier-based rate limits:
TierRequests/MinConcurrent Executions
Free102
Starter6010
Professional30050
Enterprise1,000200
See Rate Limits for detailed policies.

SDKs and Libraries

Official SDKs are available for popular languages:

SDK Example

import { SO1 } from '@so1/sdk';

const client = new SO1({
  apiKey: process.env.SO1_API_KEY
});

const execution = await client.agents.execute({
  agentId: 'mintlify-author',
  taskType: 'create-agent-reference',
  context: {
    agentName: 'workflow-architect',
    sourcePath: '/agents/automation/workflow-architect.md'
  }
});

console.log(`Task ID: ${execution.taskId}`);

// Wait for completion
const result = await execution.waitForCompletion();
console.log('Agent output:', result.output);

API Endpoints