---
title: "SDK Rust"
lang: pt-BR
canonical: https://doc.apibrasil.io/sdks/rust
markdown: https://doc.apibrasil.io/sdks/rust.md
source: apibrasil-documentation
---

# SDK Rust

- **Situação:** publicado
- **Instalação:** `cargo add apibrasil`
- **Registry:** crates.io — https://crates.io/crates/apibrasil
- **Repositório:** https://github.com/APIBrasil/apigratis-sdk-rust

## Não invente a assinatura

NÃO INVENTE A API DO SDK DE Rust. Cada biblioteca deste catálogo tem construtor, nomes de método e formato de retorno próprios, e nenhum deles se deduz do nome do pacote. Abra o README do repositório acima e use exatamente o que está escrito lá. Se você não conseguir abrir o repositório, NÃO CHUTE: escreva o cliente em HTTP puro, seguindo a seção abaixo, e diga na resposta que foi isso que você fez e por quê.

## Como autenticar

O Bearer vai no cabeçalho Authorization, em toda chamada. O DeviceToken só nas APIs cobradas por plano — as por crédito não pedem. É o mesmo par que o SDK põe por você.

Com homolog verdadeiro no corpo, o gateway responde de uma base fixa. O CPF 00000000000 é o dela e não é de ninguém.

## O repositório no GitHub

- **Estrelas:** 0
- **Forks:** 0
- **Issues abertas:** 0
- **Linguagem:** Rust
- **Licença:** MIT License
- **Último envio:** 25 de julho de 2026
- **git clone:** `https://github.com/APIBrasil/apigratis-sdk-rust.git`

## README do repositório

Reproduzido do repositório, no ramo padrão. É a documentação de quem mantém a biblioteca: a assinatura do SDK é o que está aqui, e não o que se deduz do nome do pacote.

# SDK RUST - APIGratis by API BRASIL 🦀

