[EN] DERE: chart of accounts via the Accounts API

Load the DeRE chart of accounts through the Accounts API, with D-1011 mappings, examples, validations and errors.

1. Context

The DeRE (Declaração de Regimes Específicos) is the ancillary obligation of IBS and CBS for the specific regimes. One of its first events is the D-1011, Plano Geral de Contas Comentado (PGCC): the company's chart of accounts, with the tax classification of each account. The Brinta platform receives the accounts, builds the D-1011, validates it and transmits it to the Receita.

ModuleInput dataChannelCadence
Eventual (D-1011)Chart of accounts, with codTrib and referential plan per accountAccounts API (this guide), web interface or templateOnce, and on every change to the chart
Periodic (D-1101, D-1106, D-1199)Trial balance and journal entriesCSV via SFTP or Batch APIMonthly
TransactionalBilling and salesREST API or Batch APIDaily or continuous

This guide only covers loading the chart of accounts with the Accounts API. Each account you create becomes an account (infoConta) in the D-1011. The accounts are also the reference for the monthly events: every account that appears in the trial balance must exist and be in force in the chart.

Out of scope: balances and journal entries (Accounting Entries API) and the operations of the transactional event (Transactions API and Batch API). They are mentioned only as context. See DeRE: sending transactions to Brinta.

2. Before you start

RequirementDetail
Company registered in BrintaThe filing company must exist in Brinta with its CNPJ. Brinta uses the root CNPJ to identify it in the DeRE
Supported regimeToday Brinta generates the D-1011 for the Financial Services regime
Referential planThe available referential chart of accounts is COSIF
API tokenFound in the dashboard, under Company Management › API & Integrations
Account → codTrib relationYour tax team defines which codTrib applies to each analytical account. It is a business input: the integration only carries it
Account → COSIF relationYour tax team defines which COSIF account applies to each account in the chart, synthetic ones included
Mixed accounts resolvedEach analytical account must have a single codTrib. If an account has more than one, it must be split before it is sent (section 3)

Not sent through the Accounts API: the referential plan of the D-1011 header (planoCtaRef) and the closing frequency (freqEncerr). They are set once in the company's DeRE filing, with the Brinta team.

3. Key concepts

You don't need to know accounting to integrate, but you do need to understand what each piece of data represents.

ConceptWhat it isWhere it goes in the API
Chart of accountsThe company's list of accounts, organized as a treeOne POST call per account
Synthetic accountGroups other accounts. Holds no balance. It is the only kind that can be a parenttype: "S"
Analytical accountA leaf of the tree: holds a balance and has no childrentype: "A"
LevelDepth of the account in the tree, from 1 to 99. Level-1 accounts have no parentlevel
Parent accountThe synthetic account it depends on. Every account above level 1 has a parentparent_account
Account natureThe accounting group it belongs to: 1 asset, 2 liability, 3 equity, 4 revenue, 5 expensenature
Balance natureWhether the balance is normally C (credit), D (debit) or V (variable)sub_nature
codTribIBS and CBS taxation code, 9 digits, from DeRE Table 11. Only analytical accounts carry itaccount_mappings, group CodTrib IBS/CBS - DeRe
Referential plan (COSIF)The official account equivalent to your account, in the Central Bank's chart. Every account has oneaccount_mappings, group COSIF
ISS indicator1 if the account is subject to ISS, 0 if not. Analytical accounts onlycode_mappings, type dere_ind_trib_iss
Mixed accountAn analytical account with more than one codTrib. The DeRE does not accept itResolved by splitting it
Split (desdobramento)The mixed account becomes synthetic, and one analytical child account is created for each codTrib. The children share the original's COSIF accountsplit_code
Split codeThree digits: 000 for an unsplit account or for the original account; 001, 002, … for each childsplit_code
Full code (cCta)The account's internal code followed by its split code, with no dots or dashes. For example, 1101 + 000 = 1101000See section 4.4

4. Structure of a DeRE account

Example of an unsplit analytical account, with its codTrib, COSIF account and ISS indicator, with POST /accounts:

