Skip to content

Rastreamento de Requisições e Custos

O SipPulse AI fornece um sistema completo de rastreamento de requisições que permite monitorar custos, performance e uso de cada chamada de API individualmente. Isso é especialmente útil para:

  • Controle de custos por cliente ou projeto
  • Relatórios de uso detalhados
  • Repasse de custos para clientes finais

O que é o x-request-id?

Toda requisição de consumo (TTS, ASR, LLM, etc.) retorna um header HTTP chamado x-request-id. Este identificador único permite rastrear os custos e métricas específicas daquela requisição.

Formato do ID

O ID segue o padrão: req_ + 32 caracteres alfanuméricos

Exemplo: req_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6


Rotas que Retornam x-request-id

RotaMétodoTipo de RespostaDescrição
/audio/speechPOSTStreamingText-to-Speech (compatível OpenAI)
/tts/generatePOSTJSONText-to-Speech
/asr/transcribePOSTJSONSpeech-to-Text
/audio/transcriptionsPOSTJSONSpeech-to-Text (compatível OpenAI)
/llms/completionPOSTStreamingGeração de texto LLM
/chat/completionsPOSTStreamingChat LLM (compatível OpenAI)
/text-inteligencePOSTJSONAnálise de texto
/anonymizePOSTJSONAnonimização de texto

Como Extrair o x-request-id

javascript
const response = await fetch('https://api.sippulse.ai/tts/generate', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer seu_token',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    model: 'openai-tts-1',
    input: 'Olá, como posso ajudar?',
    voice: 'alloy'
  })
});

// Extrair o request ID do header
const requestId = response.headers.get('x-request-id');
console.log('Request ID:', requestId);

const data = await response.json();
python
import requests

response = requests.post(
    'https://api.sippulse.ai/tts/generate',
    headers={
        'Authorization': 'Bearer seu_token',
        'Content-Type': 'application/json'
    },
    json={
        'model': 'openai-tts-1',
        'input': 'Olá, como posso ajudar?',
        'voice': 'alloy'
    }
)

# Extrair o request ID do header
request_id = response.headers.get('x-request-id')
print(f'Request ID: {request_id}')

data = response.json()
bash
curl -i -X POST https://api.sippulse.ai/tts/generate \
  -H "Authorization: Bearer seu_token" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai-tts-1",
    "input": "Olá, como posso ajudar?",
    "voice": "alloy"
  }'

# O header x-request-id aparecerá na resposta

Consultando Detalhes de Uso

Com o request_id em mãos, você pode consultar os detalhes completos de custo e performance:

GET https://api.sippulse.ai/usage-requests/{request_id}

Processamento Assíncrono

O cálculo de custos e a cobrança são processados de forma assíncrona. Isso significa que imediatamente após receber o x-request-id, os detalhes de uso podem ainda não estar disponíveis (tipicamente um delay de alguns milissegundos).

Para acesso programático, considere implementar um pequeno delay ou lógica de retry para garantir que você obtenha os dados corretamente.

Exemplo de Implementação com Retry

Ao consultar detalhes de uso de forma programática, é recomendado implementar um mecanismo de retry:

javascript
async function getUsageWithRetry(requestId, maxRetries = 3, delayMs = 100) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const response = await fetch(
        `https://api.sippulse.ai/usage-requests/${requestId}`,
        { headers: { 'Authorization': 'Bearer seu_token' } }
      );

      if (response.ok) {
        const data = await response.json();
        // Verifica se os dados de custo estão disponíveis
        if (data.total_price_local !== undefined) {
          return data;
        }
      }

      // Aguarda antes de tentar novamente (backoff exponencial)
      if (attempt < maxRetries) {
        await new Promise(resolve => setTimeout(resolve, delayMs * attempt));
      }
    } catch (error) {
      if (attempt === maxRetries) throw error;
    }
  }

  throw new Error(`Falha ao obter uso após ${maxRetries} tentativas`);
}

// Uso
const usage = await getUsageWithRetry('req_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6');
console.log('Custo:', usage.total_price_local);
python
import time
import requests