SDK oficial Rust da plataforma [APIBrasil](https://apibrasil.com.br) — WhatsApp, SMS, consultas de CPF/CNPJ, veículos, CEP, correios, pagamentos PIX/boleto e muito mais.

[![Crates.io](https://img.shields.io/crates/v/apibrasil.svg)](https://crates.io/crates/apibrasil)
[![Docs.rs](https://docs.rs/apibrasil/badge.svg)](https://docs.rs/apibrasil)
[![CI](https://github.com/APIBrasil/apigratis-sdk-rust/actions/workflows/ci.yml/badge.svg)](https://github.com/APIBrasil/apigratis-sdk-rust/actions/workflows/ci.yml)
<a href="https://github.com/APIBrasil/apigratis-sdk-rust/issues" target="_blank"><img alt="GitHub issues" src="https://img.shields.io/github/issues/APIBrasil/apigratis-sdk-rust"></a>
<a href="https://github.com/APIBrasil/apigratis-sdk-rust/network" target="_blank"><img alt="GitHub forks" src="https://img.shields.io/github/forks/APIBrasil/apigratis-sdk-rust"></a>
<a href="https://github.com/APIBrasil/apigratis-sdk-rust/stargazers" target="_blank"><img alt="GitHub stars" src="https://img.shields.io/github/stars/APIBrasil/apigratis-sdk-rust"></a>

## Canais de suporte (Comunidade)

[![WhatsApp Group](https://img.shields.io/badge/WhatsApp-Channel-25D366?logo=whatsapp)](https://whatsapp.com/channel/0029VaMiaT6B4hdX3hrUcz3X)
[![Telegram Group](https://img.shields.io/badge/Telegram-Group-32AFED?logo=telegram)](https://t.me/apibrasil1)

## Instalação

```bash
cargo add apibrasil
cargo add tokio --features macros,rt-multi-thread
cargo add serde_json
```

Requer **Rust >= 1.86**. TLS via `rustls` por padrão — sem depender de OpenSSL instalado.

Obtenha suas credenciais em https://apibrasil.com.br

## Começando

```rust
use apibrasil::{ApiBrasil, Config};
use serde_json::json;

#[tokio::main]
async fn main() -> apibrasil::Result<()> {
    let api = ApiBrasil::new(
        Config::new()
            .bearer_token("SEU_BEARER_TOKEN")  // JWT do login
            .device_token("SEU_DEVICE_TOKEN"),  // device dos serviços device-based
    );

    // WhatsApp
    api.whatsapp()
        .send_text(json!({ "number": "5511999999999", "text": "Olá! 👋" }))
        .await?;

    // Consulta CNPJ (por créditos)
    let empresa = api.consulta().cnpj(json!({ "cnpj": "00000000000000" })).await?;
    println!("{:?}", empresa.data());

    Ok(())
}
```

As credenciais também podem vir só do ambiente — `ApiBrasil::from_env()` lê automaticamente `APIBRASIL_BEARER_TOKEN`, `APIBRASIL_DEVICE_TOKEN`, `APIBRASIL_SECRET_KEY` e `APIBRASIL_BASE_URL`.

Também é possível autenticar por email/senha — o token retornado fica guardado no cliente:

```rust
let (api, sessao) = apibrasil::login(
    json!({ "email": "voce@empresa.com.br", "password": "******" }),
    Default::default(),
)
.await?;

// contas com 2FA:
let api = ApiBrasil::from_env();
let sessao = api.auth().login(json!({ "email": email, "password": senha })).await?;
if apibrasil::requires_2fa(&sessao) {
    let challenge = sessao["challenge"].clone();
    api.auth().send_2fa(json!({ "challenge": challenge, "method": "email" })).await?;
    api.auth().verify_2fa(json!({ "challenge": challenge, "code": "000000" })).await?;
}
```

## Como a plataforma funciona

A API Brasil tem duas famílias de serviços:

| Família          | Autenticação                                   | Exemplos                                                                    |
| ---------------- | ---------------------------------------------- | --------------------------------------------------------------------------- |
| **Device-based** | `Authorization: Bearer` + header `DeviceToken` | WhatsApp, SMS, veículos, CEP, correios, DDD, feriados, tradução, clima, OCR |
| **Por créditos** | apenas `Authorization: Bearer` (debita saldo)  | `consulta().cpf`, `consulta().cnpj`, `consulta().veiculos`, Serasa, CNH     |

Para os serviços device-based, crie um device com a `SecretKey` da API desejada (painel APIBrasil) e use o `device_token` retornado:

```rust
use apibrasil::RequestOptions;

let device = api
    .with_options(RequestOptions::new().secret_key("SUA_SECRET_KEY"))
    .devices()
    .store(json!({ "device_name": "meu-bot", "type": "server" }))
    .await?;

api.set_device_token("device_token_retornado");
```

## Serviços disponíveis

| Módulo                                                                   | Descrição                                                                                                  |
| ------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- |
| `api.whatsapp()`                                                         | WhatsApp: `start`, `qrcode`, `send_text`, `send_file`, `send_audio`, `send_video`, fila (`queue`)...        |
| `api.evolution()`                                                        | Evolution API: `request(controller, action, body)`                                                          |
| `api.whatsmeow()`                                                        | WhatsMeow: `request(action, body)`, `send_text`, `instance_qr`...                                           |
| `api.sms()`                                                              | SMS device-based (`send`) e por créditos (`send_with_credits`)                                              |
| `api.dados()`                                                            | Dados cadastrais device-based (`cpf`, `cnpj`, `lista_socios`...)                                            |
| `api.vehicles()`                                                         | Veículos por placa (`dados`, `fipe`, `consulta_fipe`, `base_dados`)                                         |
| `api.fipe()`                                                             | Tabela FIPE (`consultar_marcas`, `consultar_modelos`...)                                                    |
| `api.correios()`                                                         | Correios (`rastreio`, `request`)                                                                            |
| `api.cep()`                                                              | CEP + geolocalização (`cep`, `cidades`, `estados`, `calcular_distancia`)                                    |
| `api.geolocation()` / `api.geomatrix()`                                  | Geolocalização e matriz de distâncias                                                                      |
| `api.recognize()`                                                        | OCR / Google Vision (`base64`, `uri`)                                                                      |
| `api.ddd()` / `api.holidays()` / `api.translate()` / `api.weather()`     | DDD, feriados, tradução, clima                                                                             |
| `api.loterias()`                                                         | Loterias (`latest`, `resultado`)                                                                            |
| `api.database_ip()`                                                      | GeoIP (`ip`)                                                                                                |
| `api.consulta()`                                                         | Consultas por créditos: `cpf`, `cnpj`, `cnh`, `cep`, `veiculos`, `telefone`, `generic(service, body)`       |
| `api.ura()` / `api.chip_virtual()`                                       | URA reversa e chip virtual                                                                                  |
| `api.bulk()`                                                             | Execução em lote (`direct`, `queue`)                                                                        |
| `api.auth()`                                                             | Login, 2FA, cadastro, recuperação de senha, perfil                                                          |
| `api.devices()`                                                          | CRUD de devices                                                                                             |
| `api.catalog()`                                                          | Catálogo de APIs, planos, documentações, servidores                                                         |
| `api.account()`                                                          | Saldo, faturas, notificações, tickets                                                                       |
| `api.payments()`                                                         | Recargas e pagamentos PIX/boleto/cartão (Santander, Inter, Mercado Pago, Sicoob)                            |
| `api.ip_whitelist()` / `api.bearer_rate_limit()`                         | Segurança da conta                                                                                          |
| `api.reports()`                                                          | Relatórios e dashboard de consumo                                                                           |

Todo método é `async` e aceita o body como `json!({...})`, `None` ou `()`.

### WhatsApp

```rust
// iniciar sessão e obter QR Code
api.whatsapp()
    .start(json!({ "webhook_wh_message": "https://seu-webhook.com/mensagens" }))
    .await?;

let qr = api.whatsapp().qrcode(None).await?;
println!("{:?}", qr.response()); // data URI base64

// envios
api.whatsapp().send_text(json!({ "number": "5511999999999", "text": "Olá!" })).await?;
api.whatsapp()
    .send_file(json!({ "number": "5511999999999", "path": "https://exemplo.com/boleto.pdf" }))
    .await?;
api.whatsapp()
    .send_location(json!({ "number": "5511999999999", "lat": -23.5, "lng": -46.6 }))
    .await?;

// qualquer action do catálogo
api.whatsapp().request("getAllChats", None).await?;

// fila assíncrona
api.whatsapp()
    .queue("sendText", json!({ "number": "5511999999999", "text": "vai por fila" }))
    .await?;
```

O envelope device-based tem acessores tipados — e continua sendo um JSON:

```rust
let res = api.whatsapp().send_text(json!({ "number": "...", "text": "..." })).await?;

res.is_error();       // bool
res.message();        // Option<&str>
res.response();       // Option<&Json>
res.api_limit();      // Option<&Json>
res["response"];      // acesso direto por chave

#[derive(serde::Deserialize)]
struct Enviado { id: String }

let enviado: Enviado = res.decode()?; // decodifica o campo `response`
```

### Consultas por créditos

```rust
use apibrasil::Consulta;

let cpf = api.consulta().cpf(json!({ "cpf": "00000000000" })).await?;
println!("{:?} {:?}", cpf.balance(), cpf.data());

// o campo `tipo` define o produto consultado
api.consulta()
    .cnpj(Consulta::new("lista-socios").field("cnpj", "00000000000000"))
    .await?;

// modo homologação (sandbox, sem cobrança)
api.consulta()
    .cnpj(Consulta::new("serasa-score-pj").homolog(true).field("cnpj", "00000000000000"))
    .await?;

// qualquer serviço do catálogo
api.consulta().generic("cnh", json!({ "cpf": "00000000000" })).await?;
```

### Veículos e FIPE (device-based)

```rust
api.vehicles().dados(json!({ "placa": "ABC1234" })).await?;
api.vehicles().fipe(json!({ "placa": "ABC1234" })).await?;
api.fipe().consultar_marcas(json!({ "codigoTabelaReferencia": 300 })).await?;
```

### SMS

```rust
api.sms().send(json!({ "number": "5511999999999", "message": "Olá!" })).await?;
api.sms().send_with_credits(json!({ "number": "5511999999999", "message": "Olá!" })).await?;
```

### Pagamentos e recargas

```rust
api.payments().recharge(json!({ "amount": 50, "type": "pix" })).await?;
api.payments().pix_generate("santander", json!({ "amount": 50 })).await?;
api.payments().pix_status("santander", "TX_ID").await?;

let pdf = api.payments().boleto_pdf("inter", "ID").await?; // Vec<u8>
std::fs::write("boleto.pdf", pdf)?;
```

### Múltiplos devices

```rust
let bot1 = api.with_device("device_token_1");
let bot2 = api.with_device("device_token_2");

bot1.whatsapp().send_text(json!({ "number": "5511999999999", "text": "do bot 1" })).await?;
bot2.whatsapp().send_text(json!({ "number": "5511999999999", "text": "do bot 2" })).await?;
```

## Tratamento de erros

Toda chamada devolve `apibrasil::Result<T>`; a falha carrega a categoria em `error.kind()`:

| `ErrorKind`           | Quando                                        |
| --------------------- | --------------------------------------------- |
| `Validation`          | 400/422 — payload inválido                    |
| `Authentication`      | 401 — token ausente/expirado                  |
| `InsufficientBalance` | 402 — sem saldo/créditos                      |
| `Permission`          | 403 — sem permissão (ex: exige PJ)            |
| `NotFound`            | 404/410 — sem dados / rota desativada         |
| `RateLimit`           | 429 — limite atingido (`error.retry_after`)   |
| `Server`              | 5xx — erro do gateway/provedor                |
| `Network` / `Timeout` | falha antes da resposta                       |
| `Api`                 | qualquer outra falha da API                   |

```rust
use apibrasil::ErrorKind;

match api.consulta().cpf(json!({ "cpf": "00000000000" })).await {
    Ok(consulta) => println!("{:?}", consulta.data()),
    Err(error) => match error.kind() {
        ErrorKind::InsufficientBalance => println!("Recarregue seus créditos"),
        ErrorKind::RateLimit => println!("Aguarde {:?}", error.retry_after),
        // detalhes completos da falha
        _ => println!("{} {:?} {:?}", error, error.status, error.code),
    },
}
```

Cada categoria também tem o seu predicado: `error.is_insufficient_balance()`, `error.is_rate_limit()`, `error.is_network()`...

## Retry e observabilidade

Por padrão a SDK refaz a chamada em **HTTP 429** e em **falhas de conexão** (2 tentativas extras, backoff exponencial com jitter, respeitando `Retry-After`). Timeouts e erros de negócio nunca são refeitos — evita duplicar cobranças e envios.

```rust
use std::time::Duration;
use apibrasil::{Config, FnHooks, RetryConfig};

let api = ApiBrasil::new(
    Config::new()
        .retry(RetryConfig {
            retries: 3,
            min_delay: Duration::from_millis(500),
            retry_on_statuses: vec![429, 503],
            ..Default::default()
        }) // ou RetryConfig::none()
        .hooks(
            FnHooks::new()
                .on_request(|info| println!("→ {} {} (#{})", info.method, info.url, info.attempt))
                .on_response(|info| println!("← {} em {:?}", info.status, info.duration))
                .on_retry(|info| println!("retry em {:?}: {}", info.delay, info.reason)),
        ),
);
```

Para cancelar ou limitar uma chamada, use as ferramentas do próprio runtime:

```rust
let envio = tokio::time::timeout(
    Duration::from_secs(10),
    api.whatsapp().send_text(json!({ "number": "...", "text": "..." })),
)
.await;
```

## Opções por requisição

`with_options` devolve um cliente (ou serviço) que usa as opções em todas as chamadas, compartilhando a mesma conexão e credenciais:

```rust
use apibrasil::RequestOptions;

api.with_options(
    RequestOptions::new()
        .secret_key("SUA_SECRET_KEY")
        .header("X-Correlation-Id", "abc-123")
        .timeout(Duration::from_secs(5)),
)
.devices()
.store(json!({ "device_name": "meu-bot" }))
.await?;

// também por serviço
api.whatsapp()
    .with_options(RequestOptions::new().device_token("outro-device"))
    .send_text(json!({ "number": "...", "text": "..." }))
    .await?;
```

## Cliente síncrono

Sem `async`/`await`, com a feature `blocking`:

```toml
apibrasil = { version = "1", features = ["blocking"] }
```

```rust
use apibrasil::blocking::ApiBrasil;

fn main() -> apibrasil::Result<()> {
    let api = ApiBrasil::from_env()?;

    api.whatsapp().send_text(json!({ "number": "5511999999999", "text": "Olá!" }))?;
    let empresa = api.consulta().cnpj(json!({ "cnpj": "00000000000000" }))?;
    println!("{:?}", empresa.data());

    // qualquer método assíncrono, inclusive os sem espelho síncrono
    let planos = api.block_on(api.asynchronous().catalog().plans())?;
    println!("{planos}");

    Ok(())
}
```

## Transporte plugável

O HTTP é feito pelo `reqwest`, mas o trait `Transport` permite trocar a camada inteira (proxy corporativo, instrumentação, mocks de teste):

```rust
use apibrasil::core::transport::{BoxFuture, Transport, TransportRequest, TransportResponse};

struct MeuTransporte;

impl Transport for MeuTransporte {
    fn execute(&self, request: TransportRequest) -> BoxFuture<'_, apibrasil::Result<TransportResponse>> {
        Box::pin(async move {
            // use o cliente HTTP que quiser e devolva status, headers e data
            Ok(TransportResponse::json(200, json!({ "ok": true })))
        })
    }
}

let api = ApiBrasil::new(Config::new().transport(MeuTransporte));
```

Para apenas configurar proxy, TLS ou pool de conexões, reaproveite o transporte padrão:

```rust
use apibrasil::ReqwestTransport;

let http = reqwest::Client::builder()
    .proxy(reqwest::Proxy::all("http://proxy.empresa:3128")?)
    .build()?;

let api = ApiBrasil::new(Config::new().transport(ReqwestTransport::with_client(http)));
```

## Módulos

```rust
use apibrasil::{ApiBrasil, Config};   // cliente + tipos do dia a dia
use apibrasil::core;                  // HTTP, transporte, erros, retry, hooks
use apibrasil::services::messaging;   // WhatsApp, SMS, Evolution, WhatsMeow
use apibrasil::services::data;        // consultas, veículos, CEP, FIPE...
use apibrasil::services::platform;    // auth, devices, pagamentos, relatórios
use apibrasil::generated;             // catálogo gerado
use apibrasil::legacy;                // interface legada
use apibrasil::blocking;              // cliente síncrono (feature = "blocking")
```

Cada serviço também pode ser usado isoladamente sobre o mesmo cliente HTTP:

```rust
use std::sync::Arc;
use apibrasil::{Config, HttpClient};

let http = Arc::new(HttpClient::new(Config::new().bearer_token("...")));
let api = ApiBrasil::with_http(http.clone());
```

## Catálogo gerado

As actions de WhatsApp/Evolution/WhatsMeow e os 210+ `tipo` de consulta são gerados do catálogo real da plataforma:

```bash
cargo run --features blocking --bin codegen
```

```rust
use apibrasil::generated;

generated::WHATSAPP_ACTIONS;                    // &[&str] com todas as actions
generated::service_actions_for("cep");          // ["bairros", "cep", "cidades", ...]
generated::has_action("whatsapp", "sendText");  // true

let meta = generated::consulta_tipo("acerta-essencial").unwrap();
// meta.service = "cpf", meta.fields = ["cpf"]
```

## Endpoint sem método dedicado?

Todo o gateway fica acessível pela porta de saída genérica, já com seus headers de autenticação:

```rust
use apibrasil::Method;

api.request(Method::Post, "/consulta/cpf/credits", json!({ "cpf": "00000000000" })).await?;
api.request(Method::Get, "/reports/quick-stats", None).await?;
```

Documentação completa dos endpoints: https://doc.apibrasil.io

## Configuração avançada

```rust
let api = ApiBrasil::new(Config {
    bearer_token: Some("...".into()),  // ou APIBRASIL_BEARER_TOKEN
    device_token: Some("...".into()),  // ou APIBRASIL_DEVICE_TOKEN
    secret_key: Some("...".into()),    // usada em devices().store (ou APIBRASIL_SECRET_KEY)
    base_url: Some("https://gateway.apibrasil.io/api/v2".into()), // padrão (ou APIBRASIL_BASE_URL)
    timeout: Some(Duration::from_secs(30)),
    ..Default::default()
});
```

## Licença

MIT — veja [LICENSE](https://github.com/APIBrasil/apigratis-sdk-rust/blob/main/LICENSE).

## A mesma API por HTTP

Endereço base: https://gateway.apibrasil.io/api/v2
O caminho e o método de cada endpoint estão na página daquela API nesta documentação. Não deduza rota a partir do nome do serviço.

### Autenticação, em cabeçalhos HTTP
- `Authorization: Bearer SEU_TOKEN` — em toda chamada.
- `DeviceToken: SEU_DEVICE_TOKEN` — só nas APIs cobradas por plano; as cobradas por crédito não pedem. O nome exato do cabeçalho é o que a página do endpoint declara.

```bash
curl -X POST https://gateway.apibrasil.io/api/v2/dados/cpf \
  -H "Authorization: Bearer $APIBRASIL_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"cpf": "00000000000", "homolog": true}'
```

Com `homolog` verdadeiro no corpo, o gateway responde de uma base fixa e não consome crédito. O CPF 00000000000 é dessa base e não é de ninguém — use-o nos testes, nunca em produção.

## As outras linguagens

- [C++](https://doc.apibrasil.io/sdks/cpp.md): `git clone https://github.com/APIBrasil/apigratis-sdk-cpp`
- [Python](https://doc.apibrasil.io/sdks/python.md): `pip install api-brasil`
- [Lua](https://doc.apibrasil.io/sdks/lua.md): `luarocks install apibrasil`
- [PHP](https://doc.apibrasil.io/sdks/php.md): `composer require jhowbhz/apigratis-sdk-php`
- [Java](https://doc.apibrasil.io/sdks/java.md): `mvn dependency:get -Dartifact=br.com.apibrasil:apigratis-sdk-java:0.0.1`
- [Ruby](https://doc.apibrasil.io/sdks/ruby.md): `gem install apigratis-sdk-ruby`
- [C# / .NET](https://doc.apibrasil.io/sdks/csharp.md): `dotnet add package ApiBrasil`
- [Node.js / TypeScript](https://doc.apibrasil.io/sdks/javascript.md): `npm install apigratis-sdk-nodejs`
- [Go](https://doc.apibrasil.io/sdks/go.md): `go get github.com/APIBrasil/apigratis-sdk-go`
- [Dart / Flutter](https://doc.apibrasil.io/sdks/flutter.md): `flutter pub add apigratis_sdk_flutter`
- [Elixir](https://doc.apibrasil.io/sdks/elixir.md): `mix deps.get  # com {:apibrasil, "~> 0.0.1"} no mix.exs`

## Ver também

- SDKs oficiais: [SDKs oficiais](https://doc.apibrasil.io/sdks.md)
- Índice da documentação: https://doc.apibrasil.io/llms.txt
- Versão HTML desta página: https://doc.apibrasil.io/sdks/rust