{
  "account_external_id": "1101000",
  "company_account_external_id": "CLI-98765",
  "location": "BR",
  "name": "Caixa e equivalentes de caixa",
  "description": "Disponibilidades em caixa e em contas de liquidez imediata",
  "type": "A",
  "level": 3,
  "order_id": 3,
  "nature": 1,
  "sub_nature": "D",
  "parent_account": "11000",
  "split_code": "000",
  "status": "ACTIVE",
  "valid_from": "2026-10-01T00:00:00Z",
  "account_mappings": [
    { "group": "CodTrib IBS/CBS - DeRe", "account": "118915099" },
    { "group": "COSIF", "account": "1.1.1.10.00.00-8" }
  ],
  "code_mappings": [
    { "type": "dere_ind_trib_iss", "value": "0" }
  ]
}

The other Accounts API fields (name_alt, account_alt, hierarchy_code, centers and others) can be sent in the same format. They do not go into the D-1011.

4.1 Account fields

FieldRequired by the APIRequired by the DeREDescription
account_external_idYesYesFull account code (internal + split). Unique per company. See section 4.4
company_account_external_id or company_idOne of the twoYesThe filing company: its ID in your system or its UUID in Brinta. Never both
locationYesYesBR
nameYesYesAccount name. Up to 100 characters in the DeRE
descriptionYesYes, for analytical accountsAccount description. Up to 300 characters in the API
typeYesYesS synthetic or A analytical. See section 4.2
levelYesYesLevel from 1 to 99
order_idYesNoDisplay order. Brinta sorts the D-1011 accounts by code, not by this field
natureNoYesAccount nature, from 1 to 5. See section 4.3
sub_natureNoYesBalance nature: C, D or V. See section 4.3
parent_accountNoYes, if level > 1Full code of the parent account. See section 4.4
split_codeNoYesSplit code, from 000 to 999. See section 4.4
statusNoNoACTIVE (default) or INACTIVE
valid_fromNoYesStart of the account's validity (ISO 8601). See section 4.5
valid_untilNoNoEnd of validity. Cannot be earlier than the start
account_mappingsNoYesThe codTrib and the COSIF account. See section 4.6
code_mappingsNoYes, for analytical accountsThe ISS indicator. See section 4.6

Several fields are optional for the API but required by the DeRE. If they are missing, the API still creates the account, but the D-1011 comes out with errors and Brinta does not transmit it until they are fixed.

4.2 type: synthetic or analytical

Send S for accounts that group others and A for accounts that hold a balance.

  • An account is synthetic if and only if another account has it as its parent.
  • Every level-1 account is synthetic.
  • An analytical account cannot be the parent of another account.

The API accepts any text in type and stores it as received, because the field is used by other obligations. For the DeRE, Brinta recognizes S and A (also SYNTHETIC and ANALYTIC). If any other value arrives, it infers the type from the hierarchy.

4.3 nature and sub_nature

These are two different pieces of data and must not be confused.

FieldWhat it representsValues for the DeRE
natureThe account's accounting group (codNat in the D-1011)1 asset · 2 liability · 3 equity · 4 revenue · 5 expense
sub_natureWhich side the balance is usually on (natCta in the D-1011)C credit · D debit · V variable
  • The API accepts any integer in nature. For the DeRE it must be a value from 1 to 5.
  • sub_nature only accepts C, D or V. If you don't have the value, don't send the field: sending it empty or as null returns an error.
  • Brinta checks that the first digit of the codTrib is consistent with nature: 1 asset, 2 liability or equity, 3 revenue, 4 expense. A mismatch is reported as a warning.

4.4 Code, split and parent account

  • account_external_id: the account's full code (cCta): the internal code plus the split code, with no dots or dashes (1101 + 000 = 1101000). It must be unique in the chart.
  • split_code: the split code, also sent on its own. 000 on every unsplit account and on the original account of a mixed account; 001, 002, … on each child. Always three digits, as text.
  • The full code must end with the split_code: Brinta obtains the internal code (cCtaInterna) by removing the split_code from the end (1101000 − 000 → 1101).
  • parent_account: the full code of the parent account, which must already exist in the same company, be synthetic and be active.
  • level: must be greater than the parent's level. Use the parent's level + 1.

4.5 Dates

  • valid_from is the start of the account's validity (iniVig) and is required by the DeRE. Send the date from which the account is in use.
  • valid_until is the end of validity (fimVig). Send it only if the account is no longer used.
  • If you don't send start_date, the API sets it to the value of valid_from, and vice versa.
  • The end can never be earlier than the start: the API rejects it.

