https://kiro.sovereignroute.comThe Kiro Sync API is a bidirectional synchronization service that maintains context continuity between the Kiro IDE (running on your local Mac) and the Kiro server-side agent. This ensures that regardless of where you interact with Kiroβthrough the IDE or directly via CLIβall conversation history, documents, and command state remain perfectly synchronized.
βββββββββββββββββββ HTTPS/TLS ββββββββββββββββββββ
β Kiro IDE βββββββββββββββββββββββββββββΊβ Sync Server β
β (Mac Local) β Bearer Auth Required β (Linux Remote) β
βββββββββββββββββββ ββββββββββββββββββββ
β β
β Initiates Commands β Executes Commands
β Syncs Conversations β Syncs Results
β Pushes Documents β Stores State
β β
βββββββββββββββββββββββββββββββββββββββββββββββββ
Shared Context & State
All API endpoints (except / and /docs) require Bearer token authentication.
Authorization: Bearer YOUR_TOKEN_HERE
curl -H "Authorization: Bearer YOUR_TOKEN" \
https://kiro.sovereignroute.com/sync
/sync
Fetches the complete current state including all conversations, documents, and pending commands.
Use Cases:
Request:
GET /sync HTTP/1.1
Host: kiro.sovereignroute.com
Authorization: Bearer YOUR_TOKEN
Response (200 OK):
{
"conversations": {
"conv-abc123": [
{
"role": "user",
"content": "Create a sync API",
"timestamp": 1710338438173
},
{
"role": "assistant",
"content": "I'll create the sync API...",
"timestamp": 1710338445230
}
]
},
"documents": {
"doc-xyz789": {
"path": "/home/user/project/server.js",
"content": "const http = require('http');...",
"timestamp": 1710338450000
}
},
"commands": {
"cmd-1710338460000-abc": {
"type": "execute_bash",
"command": "ls -la",
"status": "completed",
"result": "total 48\ndrwxr-xr-x...",
"createdAt": 1710338460000,
"updatedAt": 1710338461500
}
},
"lastUpdate": 1710338461500
}
/sync
Uploads local state to the server. Server performs timestamp-based merge.
Use Cases:
Request:
POST /sync HTTP/1.1
Host: kiro.sovereignroute.com
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json
{
"conversations": { /* ... */ },
"documents": { /* ... */ },
"commands": { /* ... */ },
"lastUpdate": 1710338470000
}
Response (200 OK):
{
"status": "updated", // or "current" if server data is newer
"data": {
// Complete merged state
}
}
Merge Logic:
client.lastUpdate > server.lastUpdate β Server accepts client dataserver.lastUpdate >= client.lastUpdate β Server returns its data (client should update)Commands enable the IDE to request server-side operations that require direct system access, such as file operations, bash execution, or AWS API calls.
/command
Creates a new command in the queue for the server agent to process.
Use Cases:
Request:
POST /command HTTP/1.1
Host: kiro.sovereignroute.com
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json
{
"type": "execute_bash",
"command": "df -h",
"workingDir": "/home/openclaw",
"metadata": {
"initiatedBy": "ide",
"conversationId": "conv-abc123"
}
}
Response (200 OK):
{
"commandId": "cmd-1710338480000-xyz789",
"status": "pending"
}
Command Types:
| Type | Description | Required Fields |
|---|---|---|
execute_bash | Run bash command | command |
read_file | Read file contents | path |
write_file | Write/create file | path, content |
list_directory | List directory contents | path |
aws_operation | AWS CLI operation | service, operation, parameters |
code_search | Search codebase | query |
/command/{commandId}
Retrieves the current status and result of a specific command.
Request:
GET /command/cmd-1710338480000-xyz789 HTTP/1.1
Host: kiro.sovereignroute.com
Authorization: Bearer YOUR_TOKEN
Response (200 OK):
{
"type": "execute_bash",
"command": "df -h",
"status": "completed",
"result": {
"stdout": "Filesystem Size Used Avail Use% Mounted on...",
"stderr": "",
"exitCode": 0
},
"createdAt": 1710338480000,
"updatedAt": 1710338481200
}
Status Values:
pending - Command queued, waiting for agentprocessing - Agent is executing the commandcompleted - Successfully finishedfailed - Execution failed (check error field)/command/{commandId}
Used by the server agent to update command status and results. IDE typically doesn't call this directly.
Request:
PATCH /command/cmd-1710338480000-xyz789 HTTP/1.1
Host: kiro.sovereignroute.com
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json
{
"status": "completed",
"result": {
"stdout": "...",
"exitCode": 0
}
}
Response (200 OK):
{
// Updated command object
}
{
"conversations": {
"[conversationId]": [
{
"role": "user" | "assistant" | "system",
"content": "string",
"timestamp": number,
"metadata": object (optional)
}
]
},
"documents": {
"[documentId]": {
"path": "string (optional)",
"content": "string",
"language": "string (optional)",
"timestamp": number
}
},
"commands": {
"[commandId]": {
"type": "string",
"status": "pending" | "processing" | "completed" | "failed",
"result": any,
"error": "string (if failed)",
"createdAt": number,
"updatedAt": number,
// ... command-specific fields
}
},
"lastUpdate": number
}
All timestamps are Unix time in milliseconds (JavaScript Date.now() format).
const timestamp = Date.now(); // 1710338438173
1. IDE starts
2. GET /sync β Retrieve all conversations, documents, commands
3. Restore UI state from synced data
4. Start periodic sync polling (every 30s)
1. User types message in IDE
2. IDE adds message to local conversations object
3. POST /sync with updated conversations
4. Server merges and returns latest state
5. IDE updates UI if server had newer data
1. User requests "list files in /home/openclaw"
2. IDE: POST /command with type="execute_bash", command="ls -la /home/openclaw"
3. Server responds with commandId
4. IDE: Poll GET /command/{commandId} every 1-2 seconds
5. When status="completed", display result to user
6. IDE: POST /sync to update conversation with result
1. Agent: GET /sync periodically (every 5-10s)
2. Check for commands with status="pending"
3. For each pending command:
a. PATCH /command/{id} with status="processing"
b. Execute the operation
c. PATCH /command/{id} with status="completed" and result
4. POST /sync to update lastUpdate timestamp
class KiroSyncClient {
constructor(token) {
this.baseUrl = 'https://kiro.sovereignroute.com';
this.token = token;
this.headers = {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
};
}
async getSync() {
const res = await fetch(`${this.baseUrl}/sync`, {
headers: this.headers
});
return res.json();
}
async pushSync(data) {
const res = await fetch(`${this.baseUrl}/sync`, {
method: 'POST',
headers: this.headers,
body: JSON.stringify(data)
});
return res.json();
}
async submitCommand(command) {
const res = await fetch(`${this.baseUrl}/command`, {
method: 'POST',
headers: this.headers,
body: JSON.stringify(command)
});
return res.json();
}
async getCommand(commandId) {
const res = await fetch(`${this.baseUrl}/command/${commandId}`, {
headers: this.headers
});
return res.json();
}
async waitForCommand(commandId, timeout = 30000) {
const start = Date.now();
while (Date.now() - start < timeout) {
const cmd = await this.getCommand(commandId);
if (cmd.status === 'completed' || cmd.status === 'failed') {
return cmd;
}
await new Promise(r => setTimeout(r, 1000));
}
throw new Error('Command timeout');
}
}
// Usage
const client = new KiroSyncClient('YOUR_TOKEN');
// Pull sync data
const data = await client.getSync();
// Submit command
const { commandId } = await client.submitCommand({
type: 'execute_bash',
command: 'ls -la'
});
// Wait for result
const result = await client.waitForCommand(commandId);
console.log(result.result.stdout);
import requests
import time
class KiroSyncClient:
def __init__(self, token):
self.base_url = 'https://kiro.sovereignroute.com'
self.headers = {
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
def get_sync(self):
r = requests.get(f'{self.base_url}/sync', headers=self.headers)
return r.json()
def push_sync(self, data):
r = requests.post(f'{self.base_url}/sync',
headers=self.headers, json=data)
return r.json()
def submit_command(self, command):
r = requests.post(f'{self.base_url}/command',
headers=self.headers, json=command)
return r.json()
def get_command(self, command_id):
r = requests.get(f'{self.base_url}/command/{command_id}',
headers=self.headers)
return r.json()
def wait_for_command(self, command_id, timeout=30):
start = time.time()
while time.time() - start < timeout:
cmd = self.get_command(command_id)
if cmd['status'] in ['completed', 'failed']:
return cmd
time.sleep(1)
raise TimeoutError('Command timeout')
# Usage
client = KiroSyncClient('YOUR_TOKEN')
data = client.get_sync()
result = client.submit_command({'type': 'execute_bash', 'command': 'pwd'})
cmd = client.wait_for_command(result['commandId'])
print(cmd['result']['stdout'])
# Get sync data
curl -H "Authorization: Bearer YOUR_TOKEN" \
https://kiro.sovereignroute.com/sync
# Push sync data
curl -X POST \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"conversations":{},"documents":{},"lastUpdate":1710338438173}' \
https://kiro.sovereignroute.com/sync
# Submit command
curl -X POST \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"type":"execute_bash","command":"uptime"}' \
https://kiro.sovereignroute.com/command
# Check command status
curl -H "Authorization: Bearer YOUR_TOKEN" \
https://kiro.sovereignroute.com/command/cmd-1710338480000-xyz789
| Code | Meaning | Response |
|---|---|---|
| 200 | Success | JSON with requested data |
| 401 | Unauthorized | {"error": "Unauthorized"} |
| 404 | Not Found | {"error": "Command not found"} or plain text |
| 500 | Server Error | JSON with error details |
// Always check the response status
const response = await client.pushSync(localData);
if (response.status === 'current') {
// Server has newer data, update local state
localData = response.data;
updateUI(localData);
} else if (response.status === 'updated') {
// Server accepted our update
console.log('Sync successful');
}
const cmd = await client.waitForCommand(commandId);
if (cmd.status === 'failed') {
console.error('Command failed:', cmd.error);
// Show error to user
} else {
// Process successful result
processResult(cmd.result);
}
/var/log/kiro-sync/