Skip to main content

Introdução

A API REST do Testly permite que você integre experimentação A/B em qualquer aplicação, independente do framework ou linguagem.

Quando usar a API diretamente?

  • ✅ Você está usando um framework não suportado (Vue, Svelte, Angular)
  • ✅ Precisa de integração server-side
  • ✅ Quer construir sua própria camada de abstração
  • ✅ Está migrando de outra ferramenta

Quando usar o SDK React?

  • ✅ Você está usando React, Next.js ou Remix
  • ✅ Quer começar rápido sem configuração
  • ✅ Precisa de gerenciamento automático de estado
Recomendação: Se você usa React, prefira o SDK oficial. Ele já implementa boas práticas de cache, retry e error handling.

Base URL

https://api.testly.com/v1
Todas as requisições devem usar HTTPS. HTTP não é suportado.

Autenticação

A API do Testly usa API Keys para autenticação. Inclua sua chave no header Authorization:
Authorization: Bearer YOUR_API_KEY

Obter sua API Key

  1. Acesse o dashboard do Testly
  2. Vá em ConfiguraçõesAPI Keys
  3. Copie sua chave (começa com testly_)
Segurança: Nunca exponha sua API Key em código client-side público. Use variáveis de ambiente e mantenha-a no servidor quando possível.

Exemplo de Requisição

curl https://api.testly.com/v1/experiments \
  -H "Authorization: Bearer testly_abc123xyz..." \
  -H "Content-Type: application/json"

Rate Limits

PlanoLimite
Free100 requisições/minuto
Pro1.000 requisições/minuto
EnterpriseCustomizável
Headers de resposta incluem informações sobre rate limit:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640995200
Se exceder o limite, você receberá um erro 429 Too Many Requests. Implemente retry com backoff exponencial.

Estrutura da Resposta

Sucesso

Requisições bem-sucedidas retornam JSON com status 2xx:
{
  "success": true,
  "data": {
    // Dados da resposta
  }
}

Erro

Erros retornam JSON com status 4xx ou 5xx:
{
  "success": false,
  "error": {
    "code": "INVALID_API_KEY",
    "message": "A API Key fornecida é inválida",
    "details": {}
  }
}

Códigos de Status HTTP

CódigoDescrição
200 OKRequisição bem-sucedida
201 CreatedRecurso criado com sucesso
400 Bad RequestParâmetros inválidos
401 UnauthorizedAPI Key ausente ou inválida
403 ForbiddenSem permissão para acessar o recurso
404 Not FoundRecurso não encontrado
429 Too Many RequestsRate limit excedido
500 Internal Server ErrorErro no servidor (contacte suporte)

Códigos de Erro Comuns

INVALID_API_KEY

{
  "code": "INVALID_API_KEY",
  "message": "A API Key fornecida é inválida ou expirou"
}
Solução: Verifique se sua API Key está correta no dashboard.

EXPERIMENT_NOT_FOUND

{
  "code": "EXPERIMENT_NOT_FOUND",
  "message": "Experimento não encontrado"
}
Solução: Verifique se o experimentId existe e está ativo.

MISSING_REQUIRED_FIELD

{
  "code": "MISSING_REQUIRED_FIELD",
  "message": "Campo obrigatório ausente",
  "details": {
    "field": "userId"
  }
}
Solução: Inclua todos os campos obrigatórios na requisição.

Recursos Principais

A API do Testly oferece os seguintes recursos:

1. Experimentos

Gerenciar experimentos A/B:
  • GET /experiments - Listar todos os experimentos
  • GET /experiments/:id - Obter detalhes de um experimento
  • POST /experiments - Criar novo experimento
  • PATCH /experiments/:id - Atualizar experimento
  • DELETE /experiments/:id - Deletar experimento

2. Variantes

Atribuir e gerenciar variantes:
  • POST /variants/assign - Atribuir variante para um usuário
  • GET /variants/:id - Obter detalhes de uma variante

3. Eventos

Registrar impressões e conversões:
  • POST /events/impression - Registrar impressão
  • POST /events/conversion - Registrar conversão

Exemplo: Fluxo Completo

Aqui está um exemplo completo de como implementar um experimento A/B usando a API diretamente:

1. Atribuir Variante

curl -X POST https://api.testly.com/v1/variants/assign \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "experimentId": "homepage-hero-test",
    "userId": "user_123"
  }'
Resposta:
{
  "success": true,
  "data": {
    "variantId": "variant-b",
    "variantName": "Variante B",
    "experimentId": "homepage-hero-test"
  }
}

2. Registrar Impressão