4.6 Mappings for the DeRE

The DeRE uses three pieces of data that are not plain account fields but correspondences.

DataHow it is sentApplies toRule
codTribaccount_mappings: { "group": "CodTrib IBS/CBS - DeRe", "account": "<codTrib>" }Analytical onlyA single codTrib per account, 9 digits, existing in Table 11
COSIF accountaccount_mappings: { "group": "COSIF", "account": "<COSIF code>" }All accountsA single COSIF account per account. The children of a split use the same one as the original
ISS indicatorcode_mappings: { "type": "dere_ind_trib_iss", "value": "0" } or "1"Analytical onlyNot allowed on synthetic accounts
  • The COSIF code is sent exactly as it appears in the chart, with dots and dash (1.1.1.10.00.00-8). With digits only (1111000008) the API answers Account … not found in group COSIF.
  • The API rejects an account from a group that does not exist, a repeated group, and more accounts than the group allows.
  • The API response does not return account_mappings or code_mappings. To check them after the load, use Account Management in the dashboard.

4.7 From JSON to the D-1011 event

D-1011 fieldAPI field
cCtaaccount_external_id (full code)
cCtaInternaaccount_external_id without the trailing split_code
cDbrMistasplit_code
nomeCtaname
indCtatype
descCtadescription
cCtaSupparent_account
cCtaRefaccount_mappings, group COSIF
nivelCtalevel
natCtasub_nature
codNatnature
codTribaccount_mappings, group CodTrib IBS/CBS - DeRe
indTribISScode_mappings, type dere_ind_trib_iss
iniVigvalid_from
fimVigvalid_until

Brinta generates the rest: the company's root CNPJ (nrInsc), the referential plan and closing frequency of the header, the event's validity period, the order of the accounts, the event identifier and the signature.

5. Integration flow

  1. Prepare the data with the tax team. For each account in the chart: type, level, parent, nature, balance nature, COSIF account and, if analytical, codTrib and ISS indicator.
  2. Resolve the mixed accounts. Every analytical account with more than one codTrib is split into a synthetic account (000) and one analytical child per codTrib (001, 002, …), before anything is sent.
  3. Order the load. Send the level-1 accounts first, then level 2, and so on: an account is only created if its parent already exists.
  4. Create each account with a POST /accounts.
  5. Read the response. 200 means the account was created. Any other status means it was not (section 8).
  6. Check with GET /accounts the accounts you want to verify.
  7. Let Brinta know when the load is finished, so it generates the D-1011.

A 200 response confirms that the account was saved, not that it meets the DeRE rules. Those rules are checked when Brinta generates the D-1011 (section 8.2), so validate them before sending.

When the chart changes. A new account or a new split is loaded with the same POST. The Accounts API does not allow editing an existing account: changes to accounts already created are made from the dashboard. In both cases, Brinta generates a new version of the D-1011 with the new validity.

6. Endpoints and authentication

MethodEndpointWhat it does
POSThttps://api.brinta.com/accountsCreates an account
GEThttps://api.brinta.com/accounts?account_external_id={code}&company_account_external_id={company}Returns an account by its code

Authentication: Authorization: Bearer <token>, with Content-Type: application/json.

Identifying the company. Send exactly one of these two fields: in the body for the POST, as a query parameter for the GET.

FieldWhat it is
company_account_external_idThe company's ID in your system
company_idThe company's UUID in Brinta

Optionally, parent_company_id or parent_company_external_id check that the company belongs to that group. A token can only read and write accounts of the companies in its own group.

7. Examples

A minimal chart of six accounts: two synthetic, one analytical, and a mixed account split into two children. The COSIF accounts and codTribs are real; the classification of each account is illustrative only.

CodeNametypelevelParentsplit_codeCOSIFcodTrib
1000AtivoS10001.0.0.00.00.00-9
11000DisponibilidadesS210000001.1.0.00.00.00-2
1101000CaixaA3110000001.1.1.10.00.00-8118915099
7101000Rendas de empréstimosS3710000007.1.1.05.00.00-8
7101001Rendas de empréstimos: créditoA471010000017.1.1.05.00.00-8311011101
7101002Rendas de empréstimos: câmbioA471010000027.1.1.05.00.00-8311011102

