Check a CNPJ's federal tax debt via API

To check a CNPJ in Brazil's federal tax debt registry (dívida ativa da União), the official free option is Dívida Aberta, from the National Treasury Attorney's Office (PGFN): one lookup at a time, on a page with a bot check. For automated screening of many CNPJs, CNPJAPI tells you by API, on paid plans, whether the company was under collection in the latest quarterly data PGFN publishes as open data, not its status today. The information comes in every CNPJ lookup, in the same JSON as the registration data, with no extra call and no extra cost. Neither replaces the official tax clearance certificate.

It is a useful signal before selling on credit, approving a credit line or closing a deal with a supplier.

What the federal tax debt registry is

Brazil's federal tax debt registry (dívida ativa da União) lists debts owed to the Federal Government, and also to the FGTS (the employees' severance fund), that were not paid on time and that PGFN entered for collection. It has three parts: federal taxes and fines (non-social-security), social security contributions and FGTS. An entry may be collected in court (tax enforcement). It changes status when it is placed in an installment plan, backed by a guarantee or suspended by a court decision, and stops showing as under collection when it is paid, cancelled or otherwise extinguished. Debts not yet entered are not in this registry.

Ways to check

Criterion Dívida Aberta (PGFN) PGFN open data CNPJAPI
Purpose Check one company Download the whole registry Automated screening by API
Updates More recent than the quarterly data Quarterly Quarterly, with the extraction month
Volume One lookup at a time Compressed CSV files, millions of rows One CNPJ per call or up to 20 in a batch
Search By CNPJ, CPF or name No search (whole file) By CNPJ root (the whole company)
Bot check Yes No No (API key access)
Format Web page CSV JSON
Cost Free Free Included in paid plans

For screening customer and supplier records, the API saves you from downloading and processing the files every quarter.

Five points before you use it

  1. Source: PGFN's open data on the federal tax debt registry. Every response carries "Fonte": "PGFN, dados abertos da dívida ativa da União".
  2. Date: PGFN publishes the data every quarter. The response carries the extraction month (Referencia) and the date PGFN published the batch (PublicadoEm).
  3. Lag: the data is a snapshot of the extraction date and is usually from 3 weeks to about 4 months old; if publication is late, up to 5 months after the reference month, when the block starts coming as unavailable. Payments, installment plans, guarantees and court decisions after the extraction do not show; entries made afterwards do not show either.
  4. Where to check the current status: in PGFN's official lookup, Dívida Aberta. To request a review of an entry, the channel is REGULARIZE.
  5. Not a certificate: this information does not replace the official tax clearance certificate (certidão de regularidade fiscal).

How it works

Make the regular CNPJ lookup (GET /{cnpj}) with the API key of a paid plan. The response gains a DividaAtiva field at the end of the JSON, after Sancoes. For a company with entries, it looks like this (fictitious CNPJ and amounts):

curl https://api.cnpjapi.com.br/98765432000198 \
  -H "Authorization: Bearer cnpj_sua_chave"
"DividaAtiva": {
  "Fonte": "PGFN, dados abertos da dívida ativa da União",
  "Referencia": "2026-09",
  "PublicadoEm": "2026-10-21",
  "ConstavaEmCobranca": true,
  "EmCobranca": {
    "Inscricoes": 12,
    "ValorConsolidado": 184532.17,
    "Ajuizadas": 3,
    "PorBase": {
      "NaoPrevidenciaria": { "Inscricoes": 9, "ValorConsolidado": 150210.40 },
      "Previdenciaria": { "Inscricoes": 2, "ValorConsolidado": 30101.77 },
      "FGTS": { "Inscricoes": 1, "ValorConsolidado": 4220.00 }
    }
  },
  "SituacaoRegular": {
    "BeneficioFiscal": { "Inscricoes": 2, "ValorConsolidado": 20400.00 },
    "Garantia": { "Inscricoes": 0, "ValorConsolidado": 0.00 },
    "SuspensaDecisaoJudicial": { "Inscricoes": 1, "ValorConsolidado": 8000.00 },
    "EmNegociacao": { "Inscricoes": 0, "ValorConsolidado": 0.00 }
  },
  "CNPJsRegistrados": ["98765432000198"]
}