curl -X POST https://api.testly.com/v1/events/impression \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "experimentId": "homepage-hero-test",
    "variantId": "variant-b",
    "userId": "user_123"
  }'
Resposta:
{
  "success": true,
  "data": {
    "eventId": "evt_abc123",
    "timestamp": "2024-01-15T10:30:00Z"
  }
}

3. Registrar Conversão

curl -X POST https://api.testly.com/v1/events/conversion \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "experimentId": "homepage-hero-test",
    "variantId": "variant-b",
    "userId": "user_123",
    "eventName": "cta_clicked"
  }'
Resposta:
{
  "success": true,
  "data": {
    "eventId": "evt_xyz789",
    "timestamp": "2024-01-15T10:35:00Z"
  }
}

SDK vs API Direta

AspectoSDK ReactAPI Direta
Setup2 linhas de códigoImplementação manual
CacheAutomáticoVocê precisa implementar
RetryAutomáticoVocê precisa implementar
TypeScriptTipos incluídosVocê precisa criar
ImpressõesAutomáticasVocê precisa chamar
EstadoGerenciado pelo ReactVocê precisa gerenciar
Use caseApps ReactQualquer linguagem

Implementação Customizada

Se você quiser criar sua própria camada de abstração (ex: SDK para Vue):

Exemplo: Cliente JavaScript

class TestlyClient {
  constructor(apiKey) {
    this.apiKey = apiKey;
    this.baseUrl = 'https://api.testly.com/v1';
  }

  async assignVariant(experimentId, userId) {
    const response = await fetch(`${this.baseUrl}/variants/assign`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${this.apiKey}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ experimentId, userId })
    });

    if (!response.ok) {
      throw new Error(`HTTP ${response.status}`);
    }

    return response.json();
  }

  async recordImpression(experimentId, variantId, userId) {
    const response = await fetch(`${this.baseUrl}/events/impression`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${this.apiKey}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ experimentId, variantId, userId })
    });

    return response.json();
  }

  async recordConversion(experimentId, variantId, userId, eventName) {
    const response = await fetch(`${this.baseUrl}/events/conversion`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${this.apiKey}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ experimentId, variantId, userId, eventName })
    });

    return response.json();
  }
}

// Uso
const client = new TestlyClient('YOUR_API_KEY');

// 1. Atribuir variante
const { data } = await client.assignVariant('homepage-hero', 'user_123');
console.log('Variante:', data.variantId);

// 2. Registrar impressão
await client.recordImpression('homepage-hero', data.variantId, 'user_123');

// 3. Registrar conversão
await client.recordConversion('homepage-hero', data.variantId, 'user_123', 'clicked');

Webhooks (Em Desenvolvimento)

Em breve você poderá configurar webhooks para receber notificações de:
  • ✅ Experimento atingiu significância estatística
  • ✅ Conversões registradas
  • ✅ Mudanças em experimentos
Webhooks estão em desenvolvimento. Entre em contato via [email protected] se precisar dessa funcionalidade.

Exemplos em Outras Linguagens

Python

import requests

class TestlyClient:
    def __init__(self, api_key):
        self.api_key = api_key
        self.base_url = 'https://api.testly.com/v1'
        self.headers = {
            'Authorization': f'Bearer {api_key}',
            'Content-Type': 'application/json'
        }
    
    def assign_variant(self, experiment_id, user_id):
        response = requests.post(
            f'{self.base_url}/variants/assign',
            headers=self.headers,
            json={'experimentId': experiment_id, 'userId': user_id}
        )
        return response.json()

# Uso
client = TestlyClient('YOUR_API_KEY')
result = client.assign_variant('homepage-hero', 'user_123')
print(result['data']['variantId'])

PHP

<?php
class TestlyClient {
    private $apiKey;
    private $baseUrl = 'https://api.testly.com/v1';
    
    public function __construct($apiKey) {
        $this->apiKey = $apiKey;
    }
    
    public function assignVariant($experimentId, $userId) {
        $ch = curl_init("{$this->baseUrl}/variants/assign");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            "Authorization: Bearer {$this->apiKey}",
            "Content-Type: application/json"
        ]);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
            'experimentId' => $experimentId,
            'userId' => $userId
        ]));
        
        $response = curl_exec($ch);
        curl_close($ch);
        
        return json_decode($response, true);
    }
}

// Uso
$client = new TestlyClient('YOUR_API_KEY');
$result = $client->assignVariant('homepage-hero', 'user_123');
echo $result['data']['variantId'];
?>

Próximos Passos


Suporte

Precisa de ajuda com a API?

Contato

Email: [email protected]Discord: discord.gg/testlyRespondemos em até 24h (geralmente muito mais rápido!)