(Account 71000 and its ancestors are loaded the same way as 1000 and 11000.)

7.1 Level-1 synthetic account

curl -X POST https://api.brinta.com/accounts \
  -H "Authorization: Bearer $BRINTA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "account_external_id": "1000",
    "company_account_external_id": "CLI-98765",
    "location": "BR",
    "name": "Ativo",
    "description": "Ativo total",
    "type": "S",
    "level": 1,
    "order_id": 1,
    "nature": 1,
    "sub_nature": "D",
    "split_code": "000",
    "valid_from": "2026-10-01T00:00:00Z",
    "account_mappings": [
      { "group": "COSIF", "account": "1.0.0.00.00.00-9" }
    ]
  }'

A synthetic account carries no codTrib or ISS indicator, but it does carry its COSIF account.

7.2 Intermediate synthetic account

{
  "account_external_id": "11000",
  "company_account_external_id": "CLI-98765",
  "location": "BR",
  "name": "Disponibilidades",
  "description": "Disponibilidades",
  "type": "S",
  "level": 2,
  "order_id": 2,
  "nature": 1,
  "sub_nature": "D",
  "parent_account": "1000",
  "split_code": "000",
  "valid_from": "2026-10-01T00:00:00Z",
  "account_mappings": [
    { "group": "COSIF", "account": "1.1.0.00.00.00-2" }
  ]
}

7.3 Analytical account

This is the example in section 4: 1101000, with codTrib 118915099, COSIF 1.1.1.10.00.00-8 and ISS indicator 0.

7.4 Split mixed account

First the original account, now synthetic, with split_code 000:

{
  "account_external_id": "7101000",
  "company_account_external_id": "CLI-98765",
  "location": "BR",
  "name": "Rendas de empréstimos",
  "description": "Rendas de empréstimos",
  "type": "S",
  "level": 3,
  "order_id": 20,
  "nature": 4,
  "sub_nature": "C",
  "parent_account": "71000",
  "split_code": "000",
  "valid_from": "2026-10-01T00:00:00Z",
  "account_mappings": [
    { "group": "COSIF", "account": "7.1.1.05.00.00-8" }
  ]
}

Then one child per codTrib, each with its own split_code and the same COSIF account:

{
  "account_external_id": "7101001",
  "company_account_external_id": "CLI-98765",
  "location": "BR",
  "name": "Rendas de empréstimos: operações de crédito",
  "description": "Rendas de operações de crédito",
  "type": "A",
  "level": 4,
  "order_id": 21,
  "nature": 4,
  "sub_nature": "C",
  "parent_account": "7101000",
  "split_code": "001",
  "valid_from": "2026-10-01T00:00:00Z",
  "account_mappings": [
    { "group": "CodTrib IBS/CBS - DeRe", "account": "311011101" },
    { "group": "COSIF", "account": "7.1.1.05.00.00-8" }
  ],
  "code_mappings": [
    { "type": "dere_ind_trib_iss", "value": "0" }
  ]
}
{
  "account_external_id": "7101002",
  "company_account_external_id": "CLI-98765",
  "location": "BR",
  "name": "Rendas de empréstimos: operações de câmbio",
  "description": "Rendas de operações de câmbio",
  "type": "A",
  "level": 4,
  "order_id": 22,
  "nature": 4,
  "sub_nature": "C",
  "parent_account": "7101000",
  "split_code": "002",
  "valid_from": "2026-10-01T00:00:00Z",
  "account_mappings": [
    { "group": "CodTrib IBS/CBS - DeRe", "account": "311011102" },
    { "group": "COSIF", "account": "7.1.1.05.00.00-8" }
  ],
  "code_mappings": [
    { "type": "dere_ind_trib_iss", "value": "0" }
  ]
}

7.5 Get an account

curl "https://api.brinta.com/accounts?account_external_id=1101000&company_account_external_id=CLI-98765" \
  -H "Authorization: Bearer $BRINTA_TOKEN"

Response 200:

