NFS-e access key
The 50-digit access key of the national NFS-e, the service invoice of the Sistema Nacional NFS-e.
Validate
Validates the 50-digit access key of a national NFS-e: municipality code (7), generator environment ambGer (1), tax id type (1), tax id (14), NFS-e number nNFSe (13), year and month AAMM (4), numeric code (9) and check digit (1).
- The key may start with
NFS, the prefix of the XMLIdattribute, in any case. Whitespace around the value is ignored. - The DANFSe prints the key as a single block, so it has no printed mask (there is no
nfseKey.format). The 8 fields (municipality code,ambGer, tax id type, tax id,nNFSe,AAMM, numeric code and check digit) may be written apart: any run of whitespace,.,-or/is accepted between two fields, ascpf.isValidreads its mask. A separator inside a field, or between theNFSprefix and the key, makes the value invalid. - Only a string is read. Any other type returns
false. - The municipality code must start with an IBGE state code. The function checks only that prefix and does not look the municipality up.
ambGermust be 1 (municipality system) or 2 (Sistema Nacional NFS-e).- Tax id type 1 is a CPF, left-padded with
000. Type 2 is a CNPJ. The CPF or CNPJ must have valid check digits of its own. - An alphanumeric CNPJ is accepted with type 2, as
cnpj.isValidwith version 2 reads it: letters only in the 14 tax id positions, in any case. The alphanumeric schema comes from the restricted-production (RTC) package of 2026-07-27. The service has handled the alphanumeric CNPJ in production since 2026-08-10, while the production XSD of 2026-02-09 still types the key as digits only. - The letters of an alphanumeric CNPJ stand in the 14 positions of the tax id (10 to 23 of the key), as
TSIdNFSeof the schema bundle of 2026-07-27 types them. - The NFS-e number cannot be all zeros. The month must be 01 to 12.
- The check digit is a modulus 11 over the first 49 characters, weights 2 to 9 from the right. A remainder of 0 or 1 gives 0. A letter counts as its ASCII code minus 48 (
Ais 17), by analogy with NT Conjunta 2025.001. - No official document states the weights or the remainder rule; the documents only say "módulo 11". The rule was confirmed against more than a hundred NFS-e keys from public repositories, from both environments, with remainders 0, 1 and 10 among them.
- The example key in item 9.1 of the Guia do Emissor v1.2 is not valid: its check digit does not match and its CNPJ is invalid.
- The keys of the municipal NFS-e models that are not the national standard are out of scope, and so is the 44-digit DF-e key (use
nfeKey.isValid).
| Parameter | Type | Required |
|---|---|---|
value | string | yes |
| returns | boolean |
Check if the access key (chave de acesso) of a national NFS-e, the Nota Fiscal de Serviço eletrônica of the Sistema Nacional NFS-e, is valid.
- The key is one block of 50 characters,
Cód.Mun.(7) Amb.Ger.(1) Tipo de Inscrição Federal(1) Inscrição Federal(14) nNFSe(13) AAMM(4) Cód.Num.(9) DV(1), all digits except an alphanumeric CNPJ in the Inscrição Federal. - The
NFSliteral theIdattribute ofinfNFSeputs in front of the key is stripped, with surrounding whitespace. - The DANFSe prints the key as a single block, so it has no printed mask. The boundaries between its 8 fields accept the mask characters
isValidCpfreads (whitespace,.,-or/, alone or in a run), while a separator inside a field makes the value invalid. - The municipality code must start with an IBGE UF code; it is not looked up in the IBGE table.
ambGermust be1(the system of the municipality) or2(the Sistema Nacional NFS-e), and the registration type1(a CPF, left padded with000) or2(a CNPJ, numeric or alphanumeric), with a CPF or CNPJ whose own check digits are valid. Letters are accepted in a CNPJ only, and lower case is read as upper case, asisValidCnpjwith{ version: 2 }reads it.nNFSemust not be all zeros and the month must be 01 to 12.- The check digit is a modulus 11 over the first 49 characters, weights 2 to 9 cycling from the right, where a remainder of 0 or 1 gives 0. A letter counts as its ASCII code minus 48 (
Ais 17). No official document states it: the NFS-e technical notes 001 to 009, the Anexo I and the Perguntas e Respostas of 08/09/2026 are silent, and Nota Técnica Conjunta 2025.001, whose ASCII minus 48 rule covers the DF-e key, lists the documents it covers (NF-e, NFC-e, CT-e, CT-e OS, GTV-e, MDF-e, BP-e, BP-e TM, NF3e and NFCom) without the NFS-e. The rule is taken by analogy with that NT and the CNPJ's own check digits. - The letters follow
TSIdNFSeof the schema bundle of 2026-07-27, in the positions of the Inscrição Federal (10 to 23). The production bundle of 09/02/2026 still types the key[0-9]{50}. - The municipal NFS-e models that are not the national standard are out of scope.
import { isValidNfseKey } from '@brazilian-utils/brazilian-utils';
isValidNfseKey('35503082258716523000119000000000001226011357924683'); // true (CNPJ issuer, SP)
isValidNfseKey('NFS35503082258716523000119000000000001226011357924683'); // true (XML Id prefix)
isValidNfseKey('43149021100040364478829000000000105725120484407255'); // true (CPF issuer, RS)
isValidNfseKey('35503082212ABC34501DE35000000000001226091357924682'); // true (alphanumeric CNPJ issuer)
isValidNfseKey('35503082258716523000119000000000001226011357924684'); // false (check digit)
isValidNfseKey('3550308 2 2 58716523000119 0000000000012 2601 135792468 3'); // true (separators between the fields)Try it with JavaScript isValidNfseKey
Shared test cases (29) and the result in each library nfseKey.isValid
Parse
Removes the formatting of a national NFS-e access key and keeps digits and upper-case letters, capped at 50 characters.
- Letters before the first digit are dropped, the
NFSprefix of the XMLIdattribute included. Letters after it are kept in upper case, because an alphanumeric CNPJ carries them.nfseKey.isValidchecks where they stand. - Every other character is removed. A partial key is kept as far as it goes.
- A number is read only when it is a safe non-negative integer. Any other number returns an empty string.
- The result is the single block the DANFSe prints, so there is no
nfseKey.format.
| Parameter | Type | Required |
|---|---|---|
value | string | number | yes |
| returns | string |
Remove everything but the digits and the letters of an alphanumeric CNPJ from the access key of a national NFS-e, and cap the result to 50 characters.
-
Letters are upper cased, as
parseCnpjwith{ version: 2 }does, and the letters in front of the first digit are dropped, theNFSprefix of the XMLIdattribute included, since the key opens with digits.isValidNfseKeychecks that the letters left stand in a CNPJ. -
That is the form the leiaute stores the key in and the one the DANFSe prints, a single block, which is why there is no
formatNfseKey.
import { parseNfseKey } from '@brazilian-utils/brazilian-utils';
parseNfseKey('NFS35503082258716523000119000000000001226011357924683');
// '35503082258716523000119000000000001226011357924683'
parseNfseKey('3550308 2 2 58716523000119 0000000000012 2601 135792468 3');
// '35503082258716523000119000000000001226011357924683'
parseNfseKey('nfs3550308 2 2 12.abc.345/01de-35 0000000000012 2609 135792468 2');
// '35503082212ABC34501DE35000000000001226091357924682'Try it with JavaScript parseNfseKey
Shared test cases (16) and the result in each library nfseKey.parse
Decode
Parses a national NFS-e access key into its fields. It accepts the same input as nfseKey.isValid and returns null exactly when that function returns false.
- The separators between fields are accepted as in
nfseKey.isValid. TheNFSprefix must touch the key. Only a string is read: any other type returnsnull. - Fields:
municipalityCode(7 digits, a string),stateCode(the 2-letter UF read from the first 2 digits of the municipality code),generatorEnvironment(1 municipality, 2 Sistema Nacional NFS-e),taxIdType(cpforcnpj),taxId,number(the NFS-e number, a number from 1 to 9999999999999),year,month(1 to 12),code(the numeric code, a string) andcheckDigit(a number). - The tax id is the 11-digit CPF without the
000padding of the key, or the 14-character CNPJ, numeric or alphanumeric, in upper case. - The year is 2000 plus the 2 digits of the key. The numeric code keeps its 9 digits, leading zeros included.
| Parameter | Type | Required |
|---|---|---|
value | string | yes |
| returns | NfseKeyInfo | null |
Parse the access key of a national NFS-e into its fields, as an NfseKeyInfo. Accepts the same input forms as isValidNfseKey.
- Returns
municipalityCode,stateCode,generatorEnvironment,taxIdType,taxId,number,year,month,codeandcheckDigit. generatorEnvironmentis anNfseKeyGeneratorEnvironment:1the system of the municipality,2the Sistema Nacional NFS-e.taxIdTypeis anNfseKeyTaxIdType,'cpf'or'cnpj', andtaxIdis the 11 digit CPF, without the000that pads it in the key, or the 14 character CNPJ, numeric or alphanumeric, in upper case.- Returns
nullwhen the key is not valid.
import { getNfseKeyInfo } from '@brazilian-utils/brazilian-utils';
getNfseKeyInfo('35503082258716523000119000000000001226011357924683');
// { municipalityCode: '3550308', stateCode: 'SP', generatorEnvironment: 2, taxIdType: 'cnpj',
// taxId: '58716523000119', number: 12, year: 2026, month: 1, code: '135792468', checkDigit: 3 }
getNfseKeyInfo('43149021100040364478829000000000105725120484407255');
// { municipalityCode: '4314902', stateCode: 'RS', generatorEnvironment: 1, taxIdType: 'cpf',
// taxId: '40364478829', number: 1057, year: 2025, month: 12, code: '048440725', checkDigit: 5 }
getNfseKeyInfo('35503082212ABC34501DE35000000000001226091357924682');
// { municipalityCode: '3550308', stateCode: 'SP', generatorEnvironment: 2, taxIdType: 'cnpj',
// taxId: '12ABC34501DE35', number: 12, year: 2026, month: 9, code: '135792468', checkDigit: 2 }
getNfseKeyInfo('invalid'); // nullSource: the technical documentation of the Sistema Nacional NFS-e, whose schema types TSIdNFSe and TSChaveNFSe and ANEXO I field NFSe/infNFSe/id define the layout and the rules E1280 and E1284, the manual da emissão por decisão administrativa ou judicial, which names the modulus 11 check digit, Nota Técnica SE/CGNFS-e 008 (item 2.1.1), which prints the key as a single block, the schemas updated for the alphanumeric CNPJ (the restricted-production bundle v1.01-20260727; the service handles the alphanumeric CNPJ in production since 2026-08-10, while the production bundle of 2026-02-09 is still digits only) and Nota Técnica Conjunta 2025.001, whose ASCII minus 48 rule for the NF-e key the check digit borrows.
Try it with JavaScript getNfseKeyInfo
Shared test cases (28) and the result in each library nfseKey.getInfo
Official sources
- gov.br/nfse/pt-br/…/documentacao-tecnica
- gov.br/nfse/pt-br/…/documentacao-atual
- gov.br/nfse/pt-br/…/manual-contribuintes-emissor-publico-api-emissao-decisao-administrativa-e-judicial.pdf
- gov.br/nfse/pt-br/…/nt-008-se-cgnfse-danfse-20260714-v1-02.pdf
- gov.br/nfse/pt-br/…/esquemas-nfse-rtc-v1-01-20260727.zip
- nfe.fazenda.gov.br/portal/exibirArquivo.aspx
See also NF-e access key, Municipalities
Last updated on
