Reservei Docs

Autenticação

Como autenticar suas requisições na API Reservei

Autenticação

A API Reservei utiliza autenticação via Bearer Token. Todas as requisições devem incluir o header Authorization com sua chave de API.

Formato da API Key

As chaves de API seguem o padrão:

TipoPrefixoExemplo
Produçãombx_live_mbx_live_8f92k3d7a9b2c4e6f8g0h1i2j3...
Testembx_test_mbx_test_a1b2c3d4e5f6g7h8i9j0k1l2...

O tipo da chave é determinado automaticamente pelo prefixo. Use chaves mbx_test_ para desenvolvimento e mbx_live_ para produção.

Segurança

Suas chaves de API são secretas e dão acesso completo à sua conta. Nunca compartilhe ou exponha em código público, repositórios Git, ou aplicações front-end.

Obtendo suas Chaves

Gere uma nova chave

Clique em "Gerar Nova Chave". Você pode criar múltiplas chaves para diferentes ambientes (produção, staging, desenvolvimento).

Copie e armazene com segurança

A chave completa só é exibida uma vez. Copie e armazene em um local seguro como:

  • Variáveis de ambiente
  • Secrets manager (AWS, GCP, Azure)
  • HashiCorp Vault

Formato do Header

Inclua o header Authorization em todas as requisições:

Authorization: Bearer mbx_live_sua_chave_aqui
Content-Type: application/json

Exemplos de Autenticação

curl -X GET https://app.reservei.co/api/v1/wallet/balance \
  -H "Authorization: Bearer mbx_live_sua_chave_aqui" \
  -H "Content-Type: application/json"
// Usando fetch nativo
const apiKey = process.env.RESERVEI_API_KEY;

const response = await fetch('https://app.reservei.co/api/v1/wallet/balance', {
  headers: {
    'Authorization': `Bearer ${apiKey}`,
    'Content-Type': 'application/json'
  }
});

const data = await response.json();

// Criando um cliente reutilizável
class ReserveiClient {
  constructor(apiKey) {
    this.apiKey = apiKey;
    this.baseUrl = 'https://app.reservei.co/api/v1';
  }

  async request(endpoint, options = {}) {
    const response = await fetch(`${this.baseUrl}${endpoint}`, {
      ...options,
      headers: {
        'Authorization': `Bearer ${this.apiKey}`,
        'Content-Type': 'application/json',
        ...options.headers
      }
    });
    
    if (!response.ok) {
      const error = await response.json();
      throw new Error(error.message || 'API Error');
    }
    
    return response.json();
  }
}

const reservei = new ReserveiClient(process.env.RESERVEI_API_KEY);
import os
import requests

api_key = os.environ.get('RESERVEI_API_KEY')

# Requisição simples
headers = {
    'Authorization': f'Bearer {api_key}',
    'Content-Type': 'application/json'
}

response = requests.get(
    'https://app.reservei.co/api/v1/wallet/balance',
    headers=headers
)

data = response.json()

# Classe cliente reutilizável
class ReserveiClient:
    def __init__(self, api_key):
        self.api_key = api_key
        self.base_url = 'https://app.reservei.co/api/v1'
        self.session = requests.Session()
        self.session.headers.update({
            'Authorization': f'Bearer {api_key}',
            'Content-Type': 'application/json'
        })
    
    def get(self, endpoint):
        response = self.session.get(f'{self.base_url}{endpoint}')
        response.raise_for_status()
        return response.json()
    
    def post(self, endpoint, data):
        response = self.session.post(f'{self.base_url}{endpoint}', json=data)
        response.raise_for_status()
        return response.json()

reservei = ReserveiClient(os.environ['RESERVEI_API_KEY'])
<?php

$apiKey = getenv('RESERVEI_API_KEY');
$baseUrl = 'https://app.reservei.co/api/v1';

// Usando cURL
$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => $baseUrl . '/wallet/balance',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json'
    ]
]);

$response = curl_exec($ch);
$data = json_decode($response, true);
curl_close($ch);

// Classe cliente
class ReserveiClient {
    private $apiKey;
    private $baseUrl = 'https://app.reservei.co/api/v1';
    
    public function __construct($apiKey) {
        $this->apiKey = $apiKey;
    }
    
    public function request($method, $endpoint, $data = null) {
        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => $this->baseUrl . $endpoint,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_CUSTOMREQUEST => $method,
            CURLOPT_HTTPHEADER => [
                'Authorization: Bearer ' . $this->apiKey,
                'Content-Type: application/json'
            ]
        ]);
        
        if ($data) {
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        }
        
        $response = curl_exec($ch);
        curl_close($ch);
        
        return json_decode($response, true);
    }
}

$reservei = new ReserveiClient(getenv('RESERVEI_API_KEY'));
package main

import (
    "bytes"
    "encoding/json"
    "net/http"
    "os"
)

type ReserveiClient struct {
    APIKey  string
    BaseURL string
    Client  *http.Client
}

func NewReserveiClient(apiKey string) *ReserveiClient {
    return &ReserveiClient{
        APIKey:  apiKey,
        BaseURL: "https://app.reservei.co/api/v1",
        Client:  &http.Client{},
    }
}