{
  "account_external_id": "1101000",
  "company_id": "7b1e2c4a-0d3f-4e5a-9b8c-1a2b3c4d5e6f",
  "company_account_external_id": "CLI-98765",
  "location": "BR",
  "name": "Caixa e equivalentes de caixa",
  "description": "Disponibilidades em caixa e em contas de liquidez imediata",
  "type": "A",
  "level": 3,
  "order_id": 3,
  "nature": 1,
  "sub_nature": "D",
  "parent_account": "11000",
  "split_code": "000",
  "status": "ACTIVE",
  "start_date": "2026-10-01T00:00:00Z",
  "valid_from": "2026-10-01T00:00:00Z",
  "centers": []
}

The response does not include account_mappings or code_mappings.

8. Validations and errors

8.1 Errors returned by the API

Format errors. Always answer 400, before any rule is applied. details carries only the first error found.

{
  "status_code": 400,
  "error": "Bad Request",
  "message": "Validation error: The provided data does not match the required format",
  "details": {
    "code": "INVALID_PARAMETERS",
    "message": "'split_code' must be 3 digits, from 000 to 999",
    "invalid_params": ["split_code"]
  }
}
details.codeWhen
INVALID_PARAMETERSBoth or neither company identifiers were sent, account_external_id is missing, or split_code does not have three digits
INVALID_ENUM_VALUEstatus or sub_nature outside its list (including sub_nature as null)
REQUIRED_FIELDA required field is missing, or type/value is missing in a code mapping, or group/account in an account mapping
No codeAny other format error: an unknown field, a wrong type, an invalid date or a text longer than the maximum

Business-rule errors. Answer with this body, without an error code: the message says which rule failed.

{ "response_data_body": "Parent account must be of type SYNTHETIC (S)", "status_code": 400 }
Statusresponse_data_bodyWhen
404Company not found or not related to parent companyThe company does not exist or is not in your token's group
400National account already exists with account <code> and company <company>The code already exists in that company
404Parent account not found for <code>No account with that parent_account exists in the company
400More than one account with code <code> in the companyThe parent_account matches more than one account
400Parent account must be of type SYNTHETIC (S)The parent is not synthetic
400Parent account must be ACTIVEThe parent is inactive
400Parent account level must be lower than the account levelThe level is not greater than the parent's
400Location not foundlocation is not a valid country
400End date cannot be before the start dateThe end date is earlier than the start date
400Unknown code mapping type: <types>A type in code_mappings does not exist
400Code mapping type sent more than once: <types>A type is repeated in code_mappings
400Account <code> not found in group <plan>The group, or the account in the group, does not exist
400More than one account <code> in group <plan>The code is duplicated inside the group
400Account mapping sent more than once: <plan>/<code>The same pair is repeated in account_mappings
400Too many accounts mapped for the groupMore accounts were mapped than the group allows
500Error creating national accountSaving failed
500Error processing centersThe centers failed, but the account was already created: a retry returns the duplicate-account error
500Account created but could not be retrievedThe account was created, but could not be read for the response

8.2 DeRE rules the API does not validate

The API saves the account even if it breaks these rules. Brinta checks them when it generates the D-1011, and an event with errors is not transmitted until they are fixed. To avoid finding them at that point, validate them before sending.

RuleWhat to check
Unique codeNo two accounts can share the same full code
Full codeaccount_external_id ends with the account's split_code
HierarchyLevel-1 accounts have no parent; the others do, and the parent is synthetic
DescriptionEvery analytical account has a description
codTrib requiredEvery analytical account has exactly one codTrib
codTrib not allowedSynthetic accounts carry no codTrib
codTrib format9 digits, no leading zero, and existing in Table 11
ISS indicatorAnalytical accounts only, with value 0 or 1
COSIF accountEvery account has one, and it exists in the COSIF plan
SplitAn account with split_code above 000 is analytical; its original (000) is synthetic and has the same COSIF account
Naturenature from 1 to 5 and sub_nature filled in on every account
Validityvalid_from filled in on every account

9. Go-live checklist

  • Filing company registered in Brinta with its CNPJ.
  • DeRE filing configured by Brinta (regime, referential plan and closing frequency).
  • API token generated.
  • Account → codTrib and account → COSIF relations defined by the tax team.
  • Mixed accounts split, with split_code on every account.
  • type, nature, sub_nature and valid_from filled in on every account.
  • Section 8.2 rules validated before sending.
  • Load ordered by level: parents before children.
  • 4xx and 5xx errors handled (section 8.1).
  • Brinta notified when the load is finished, so it generates the D-1011.

Did this page help you?