def get_usage_with_retry(request_id, max_retries=3, delay_ms=100):
    for attempt in range(1, max_retries + 1):
        try:
            response = requests.get(
                f'https://api.sippulse.ai/usage-requests/{request_id}',
                headers={'Authorization': 'Bearer seu_token'}
            )

            if response.ok:
                data = response.json()
                # Verifica se os dados de custo estão disponíveis
                if data.get('total_price_local') is not None:
                    return data

            # Aguarda antes de tentar novamente (backoff exponencial)
            if attempt < max_retries:
                time.sleep((delay_ms * attempt) / 1000)

        except Exception as e:
            if attempt == max_retries:
                raise e

    raise Exception(f'Falha ao obter uso após {max_retries} tentativas')

# Uso
usage = get_usage_with_retry('req_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6')
print(f"Custo: {usage['total_price_local']}")

Exemplo de Requisição

bash
curl -X GET https://api.sippulse.ai/usage-requests/req_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6 \
  -H "Authorization: Bearer seu_token"

Exemplo de Resposta

json
{
  "id": "req_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
  "organization_id": "org_xxxx",
  "user_id": "usr_yyyy",
  "agent_id": "agt_zzzz",
  "thread_id": "thr_wwww",
  "project_id": null,
  "auth_mode": "jwt",
  "created_at": "2026-01-07T10:30:45.000Z",
  "event_timestamp": "2026-01-07T10:30:45.000Z",
  "updated_at": "2026-01-07T10:30:47.000Z",
  "execution_time_ms": 2350,
  "processing_time_ms": 50,
  "total_price_local": 0.0025,
  "speed": 10.21,
  "items": [
    {
      "type": "model",
      "subtype": "text-to-speech",
      "identifier": "openai-tts-1",
      "pricing_rule": "tts_char",
      "amount": 24,
      "unit_price": 0.0001,
      "total_price": 0.0024,
      "performance": {
        "execution_time_ms": 2350,
        "throughput": 10.21,
        "is_cached": false
      }
    }
  ]
}

Estrutura da Resposta

Campos Principais

CampoTipoDescrição
idstringID único da requisição
organization_idstringID da organização
user_idstringID do usuário que fez a requisição
agent_idstringID do agente (se aplicável)
thread_idstringID da thread de conversa (se aplicável)
auth_modestringTipo de autenticação: jwt, api_key, guest_token
execution_time_msnumberTempo de execução em milissegundos
processing_time_msnumberTempo de processamento/setup em milissegundos
total_price_localnumberCusto total na moeda local (BRL)
speednumberThroughput (tokens/s, caracteres/s, etc.)

Campos de Items

Cada item representa um componente de custo da requisição:

CampoTipoDescrição
typestringTipo do recurso: model, feature, etc.
subtypestringSubtipo: text-to-speech, speech-to-text, llm, etc.
identifierstringIdentificador do modelo/recurso usado
pricing_rulestringRegra de cobrança aplicada
amountnumberQuantidade consumida
unit_pricenumberPreço por unidade
total_pricenumberPreço total do item

Casos de Uso

1. Repasse de Custos para Clientes

Armazene o request_id junto com o identificador do seu cliente:

javascript
async function processRequest(clientId, text) {
  const response = await ttsGenerate(text);
  const requestId = response.headers.get('x-request-id');

  // Salvar no banco de dados
  await db.usageLog.create({
    client_id: clientId,
    request_id: requestId,
    timestamp: new Date()
  });

  return response;
}

// Depois, para gerar relatório de custos:
async function generateClientReport(clientId) {
  const logs = await db.usageLog.findByClientId(clientId);

  let totalCost = 0;
  for (const log of logs) {
    const usage = await fetch(`/usage-requests/${log.request_id}`);
    totalCost += usage.total_price_local;
  }

  return totalCost;
}

2. Monitoramento de Performance

Acompanhe métricas de performance:

javascript
const response = await asrTranscribe(audioFile);
const requestId = response.headers.get('x-request-id');

const usage = await getUsageRequest(requestId);
const metrics = {
  executionTime: usage.execution_time_ms,
  throughput: usage.speed,
  cost: usage.total_price_local
};

// Enviar para sistema de monitoramento
monitoring.track('asr_performance', metrics);

Boas Práticas

  1. Sempre armazene o request_id para requisições importantes que você pode precisar auditar
  2. Não exponha request_ids para usuários finais, pois eles permitem acesso a informações de custo
  3. Implemente rate limiting baseado nos custos consultados
  4. Configure alertas para requisições com custo acima do esperado

Próximos Passos