func (c *ReserveiClient) Request(method, endpoint string, body interface{}) (*http.Response, error) {
    var buf bytes.Buffer
    if body != nil {
        json.NewEncoder(&buf).Encode(body)
    }
    
    req, err := http.NewRequest(method, c.BaseURL+endpoint, &buf)
    if err != nil {
        return nil, err
    }
    
    req.Header.Set("Authorization", "Bearer "+c.APIKey)
    req.Header.Set("Content-Type", "application/json")
    
    return c.Client.Do(req)
}

func main() {
    client := NewReserveiClient(os.Getenv("RESERVEI_API_KEY"))
    resp, _ := client.Request("GET", "/wallet/balance", nil)
    defer resp.Body.Close()
}

Gerenciamento de Chaves

Listando Chaves

No painel de API Keys você pode ver:

  • Prefixo da chave: Primeiros caracteres para identificação
  • Data de criação: Quando a chave foi gerada
  • Último uso: Última vez que a chave foi utilizada
  • Status: Ativa ou inativa

Revogando Chaves

Para revogar uma chave comprometida:

  1. Acesse Configurações → API Keys
  2. Localize a chave pelo prefixo
  3. Clique em "Revogar"
  4. Confirme a ação

A revogação é imediata e irreversível. Todas as requisições usando esta chave passarão a retornar 401 Unauthorized.

Rotação de Chaves

Recomendamos rotacionar suas chaves periodicamente:

  1. Gere uma nova chave
  2. Atualize suas aplicações para usar a nova chave
  3. Monitore que tudo está funcionando
  4. Revogue a chave antiga

Modo de Teste vs Produção

A API Reservei suporta dois tipos de chaves: Teste e Produção. A escolha é feita automaticamente baseada na chave utilizada.

Como funciona

Tipo de ChaveAmbiente DuffelDados SalvosCobrança
ProduçãoAPI realBanco de produçãoSim
TesteAPI sandboxMarcados como is_test_dataNão

Chaves de Teste

Use chaves de teste para desenvolver e testar sua integração. Os dados retornados são fictícios e as reservas não são reais.

Gerando Chaves de Teste

Ative o Modo de Teste

No painel do Reservei, clique no switch "Modo de Teste" no header para ativar o ambiente de sandbox.

Gere a Chave

Com o modo de teste ativo, vá em Configurações → Desenvolvedor e clique em "Nova Chave de Teste".

Use na Integração

Use a chave de teste durante o desenvolvimento. Todas as requisições usarão automaticamente o ambiente de teste da Duffel.

Identificando o Modo na Resposta

Todas as respostas da API incluem um campo _meta indicando o modo:

{
  "id": "orq_0000AbCdEf123456",
  "offers": [...],
  "_meta": {
    "test_mode": true,
    "message": "Dados de teste - não são reais"
  }
}

Atenção

Em produção, nunca use chaves de teste. As reservas feitas com chaves de teste não são válidas e não emitem bilhetes reais.

Vinculação com Time (Team)

Cada API key está vinculada a um time específico e herda automaticamente suas configurações:

ConfiguraçãoDescrição
default_markup_percentPercentual de markup aplicado nas ofertas
default_fee_amountTaxa fixa por reserva
default_currencyMoeda padrão (BRL)

Isso significa que diferentes integradores (diferentes times) podem ter configurações de precificação distintas, mesmo usando a mesma infraestrutura.

Erros de Autenticação

CódigoErroDescriçãoSolução
401Missing or invalid Authorization headerHeader não presente ou malformadoVerifique se o header está no formato Bearer {key}
401Invalid API key formatChave não começa com mbx_live_ ou mbx_test_Verifique se está usando a chave correta
401Invalid API keyChave não encontrada no sistemaVerifique se a chave existe e não foi revogada
401API key is inactiveChave foi desativadaGere uma nova chave ou reative no painel
403ForbiddenSem permissão para o recursoVerifique as permissões do seu time
429Rate limit exceededMuitas requisiçõesAguarde e reduza a frequência de chamadas

Exemplo de Resposta de Erro

{
  "success": false,
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid API key"
  }
}

Boas Práticas de Segurança

✅ Faça

  • Armazene chaves em variáveis de ambiente
  • Use secrets managers em produção
  • Rotacione chaves periodicamente
  • Use chaves de TESTE para desenvolvimento
  • Use chaves de PRODUÇÃO apenas em ambiente live
  • Monitore o uso das chaves

❌ Não Faça

  • Commitar chaves em repositórios Git
  • Expor chaves em código front-end
  • Compartilhar chaves entre times
  • Usar chaves de teste em produção
  • Misturar dados de teste com dados reais
  • Ignorar alertas de uso suspeito

Testando a Autenticação

Verifique se sua chave está funcionando:

curl -X GET https://app.reservei.co/api/v1/wallet/balance \
  -H "Authorization: Bearer sua_chave_aqui"

Resposta de sucesso:

{
  "success": true,
  "data": {
    "balance": "10000.00",
    "currency": "BRL"
  }
}

Resposta de erro:

{
  "success": false,
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid API key"
  }
}