A API REST do Sofia AI permite integrar agentes e orquestracoes de IA em qualquer aplicacao, seja ela web, mobile ou backend. Neste guia completo, vamos cobrir desde a autenticacao basica ate casos de uso avancados com exemplos praticos em cURL, JavaScript e Python.
Prerequisitos
Antes de comecar, voce precisa:
- Uma conta no Sofia AI
- Uma API key gerada em
/dashboard/api-keys - Pelo menos um agente ou orquestracao configurado
Autenticacao
Todas as requisicoes a API v1 exigem autenticacao via Bearer token no header Authorization:
Authorization: Bearer sk_live_sua_api_key_aqui
Exemplo basico:
curl -H "Authorization: Bearer sk_live_abc123..." \
https://sofiaia.roilabs.com.br/api/v1/agents
Gerando sua API Key
- Acesse
/dashboard/api-keys - Clique em "Nova chave"
- Defina um nome descritivo (ex: "Integracao Producao")
- Copie a chave gerada — ela so sera exibida uma vez
Endpoints Disponiveis
Agentes
Listar Agentes
GET /api/v1/agents
cURL:
curl -H "Authorization: Bearer sk_live_..." \
https://sofiaia.roilabs.com.br/api/v1/agents
Resposta:
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Atendimento ao Cliente",
"description": "Agente especializado em suporte",
"model": "llama-3.3-70b-versatile",
"status": "active",
"memoryEnabled": true,
"createdAt": "2026-01-15T10:00:00Z"
}
],
"total": 1
}
Chat com Agente
POST /api/v1/agents/{agentId}/chat
JavaScript:
const response = await fetch(
'https://sofiaia.roilabs.com.br/api/v1/agents/AGENT_ID/chat',
{
method: 'POST',
headers: {
'Authorization': 'Bearer sk_live_...',
'Content-Type': 'application/json',
},
body: JSON.stringify({
message: 'Olá! Preciso de ajuda com minha assinatura.',
conversationId: 'sessao-usuario-123', // opcional, para manter contexto
}),
}
);
const { reply, conversationId, tokens } = await response.json();
console.log('Resposta:', reply);
console.log('Tokens usados:', tokens);
Python:
import requests
response = requests.post(
'https://sofiaia.roilabs.com.br/api/v1/agents/AGENT_ID/chat',
headers={
'Authorization': 'Bearer sk_live_...',
'Content-Type': 'application/json',
},
json={
'message': 'Como posso cancelar minha assinatura?',
'conversationId': 'sessao-python-001',
}
)
data = response.json()
print(f"Resposta: {data['reply']}")
print(f"Tokens: {data['tokens']}")
Orquestracoes
Listar Orquestracoes
GET /api/v1/orchestrations
Executar Orquestracao
POST /api/v1/orchestrations/{orchestrationId}/execute
Body:
{
"input": "Texto de entrada para a orquestracao",
"variables": {
"variavel1": "valor1",
"variavel2": "valor2"
}
}
Resposta (202 Accepted):
{
"executionId": "exec-550e8400-e29b-41d4-a716",
"status": "pending",
"orchestrationId": "ORCH_ID"
}
A execucao e assincrona — voce recebe um executionId e precisa consultar o status separadamente.
Consultar Status da Execucao
GET /api/v1/executions/{executionId}
Resposta:
{
"id": "exec-uuid",
"orchestrationId": "ORCH_ID",
"status": "completed",
"output": "Relatorio gerado com sucesso...",
"tokensUsed": 3847,
"durationMs": 12430,
"createdAt": "2026-02-24T10:00:00Z",
"completedAt": "2026-02-24T10:00:12Z"
}
Status possiveis:
pending— na fila, aguardando iniciorunning— em execucaocompleted— finalizado com sucessofailed— falhou, verifiqueerrorcancelled— cancelado pelo usuario
Implementando Polling
Como as execucoes sao assincronas, voce precisa implementar polling:
JavaScript (completo):
const API_KEY = 'sk_live_...';
const BASE_URL = 'https://sofiaia.roilabs.com.br';
async function runOrchestration(orchestrationId, input) {
// 1. Iniciar execucao
const startRes = await fetch(
`${BASE_URL}/api/v1/orchestrations/${orchestrationId}/execute`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ input }),
}
);
const { executionId } = await startRes.json();
console.log(`Execucao iniciada: ${executionId}`);
// 2. Aguardar conclusao via polling
const MAX_ATTEMPTS = 60; // 5 minutos (60 x 5s)
for (let i = 0; i < MAX_ATTEMPTS; i++) {
await new Promise(r => setTimeout(r, 5000)); // aguarda 5s
const statusRes = await fetch(
`${BASE_URL}/api/v1/executions/${executionId}`,
{ headers: { 'Authorization': `Bearer ${API_KEY}` } }
);
const execution = await statusRes.json();
if (execution.status === 'completed') {
console.log(`Concluido em ${execution.durationMs}ms`);
return execution.output;
}
if (execution.status === 'failed') {
throw new Error(`Execucao falhou: ${execution.error}`);
}
console.log(`Status: ${execution.status} (tentativa ${i + 1}/${MAX_ATTEMPTS})`);
}
throw new Error('Timeout: execucao demorou mais de 5 minutos');
}
// Uso
const output = await runOrchestration(
'minha-orch-id',
'Analise as vendas de janeiro e gere um relatorio executivo'
);
console.log('Output:', output);
Python com tenacity:
import requests
import time
API_KEY = 'sk_live_...'
BASE_URL = 'https://sofiaia.roilabs.com.br'
def run_orchestration(orchestration_id: str, input_text: str) -> str:
headers = {'Authorization': f'Bearer {API_KEY}', 'Content-Type': 'application/json'}
# Iniciar execucao
response = requests.post(
f'{BASE_URL}/api/v1/orchestrations/{orchestration_id}/execute',
headers=headers,
json={'input': input_text}
)
response.raise_for_status()
execution_id = response.json()['executionId']
print(f'Execucao iniciada: {execution_id}')
# Polling
for attempt in range(60):
time.sleep(5)
status_response = requests.get(
f'{BASE_URL}/api/v1/executions/{execution_id}',
headers=headers
)
execution = status_response.json()
if execution['status'] == 'completed':
print(f"Concluido em {execution['durationMs']}ms")
return execution['output']
if execution['status'] == 'failed':
raise Exception(f"Execucao falhou: {execution.get('error', 'unknown')}")
print(f"Status: {execution['status']} (tentativa {attempt + 1}/60)")
raise TimeoutError('Execucao demorou mais de 5 minutos')
# Uso
output = run_orchestration('minha-orch-id', 'Analise as vendas e gere relatorio')
print('Output:', output)
Tratamento de Erros
Erros Comuns
| Codigo | Situacao | Solucao | |--------|---------|---------| | 401 | API key invalida | Verifique a chave e regenere se necessario | | 403 | Sem permissao | Verifique se o recurso pertence ao seu tenant | | 404 | Recurso nao encontrado | Confirme o ID do agente/orquestracao | | 429 | Rate limit atingido | Implemente retry com backoff exponencial | | 500 | Erro interno | Aguarde e tente novamente, abra ticket se persistir |
Retry com Backoff Exponencial
async function fetchWithRetry(url, options, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fetch(url, options);
if (response.ok) return response;
if (response.status === 429) {
// Rate limit: esperar e tentar novamente
const waitMs = Math.pow(2, attempt) * 1000;
console.log(`Rate limited. Aguardando ${waitMs}ms...`);
await new Promise(r => setTimeout(r, waitMs));
continue;
}
if (response.status >= 500 && attempt < maxRetries - 1) {
// Erro do servidor: retry
const waitMs = Math.pow(2, attempt) * 1000;
await new Promise(r => setTimeout(r, waitMs));
continue;
}
// Outros erros: nao fazer retry
throw new Error(`API error ${response.status}`);
}
throw new Error('Max retries exceeded');
}
SDK Oficial JavaScript
Para simplificar a integracao, use nosso SDK oficial:
npm install sofia-ai
import { SofiaClient } from 'sofia-ai';
const client = new SofiaClient({ apiKey: 'sk_live_...' });
// Chat simples
const { reply } = await client.chat('agent-id', 'Ola!');
// Execucao com aguardo automatico
const result = await client.executeAndWait('orch-id', 'Gere um relatorio');
console.log(result.output);
O SDK gerencia automaticamente polling, retries e formatacao de erros.
Rate Limits por Plano
| Plano | Requisicoes/dia | Concorrencia | |-------|----------------|--------------| | Free | 100 | 1 | | Pro | 10.000 | 5 | | Business | Ilimitado | 20 |
Conclusao
A API REST do Sofia AI oferece uma forma poderosa e flexivel de integrar IA em qualquer aplicacao. Com suporte a agentes de chat, orquestracoes multiplos-agentes e execucoes agendadas, voce tem todas as ferramentas necessarias para construir fluxos de automacao sofisticados.
Proximos passos:
Precisa de ajuda? Entre em contato com nossa equipe tecnica.