# Como consultar inscrição estadual em PHP?

> Com o SDK oficial fiscalapi-br/fiscalapi-php, uma linha consulta a inscrição estadual de um CNPJ ou CPF. A página traz a consulta única e um lote simples com pausa por plano e tratamento de 402 e 429.

URL: https://docs.fiscalapi.com.br/docs/guias/php
Atualizado em 07/11/2026

Instale o SDK oficial com `composer require fiscalapi-br/fiscalapi-php` e chame `$api->consultarIeTodos(cnpj: '...')`: a resposta traz as inscrições estaduais do documento nos 27 estados, com a situação de cada uma. Para um estado só, use `$api->consultarIe('MT', cnpj: '...')`.

* **Custo:** 1 consulta por chamada, de R$ 0,025 a R$ 0,67 conforme o plano ([tabela](#quanto-custa)).
* **Grátis para testar a API:** 10 consultas por mês de IE em um estado e de CNPJ; a consulta nos 27 estados usada neste guia é paga ([condições](#quanto-custa)).
* **Comece:** [crie a conta e a chave de API](https://app.fiscalapi.com.br?utm_source=docs\&utm_medium=docs\&utm_campaign=guia-php).

## Antes de começar

* PHP 8.1 ou mais novo, com a extensão `curl`. O SDK não puxa nenhum outro pacote.
* A chave de API na variável de ambiente `FISCALAPI_API_KEY`.

```bash
composer require fiscalapi-br/fiscalapi-php
export FISCALAPI_API_KEY="fapi_sua_chave_aqui"
```

Os métodos do SDK estão no [repositório fiscalapi-php](https://github.com/fiscalapi-br/fiscalapi-php).

## Consulta única

```php
<?php
require 'vendor/autoload.php';

use FiscalApiBr\FiscalAPI;
use FiscalApiBr\Exception\InsufficientBalanceException;
use FiscalApiBr\Exception\RateLimitException;
use FiscalApiBr\Exception\BadRequestException;
use FiscalApiBr\Exception\FiscalAPIException;

$api = new FiscalAPI(); // lê FISCALAPI_API_KEY

try {
    $resp = $api->consultarIeTodos(cnpj: '12.345.678/0001-95');

    if (($resp['complete'] ?? true) === false) {
        echo "Algum estado não respondeu: lista vazia não prova que não há IE.\n";
    }
    foreach ($resp['results'] as $estado) {
        foreach ($estado['results'] as $ie) {
            echo $estado['uf'], ' ', $ie['inscricao_estadual'], ' ', $ie['situacao_ie'], PHP_EOL;
        }
    }
} catch (InsufficientBalanceException $e) {
    echo "Acabaram as consultas do mês e não há saldo de recarga (402).\n";
} catch (RateLimitException $e) {
    echo 'Limite por minuto atingido; tente em ', $e->getRetryAfter() ?? 60, " s (429).\n";
} catch (BadRequestException $e) {
    echo 'Documento ausente ou sem dígitos: ', $e->getMessage(), PHP_EOL;
} catch (FiscalAPIException $e) {
    echo 'Erro ', $e->statusCode, ': ', $e->getMessage(), ' (request_id ', $e->requestId, ")\n";
}
```

Outras formas:

```php
$api->consultarIe('MT', cnpj: '12345678000195');     // um estado; inscrições direto em $resp['results']
$api->consultarIeTodos(cpf: '123.456.789-09');       // produtor rural pelo CPF
$api->consultarIeTodos(ie: '13.234.567-6');          // descobre o estado de uma IE
$api->consultarCnpj('12345678000195');               // dados da Receita Federal em $resp['result']
```

## Lote simples

Para uma lista de CNPJs, faça uma chamada por vez com a pausa do seu plano e grave cada resultado assim que ele chega. Salve como `lote.php`, com um CNPJ por linha em `cnpjs.txt`:

```php
<?php
require 'vendor/autoload.php';

use FiscalApiBr\FiscalAPI;
use FiscalApiBr\Exception\InsufficientBalanceException;
use FiscalApiBr\Exception\RateLimitException;
use FiscalApiBr\Exception\BadRequestException;
use FiscalApiBr\Exception\ServerException;
use FiscalApiBr\Exception\APIConnectionException;

// Segundos entre chamadas: 12 no Lite e sem plano, 3 no Starter, 1 no Pro, 0.5 no Enterprise.
const PAUSA = 3.0;
const SAIDA = 'resultado.csv';

$api = new FiscalAPI(); // já repete sozinho em 429 e 5xx, respeitando o Retry-After

// Dígitos verificadores, também do CNPJ alfanumérico. CNPJ com DV errado não
// volta erro da API: é consultado e cobrado. Melhor barrar antes.
function cnpjValido(string $cnpj): bool
{
    if (!preg_match('/^[0-9A-Z]{12}[0-9]{2}$/', $cnpj) || count(array_unique(str_split($cnpj))) === 1) {
        return false;
    }
    $v = array_map(fn ($c) => ord($c) - 48, str_split($cnpj));
    foreach ([12, 13] as $n) {
        $soma = 0;
        for ($i = 0; $i < $n; $i++) {
            $soma += $v[$i] * ((($n - 1 - $i) % 8) + 2);
        }
        $resto = $soma % 11;
        if ($v[$n] !== ($resto < 2 ? 0 : 11 - $resto)) {
            return false;
        }
    }
    return true;
}

// Retomada: pula os CNPJs que já estão no CSV de saída.
$feitos = [];
if (is_file(SAIDA)) {
    foreach (file(SAIDA, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $linha) {
        $feitos[str_getcsv($linha, escape: '')[0]] = true;
    }
}

$cnpjs = array_unique(array_filter(array_map(
    fn ($l) => strtoupper(preg_replace('/[^0-9A-Za-z]/', '', $l)),
    file('cnpjs.txt', FILE_IGNORE_NEW_LINES)
)));

$saida = fopen(SAIDA, 'a');
foreach ($cnpjs as $cnpj) {
    if (isset($feitos[$cnpj])) {
        continue;
    }
    if (!cnpjValido($cnpj)) {
        fputcsv($saida, [$cnpj, '', '', 'CNPJ invalido'], escape: ''); // não chama a API
        continue;
    }
    $inicio = microtime(true);
    try {
        $resp = $api->consultarIeTodos(cnpj: $cnpj);
        $inscricoes = [];
        foreach ($resp['results'] as $estado) {
            foreach ($estado['results'] as $ie) {
                $inscricoes[] = "{$estado['uf']}: {$ie['inscricao_estadual']} ({$ie['situacao_ie']})";
            }
        }
        $completo = ($resp['complete'] ?? true) ? 'sim' : 'nao';
        fputcsv($saida, [$cnpj, implode('; ', $inscricoes), $completo, ''], escape: '');
    } catch (InsufficientBalanceException $e) {
        echo "Parei no {$cnpj}: acabaram as consultas do mês e não há saldo de recarga (402).\n";
        break;
    } catch (RateLimitException $e) {
        sleep($e->getRetryAfter() ?? 60); // fica para a próxima rodada
        continue;
    } catch (BadRequestException $e) {
        fputcsv($saida, [$cnpj, '', '', 'invalido: ' . $e->getMessage()], escape: '');
    } catch (ServerException | APIConnectionException $e) {
        echo "Falha temporária no {$cnpj}; entra de novo na próxima rodada.\n";
    }
    fflush($saida);

    $resto = PAUSA - (microtime(true) - $inicio);
    if ($resto > 0) {
        usleep((int) ($resto * 1_000_000));
    }
}
fclose($saida);
```

Rode com `php lote.php`. Se parar no meio (402, queda, `Ctrl+C`), rode de novo: os CNPJs que já estão em `resultado.csv` são pulados. Os que tiveram falha temporária não vão para o CSV e entram na rodada seguinte.

## O que o SDK já faz e o que fica com você

| Situação                                              | SDK                                                               | Seu código                                                                             |
| ----------------------------------------------------- | ----------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| `429` (limite por minuto)                             | Tenta de novo até 3 vezes, esperando o `Retry-After` (até 60 s)   | Manter a pausa do plano. Se ainda vier `RateLimitException`, esperar `getRetryAfter()` |
| `402` (acabaram as consultas do mês e não há recarga) | Lança `InsufficientBalanceException`                              | Parar, recarregar ou mudar de plano. Repetir não resolve                               |
| `400` (documento ausente ou sem dígitos)              | Lança `BadRequestException`                                       | Corrigir o dado                                                                        |
| CNPJ com dígito verificador errado                    | Nada: a consulta em todos os estados não confere o dígito e cobra | Validar antes, como `cnpjValido` no lote                                               |
| `500`, `502`, `503`, `504`                            | Tenta de novo até 3 vezes                                         | Deixar para depois se persistir                                                        |
| `403` (chave inválida ou revogada)                    | Lança `AuthenticationException`                                   | Trocar a chave                                                                         |

## Quanto custa

|                                                | Lite    | Starter | Pro      | Enterprise |
| ---------------------------------------------- | ------- | ------- | -------- | ---------- |
| Consulta de IE (1 UF ou 27 UFs)                | R$ 0,67 | R$ 0,10 | R$ 0,065 | R$ 0,025   |
| Consulta de CNPJ (base mensal)                 | R$ 0,67 | R$ 0,10 | R$ 0,065 | R$ 0,025   |
| Consultas por minuto (somando todas as chaves) | 5       | 20      | 60       | 120        |

Valores por consulta dentro da franquia mensal. Conta sem plano tem o limite do Lite. `consultarCnpj` com `forceFresh: true` vai ao vivo na Receita e conta como 3 consultas. Resposta com erro HTTP (400, 402, 429, 500) não é cobrada. Veja [Planos e limites](/docs/referencia/plans-and-limits).

**Grátis para testar:** conta que nunca assinou plano, sem recarga e com e-mail confirmado, tem 10 consultas por mês de IE em um estado e de CNPJ da base mensal, também pela API. Teste com `$api->consultarIe('MT', cnpj: '...')` ou `$api->consultarCnpj('...')`: a consulta nos 27 estados e o CNPJ ao vivo usam plano ou recarga. [Criar conta](https://app.fiscalapi.com.br?utm_source=docs\&utm_medium=docs\&utm_campaign=guia-php).

## Perguntas frequentes

### Existe SDK PHP da FiscalAPI?

Sim, o pacote oficial `fiscalapi-br/fiscalapi-php` no Packagist (`composer require fiscalapi-br/fiscalapi-php`). Pede PHP 8.1 ou mais novo e a extensão `curl`, e não puxa outras dependências.

### Como consultar inscrição estadual por CNPJ em PHP?

Com o SDK, `$api->consultarIeTodos(cnpj: '12345678000195')` traz as inscrições nos 27 estados; `$api->consultarIe('MT', cnpj: '12345678000195')` consulta um estado. Sem o SDK, é um `GET` em `https://api.fiscalapi.com.br/api/consultar-ie-todos?cnpj=...` com o header `X-API-Key`.

### Funciona com Laravel?

Funciona: o SDK é PHP puro com autoload PSR-4. Instale com o Composer e crie a classe `FiscalApiBr\FiscalAPI` passando a chave no construtor (`new FiscalAPI($chave)`), com o valor vindo da sua configuração.

### O que fazer quando a API devolve 429?

Esperar os segundos do header `Retry-After`. O SDK já faz isso até 3 vezes; depois, lança `RateLimitException`, e `getRetryAfter()` diz quanto esperar.

### Quanto custa consultar inscrição estadual em PHP?

O mesmo de qualquer chamada à API: de R$ 0,025 (Enterprise) a R$ 0,67 (Lite) por consulta. As 10 consultas grátis do mês valem para IE em um estado e CNPJ da base mensal, no painel e pela API.