Four points to read the response right:

  • ConstavaEmCobranca is about the extraction date, not today. true means there was at least one entry under collection in the Referencia batch.
  • Regular status does not count as under collection. Entries in an installment plan or moratorium (tax benefit), guaranteed, suspended by court decision or under negotiation come separately in SituacaoRegular, with count and amount, and are not part of EmCobranca.
  • The match is by the CNPJ root. Federal taxes are usually assessed on the head office's CNPJ: looking up any establishment returns the entries of the whole company, and CNPJsRegistrados tells which CNPJs of the root are in the data. Only entries where the company is the principal debtor are included.
  • Amounts at the extraction date. ValorConsolidado is the debt with legal additions on that date, in BRL; Ajuizadas counts the entries under collection that are in tax enforcement proceedings.

When the company is not in the data, the block comes with ConstavaEmCobranca: false, zeroed counts, the same Referencia and the PublicadoEm. Read it as "was not under collection in the September 2026 extraction", not as "no debt".

Code example

The Node examples use native fetch (Node 18+) and top-level await - run them as an ES module (a .mjs file, or "type": "module" in package.json), or wrap the code in an async function.

Python:

import requests

cnpj = "98765432000198"
r = requests.get(
    f"https://api.cnpjapi.com.br/{cnpj}",
    headers={"Authorization": "Bearer cnpj_sua_chave"},
    timeout=10,
)
r.raise_for_status()
company = r.json()

debt = company.get("DividaAtiva")
if debt is None:
    # free plan ("DividaAtivaDisponivelEm") or check unavailable right now ("DividaAtivaErro")
    print("Tax debt not checked:", company.get("DividaAtivaDisponivelEm") or company.get("DividaAtivaErro"))
elif debt["ConstavaEmCobranca"]:
    collection = debt["EmCobranca"]
    print(f'Under collection in the {debt["Referencia"]} extraction:',
          collection["Inscricoes"], "entries, BRL", collection["ValorConsolidado"])
else:
    print(f'Not under collection in the {debt["Referencia"]} extraction (published on {debt["PublicadoEm"]})')

Node.js:

const cnpj = "98765432000198";
const r = await fetch(`https://api.cnpjapi.com.br/${cnpj}`, {
  headers: { Authorization: "Bearer cnpj_sua_chave" },
});
if (!r.ok) throw new Error(`HTTP ${r.status}`);
const company = await r.json();

const debt = company.DividaAtiva;
if (debt === null || debt === undefined) {
  console.log("Tax debt not checked:", company.DividaAtivaDisponivelEm ?? company.DividaAtivaErro);
} else if (debt.ConstavaEmCobranca) {
  const { Inscricoes: inscricoes, ValorConsolidado } = debt.EmCobranca;
  console.log(`Under collection in the ${debt.Referencia} extraction:`, inscricoes, "entries, BRL", ValorConsolidado);
} else {
  console.log(`Not under collection in the ${debt.Referencia} extraction (published on ${debt.PublicadoEm})`);
}

When the block is missing

  • Free plan: "DividaAtiva": null and "DividaAtivaDisponivelEm": "planos_pagos". The CNPJ data comes normally.
  • Check unavailable right now: "DividaAtiva": null and "DividaAtivaErro": "indisponivel". This is also what comes when the served batch is more than 5 months old with no newer batch loaded (PGFN published late or the next batch has not been loaded yet), so stale data is not served. The CNPJ lookup is not affected.
  • ReceitaWS format (?formato=receitaws or /v1/cnpj/{cnpj}): the field does not exist.

Many CNPJs at once

In a batch (POST /consulta/lote, up to 20 CNPJs per call), each found item carries the same block inside Dados. Handy to review your whole customer base at once.

Frequently asked questions

How recent is the federal tax debt information?

PGFN publishes the data every quarter, and every lookup shows the extraction month (Referencia) and the publication date (PublicadoEm). Between two publications, the information can be up to about 4 months behind.

The company already paid or set up an installment plan. Why does it still show?

Because PGFN's data is from a date before the payment or the installment plan; the status updates in the next quarterly publication. The current status can be checked in PGFN's Dívida Aberta, and a review of an entry is requested in REGULARIZE.

Does an installment plan count as debt?

No. Entries in an installment plan, guaranteed, suspended by court decision or under negotiation are listed separately, in regular status, and do not count as under collection.

If the company is not in the registry, does that mean it has no debt?

No. It means the company was not under collection in that month's extraction. Later entries do not show, and the data does not include debts not yet registered in the federal tax debt registry.

Does the lookup replace the tax clearance certificate?

No. For that, request the tax clearance certificate (certidão de regularidade fiscal) through the official channels.

Caveats

  • The data comes from PGFN's official registry, aggregated by CNPJ root, without changing status or amounts; it is not a judgment by CNPJAPI about the company.
  • Use the information as a dated signal, not as today's status. For decisions that depend on the current status, check the official source.

Next steps