Rate limits por plano
Atualizado em
Nesta página
A API está inclusa em todos os planos. O que muda entre eles é o limite de chamadas por minuto. O limite protege a plataforma e a fila de emissão para todos os clientes.
Limites por plano#
| Plano | Chamadas por minuto (produção) | Notas por mês |
|---|---|---|
| Essencial | 60 | 30 |
| Profissional | 120 | 150 |
| Escala | 600 | 600 |
| Contador | 600 | 1.500 (somadas entre os CNPJs) |
| Enterprise | Sob medida | Sob medida |
Sandbox (chaves emt_test_) |
30 | Não consome |
O limite é aplicado por chave e por empresa. Várias chaves da mesma empresa dividem o limite da empresa.
Headers#
Toda resposta traz o estado do seu limite:
Headers da resposta
HTTP/1.1 200 OK
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 117
X-RateLimit-Reset: 1762866960| Header | Descrição |
|---|---|
X-RateLimit-Limit |
Chamadas permitidas na janela |
X-RateLimit-Remaining |
Chamadas restantes na janela atual |
X-RateLimit-Reset |
Quando a janela reinicia (epoch, em segundos) |
Quando o limite estoura#
429
HTTP/1.1 429 Too Many Requests
Retry-After: 18
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 0Corpo
{
"status": "error",
"message": "Muitas requisições. Aguarde e tente de novo.",
"code": "RATE_LIMITED",
"details": null
}Espere os segundos de Retry-After antes de tentar de novo. Numa emissão, repita com a mesma Idempotency-Key.
Python
import time, requests
def chamar(metodo, url, **kw):
while True:
r = requests.request(metodo, url, timeout=30, **kw)
if r.status_code != 429:
return r
time.sleep(int(r.headers.get("Retry-After", "5")))JavaScript
async function chamar(url, opcoes) {
while (true) {
const r = await fetch(url, opcoes);
if (r.status !== 429) return r;
const espera = Number(r.headers.get("Retry-After") ?? 5);
await new Promise((ok) => setTimeout(ok, espera * 1000));
}
}PHP
<?php
function chamar(string $url, array $opcoes): array {
while (true) {
$ch = curl_init($url);
$retryAfter = 5;
curl_setopt_array($ch, $opcoes + [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADERFUNCTION => function ($ch, $linha) use (&$retryAfter) {
if (stripos($linha, "Retry-After:") === 0) $retryAfter = (int) trim(substr($linha, 12));
return strlen($linha);
},
]);
$body = curl_exec($ch);
if (curl_getinfo($ch, CURLINFO_HTTP_CODE) !== 429) return json_decode($body, true);
sleep($retryAfter);
}
}Como gastar menos chamadas#
- Use webhooks em vez de consultar o status de cada nota em loop.
- Se precisar de polling, espere pelo menos 2 segundos entre consultas da mesma nota.
- Liste com
limit=200em vez de buscar nota por nota. - Cacheie as tabelas de referência (municípios, códigos de serviço): elas mudam raramente.
- Em lotes grandes, considere a emissão em lote por planilha, que não usa a API.
Ritmo de emissão na Sefin#
Independentemente do seu limite, a Emitra transmite as DPS à Sefin com concorrência controlada por CNPJ. Um pico de emissões pela API entra na fila e é processado em ordem; a nota fica em queued um pouco mais, sem erro para você.
Próximos passos#
Esta página foi útil?