# Brazil Tax Reform Calculator - IBS and CBS (`kman-br/brazil-tax-reform-calculator`) Actor

Simulate Brazilian IBS/CBS tax reform scenarios with step-by-step calculations, sourced assumptions, explicit estimate warnings and privacy-safe batch diagnostics.

- **URL**: https://apify.com/kman-br/brazil-tax-reform-calculator.md
- **Developed by:** [Kman](https://apify.com/kman-br) (community)
- **Categories:** Business, Developer tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Brazil Tax Reform Calculator

Simulate Brazilian IBS/CBS tax reform scenarios for 2026–2033. Submit one anonymous calculation or a batch of up to 100. Each calculation produces a dataset row containing the engine result, step-by-step explanation, assumptions, public sources and warnings. Calculations run offline against the bundled parameter snapshot; they do not fetch current legislation.

**Not legal/tax advice.** This is an educational simulation and does not replace a qualified tax or legal professional. A `verificado` label describes the status of the parameters used in the bundled snapshot, not a professional opinion on a transaction. `ESTIMATIVA` marks hypothetical scenario assumptions. Parameters marked `nao_verificado` are always blocked.

### Input

Use the original Portuguese engine field names. Monetary amounts are BRL numbers, with at most two decimal places and a maximum of one billion. Rates are fractions between zero and one, with up to six decimal places. Input is limited to 1 MiB. Unknown fields are rejected at every level. Do not submit personal data, identifiers, names, addresses or free text.

A verified-only calculation, without old-tax comparison:

```json
{
  "categoria": "carga",
  "ano": 2026,
  "base": 10000
}
```

This returns an IBS/CBS debit and payment amount of BRL 100 before any declared waiver or credits. The result explains the configured 2026 offset against old federal taxes; it does not calculate an old-tax comparison unless enabled.

| Field | Meaning |
|---|---|
| `categoria`, `ano`, `base` | Required category, year 2026–2033 and net IBS/CBS taxable base after statutory exclusions |
| `creditos` | Eligible tax credits already established, as a complete `{ "cbs": 100, "ibs": 200 }` object; these are tax amounts, not input costs |
| `permitirEstimativas` | Omitted means false. True permits hypothetical parameters and also enables old-tax comparison unless explicitly disabled |
| `compararAntigos` | Omitted means false when estimates are disabled. Explicit false keeps old-tax comparison disabled even with estimates enabled |
| `cumpreObrigacoes` | Omitted means false. True declares compliance for the configured 2026 payment waiver |
| `confirmarEnquadramento` | Explicit eligibility declaration required for reduced/exempt categories; `enquadramentoConfirmado` is the equivalent engine field; aliases must agree |
| `comando` | `calcular` by default. `comparar` evaluates all eight transition years inside one dataset row; any estimated parameters used still need consent |
| `formato` | `texto` by default, or `json` / `markdown`; controls `formatted`, while structured fields are always retained |
| `aliquotasPlenas`, `aliquotasAntigas` | Optional hypothetical full reference rates or old-tax rates; complete numeric objects, requiring estimate consent when used |
| `tac` | Cargo only: anonymous `valor`, eligible `tipo` (`pf_nao_contribuinte` or `mei`), `pago: true`, `contratacaoDireta: true`, optional CBS/IBS `percentuais` |
| `produto`, `quantidade`, `unidade`, `destinacao` | Required for `combustivel`; product-specific unit, quantity up to one billion with six decimal places, destination `insumo`, `revenda` or `consumo_final` |
| `adRem`, `ibsRecolhido` | Optional annual CBS/IBS fuel tariffs, up to one million BRL/unit with six decimal places, and payment declaration for the configured CBS deduction |

Categories (articles of LC 214/2025). Selecting a category does not validate statutory eligibility; reduced and exempt categories also need `confirmarEnquadramento: true`.

| Category | Scenario |
|---|---|
| `geral` | General regime: full rate, full credit (art. 47) |
| `carga` | Cargo freight: general regime, optional TAC presumed credit (art. 169) |
| `reduzido30` | 30% rate reduction: regulated professional services (art. 127) |
| `reduzido60` | 60% rate reduction: listed goods and services (art. 128) |
| `reduzido100` | Zero rate: listed goods and services; the supplier keeps its credits (art. 143) |
| `urbano` | Urban rail or waterway public transport: 100% reduction, no credits for supplier or buyer (art. 285) |
| `urbanoRodoviario` | Urban bus or metro public transport: exempt, with credits annulled (arts. 157 and 51) |
| `intermunicipal` | Intercity or interstate public passenger transport: 40% reduction with credits (art. 286) |
| `aereoRegional` | Regional air transport: 40% reduction (art. 287) |
| `fretamento` | Closed-group charter: general regime, always marked ESTIMATIVA |
| `combustivel` | Fuels: single-stage per-unit regime (arts. 172–180) |

`urbano` and `urbanoRodoviario` give the same amounts (no tax, no credits) under different legal grounds: a 100% reduction for rail and waterway, an exemption for bus and metro.

Batch example with an estimated freight/TAC scenario and a verified calculation:

```json
{
  "formato": "json",
  "calculations": [
    { "categoria": "carga", "ano": 2026, "base": 10000 },
    {
      "categoria": "carga", "ano": 2033, "base": 10000,
      "creditos": { "cbs": 100, "ibs": 200 },
      "permitirEstimativas": true, "compararAntigos": false,
      "tac": {
        "valor": 1050, "tipo": "pf_nao_contribuinte",
        "pago": true, "contratacaoDireta": true,
        "percentuais": { "cbs": 0.05, "ibs": 0.05 }
      }
    }
  ]
}
```

Batch mode permits only `calculations`, `comando` and `formato` at the top level; sending single-calculation fields together with `calculations` fails with `MODO_MISTO` and no charge. In the Console form, Category, Year and Base come prefilled with the first example above, so clear them before running a batch. Entries may override the operation and format. Put all scenario flags inside each entry. There is no truncation: empty lists and lists longer than 100 fail validation.

Fuel example (hypothetical annual tariffs; no extra transition multiplier):

```json
{
  "categoria": "combustivel", "ano": 2033, "base": 10000,
  "produto": "diesel", "quantidade": 100, "unidade": "litro_20c",
  "destinacao": "insumo", "adRem": { "cbs": 1, "ibs": 0.5 },
  "permitirEstimativas": true, "compararAntigos": false
}
```

### Output

Each successful row has `status: "ok"`, a one-based `index`, `categoria`, `ano`, `selo`, `result`, `steps`, `assumptions`, `warnings`, `format` and `formatted`. The original engine result retains per-tax debits, credits, amounts due, balances, potential buyer credits and source metadata. Explanations and legal parameter notes remain in Portuguese. `formatted` is valid JSON when the selected format is `json`.

Real output of the first example above (`{"categoria":"carga","ano":2026,"base":10000}`), trimmed to the main fields; `assumptions` (7 sourced parameters) and `formatted` are omitted:

```json
{
  "index": 1,
  "status": "ok",
  "billable": true,
  "categoria": "carga",
  "ano": 2026,
  "selo": "verificado",
  "command": "calcular",
  "format": "texto",
  "result": {
    "tributos": {
      "cbs": { "debito": 90, "credito": 0, "devido": 90, "aRecolher": 90, "taxa": { "tipo": "ad_valorem", "valor": 0.009 } },
      "ibs": { "debito": 10, "credito": 0, "devido": 10, "aRecolher": 10, "taxa": { "tipo": "ad_valorem", "valor": 0.001 } }
    },
    "total": { "debito": 100, "credito": 0, "devido": 100, "aRecolher": 100, "saldoCredor": 0 }
  },
  "steps": [{
    "ano": 2026,
    "explanation": [
      "Base informada: R$ 10.000,00, já líquida das exclusões do art. 12 da LC 214/2025.",
      "CBS: débito = R$ 10.000,00 × 0,9% (taxa após transição e redução de 0%) = R$ 90,00. LC 214/2025, arts. 12, 346 e 348; veja a premissa de regime para o artigo da redução.",
      "CBS: crédito regular R$ 0,00 + presumido R$ 0,00 = R$ 0,00; devido antes de deduções R$ 90,00; saldo credor R$ 0,00. LC 214/2025, arts. 47–56. Créditos vedados ignorados: R$ 0,00.",
      "IBS: débito = R$ 10.000,00 × 0,1% (taxa após transição e redução de 0%) = R$ 10,00. LC 214/2025, arts. 12, 343 e 348; veja a premissa de regime para o artigo da redução.",
      "IBS: crédito regular R$ 0,00 + presumido R$ 0,00 = R$ 0,00; devido antes de deduções R$ 10,00; saldo credor R$ 0,00. LC 214/2025, arts. 47–56. Créditos vedados ignorados: R$ 0,00.",
      "O valor a recolher de IBS/CBS R$ 100,00 é compensável com PIS/Cofins e, se não houver débito suficiente, com outros tributos federais (Decreto 12.955/2026, art. 583, I e II; LC 214/2025, art. 348).",
      "Total a recolher de IBS/CBS R$ 100,00. Comparação com tributos antigos desativada; use --comparar para incluí-la. As compensações com esses tributos não foram apuradas."
    ]
  }],
  "warnings": [
    "Not tax advice or legal advice. This educational simulation does not replace a qualified tax or legal professional.",
    "Não é consultoria tributária: simulação educativa com base na lei pública; não substitui contador ou advogado."
  ]
}
```

In 2026 the CBS rate is 0.9% (LC 214/2025, art. 346) and the IBS rate is 0.1% (art. 343), so BRL 10,000 gives BRL 90 + BRL 10. The full `warnings` list also carries the scope and credit-segregation limits. Invalid calculations produce `status: "invalid"`, `billable: false` and an error code/message without received values. They never trigger a calculation event. An empty or all-invalid run fails without a start event. Mixed batches retain valid results and free diagnostics. Charge limits produce free `not_processed` diagnostics for the remaining entries. Invalid initial PPE configuration fails before reading INPUT or writing dataset/KV outputs. Automatic charges must already be absent or zero in the platform configuration; the guard cannot reverse a platform start charge already applied. The key-value store contains `RUN_SUMMARY` with counts, event counts, completion status and the not-tax-advice notice.

### Limits and sources

IBS and CBS credits stay separate. The simulator does not infer a net taxable base from a gross invoice, establish eligibility, calculate effective total tax burden or validate supplied credits. Old-tax comparison keeps bases constant and omits old credits and benefits. Annual reference rates, TAC coefficients and fuel tariffs may remain hypothetical in the snapshot; enabling estimates never enables unverified parameters. Fuel inputs represent the single-stage incidence; liquid volumes must already be converted to 20 °C, and GLP uses kilograms. Detailed simplified regimes, selective tax by product, special financial/real-estate regimes, operational split payment and regional exceptions are outside scope.

The bundled `parametros.json` records verification dates, status, effective dates and document/article references. Public official sources include [Constitutional Amendment 132/2023](https://www.planalto.gov.br/ccivil_03/constituicao/emendas/emc/emc132.htm), [Complementary Law 214/2025](https://www.planalto.gov.br/ccivil_03/leis/lcp/lcp214.htm), the [federal tax authority](https://www.gov.br/receitafederal/), the [IBS management committee](https://www.cgibs.gov.br/) and the [official gazette](https://www.in.gov.br/). Check the bundled dates and current legislation before relying on a scenario.

### Pricing and local execution

**Final prices and packaging approved on 2026-10-24.** The model is **pay per event**:

| Event | Price (USD) | Billing unit |
| --- | ---: | --- |
| `inicio-run` | 0.005 | Once after at least one valid calculation is fully prepared |
| `calculo-concluido` | 0.001 | Each valid calculation delivered with results, steps, assumptions and warnings |

One calculation costs USD 0.006; a batch of 100 costs USD 0.105 when all events are confirmed. A multi-year comparison counts as one calculation. Invalid calculations and diagnostics have no calculation charge. Empty or entirely invalid runs have no start charge. If a spending limit allows the start but prevents delivery, the start may be the only charged event.

The approved prices are embedded in the frozen `EVENT_PRICES_USD` constant in `src/actor/billing.mjs`. The bundled [.actor/pay_per_event.json](.actor/pay_per_event.json) records `approved_2026-10-24_not_published`; this local manifest does not configure platform monetization or authorize publication. In PPE mode, platform event prices must match the numeric constants exactly. Missing events, differing prices, nonzero automatic charges and unexpected paid events fail the initial guard. Automatic `apify-actor-start` and `apify-default-dataset-item` events must be absent or have numeric zero prices.

The Actor declares `apify` and starts at `src/actor/main.mjs`. It serializes charges and honors `ACTOR_MAX_TOTAL_CHARGE_USD`, including zero, charging-manager limits and `eventChargeLimitReached`. The last confirmed unit remains counted when it reaches the limit. Outside PPE, the adapter still calls the SDK event methods; ignored-charge responses with `chargedCount: 0` and no limit flag preserve delivery with `pricingMode: "unpriced"` and `chargeUsd: 0`. Summary event counts in that mode are not monetary charges.

The configured **256 MB** covers the measured local SDK samples: 1 calculation took **0.783 s / 89.8 MiB**, 100 took **1.482 s / 108.9 MiB**, and empty input exited 1 at **0.660 s / 88.3 MiB**. The maximum peak is approximately **109 MiB**; **512 MB is only a fallback**. Runs are limited to 256–512 MB with a 60-second default timeout. Evidence is recorded in `prova/actor-sdk/medicoes.json`. Hosted capacity and local Docker execution remain **NOT_VERIFIED**. Platform build/execution and PPE configuration are pending; publication requires new, separate approval.

For local checks, Node.js 24 is sufficient; the runner uses a file-backed fake Actor, disables network APIs, does not load the SDK and never reads a platform token. No package installation is needed:

```sh
node scripts/actor-local.mjs --input exemplos/carga-tac.json --output tmp/actor-demo
node scripts/measure-actor.mjs
node --test
```

Use a new or empty output directory inside the repository. The runner saves `dataset.jsonl`, `charges.jsonl`, `key-value-store.json` and `measurements.json`. Its events are simulations without real charges; optional `--ppe` uses the approved constants as simulated unit prices. The measurement script runs 1-calculation, 100-calculation and empty-input cases three times and saves SDK-free evidence, separate from the SDK measurements above. The original offline CLI remains available through `node src/cli.mjs` or `npm run cli -- ...`. Price approval is complete; platform validation and publication remain pending.

# Actor input Schema

## `categoria` (type: `string`):

Choose a supported scenario category; this does not establish legal eligibility.

## `ano` (type: `integer`):

Year within the configured transition schedule.

## `base` (type: `number`):

Required net IBS/CBS base after statutory exclusions, not a gross invoice price.

## `creditos` (type: `object`):

Complete numeric object. Unknown fields and personal data are rejected.

## `permitirEstimativas` (type: `boolean`):

Omitted means false: only verified parameters may be used. True also enables old-tax comparison unless compararAntigos is explicitly false.

## `compararAntigos` (type: `boolean`):

Opt-in: omitted follows the CLI (false unless permitirEstimativas is true). Explicit false disables old-tax comparison. Estimated parameters still require consent. No schema default is injected.

## `cumpreObrigacoes` (type: `boolean`):

Omitted means false. A true declaration enables the configured 2026 payment waiver.

## `confirmarEnquadramento` (type: `boolean`):

Omitted means false. Explicit confirmation is required for supported reduced or exempt categories.

## `enquadramentoConfirmado` (type: `boolean`):

Equivalent engine/CLI JSON field. If both aliases are present they must agree.

## `aliquotasPlenas` (type: `object`):

Complete numeric object. Unknown fields and personal data are rejected.

## `aliquotasAntigas` (type: `object`):

Complete numeric object. Unknown fields and personal data are rejected.

## `tac` (type: `object`):

Anonymous cargo-only scenario. No contractor identifiers or free text. Payment and direct contracting must both be true. Presumed credits start in the configured year.

## `produto` (type: `string`):

Required for combustivel only.

## `quantidade` (type: `number`):

Required for combustivel. Up to six decimal places.

## `unidade` (type: `string`):

Must match the product. Liquid volumes must already be converted to 20 degrees Celsius.

## `adRem` (type: `object`):

Complete numeric object. Unknown fields and personal data are rejected.

## `destinacao` (type: `string`):

Required for combustivel; affects potential buyer credits.

## `ibsRecolhido` (type: `boolean`):

Fuel only; enables the configured CBS deduction in the applicable transition period. Omitted means false.

## `comando` (type: `string`):

calcular evaluates the selected year; comparar evaluates all eight years in one dataset item and requires any estimate consent used.

## `formato` (type: `string`):

Structured results are always included; this controls formatted only. Batch entries may override this setting.

## `calculations` (type: `array`):

Optional alternative to the top-level scenario fields; clear Category, Year and Base first, or the run fails with MODO_MISTO. One dataset item per calculation. Invalid entries produce free diagnostics; an all-invalid run fails without any event.

## Actor input object example

```json
{
  "categoria": "carga",
  "ano": 2026,
  "base": 10000,
  "comando": "calcular",
  "formato": "texto"
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `summary` (type: `string`):

RUN_SUMMARY: received, completed and invalid calculations, plus charged events.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "categoria": "carga",
    "ano": 2026,
    "base": 10000
};

// Run the Actor and wait for it to finish
const run = await client.actor("kman-br/brazil-tax-reform-calculator").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "categoria": "carga",
    "ano": 2026,
    "base": 10000,
}

# Run the Actor and wait for it to finish
run = client.actor("kman-br/brazil-tax-reform-calculator").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "categoria": "carga",
  "ano": 2026,
  "base": 10000
}' |
apify call kman-br/brazil-tax-reform-calculator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,kman-br/brazil-tax-reform-calculator"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/AWzoKDFlxHhSP3wb0/builds/1PyFM2lCfNS2FahwL/openapi.json
