NRA HFRG - Flat XML Import Format

Simplified XML for feeding declaration data into the hub. "Flat" means all single-value fields sit at one level under the root (e.g. CarrierName instead of carrier/reprfirm/name). Only the repeating collections - counterparties, addresses, goods - are nested.

Two entry points consume this format:

Both paths use the same element names. Where their behaviour differs, it is called out below.

Files in this folder

FileRoot elementDirectionWhat it is
flat-import-template.xmlHFRGBULGARIAinputTransport declaration template - Import (9), Export (10), Internal (13), ThirdCountry (14). Every element is present; fill only those relevant to the chosen OperationType. Colour-coded copy: flat-import-template.html
flat-import-annul.xmlHFRGAnnulinputCancel template - cancellation (11)
flat-import-confirm.xmlHFRGConfirminputConfirm template - confirmation (12)
flat-import-result.xmlETRANSPORTBGUINCODEoutputResult file the hub writes back once the NRA assigns a UIN
flat-import.xsd--Schema for the three input formats - see below
field-mapping.md--This document, in Markdown

Schema

flat-import.xsd describes all three input roots, so one schema covers every input file. Validation is optional - the hub does not require it and never asks for a schema reference - but a file can be checked against it before being sent, by pointing the document at it:

<HFRGBULGARIA xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:noNamespaceSchemaLocation="flat-import.xsd">

Every length, pattern and enumeration in it is copied from the NRA schema for the element it converts into, so nothing in it is stricter than the corresponding NRA rule. Where the NRA schemas differ between a person and a firm - the carrier identifier and its type - the schema accepts the union of both, because XSD 1.0 cannot switch on the value of another element.

It checks values, not completeness: which elements are required depends on OperationType, which XSD 1.0 cannot express, so nearly everything is optional and the tables below remain the reference. Element order is not enforced either, and empty elements are valid everywhere, both matching how the converter reads the file.

Declaration types

OperationTypeDeclarationDescriptionRoot element
9ImportGoods from another EU Member State into BulgariaHFRGBULGARIA
10ExportGoods from Bulgaria to another EU Member StateHFRGBULGARIA
13Internal TransportGoods transported within BulgariaHFRGBULGARIA
14Third CountryGoods from a non-EU country after customs clearanceHFRGBULGARIA
11Cancellation (Annul)Cancel a previously submitted declarationHFRGAnnul
12ConfirmationConfirm receipt or dispatch of goodsHFRGConfirm

HFRGAnnul and HFRGConfirm are routed by their root element name; their OperationType is not read.

Header

ElementDescriptionRead by the hub
OperationTypeDeclaration type code: 9, 10, 13 or 14YES - selects the target declaration
InternalReferenceReference from the source systemYES - see below
UINUIN of the declaration being correctedYES - leave empty for a new declaration
VersionFormat versionno - accepted and ignored
FiscalRegNoBulstat/EIK of the submitting entityno - accepted and ignored
TransportDateDate/time of transportno - accepted and ignored

InternalReference is more than a label: it becomes the job folder name (invalid file name characters and spaces are stripped) and is echoed back as INTERNALREFEREN in the result file. When it is empty a GUID is used instead, and the result can no longer be matched to the source document.

What the hub does with the file

Fields the hub fills in itself

ElementBehaviour
ContactName, ContactPhone, ContactPhoneCode, ContactEmail, DeclarantNameOptional. When empty, taken from the default signer in Settings > Senders. The signing pipeline then overwrites them with the details of the signer that actually succeeded, so values supplied in the file are not guaranteed to survive.
IsCorrectNot read from the file. The hub always submits true.

Address codes: postal code, not EKATTE

Every *Ekatte element expects a 4-digit postal code. The hub resolves it to an EKATTE code through wwwroot/data/postal-to-ekatte.json.

In the flat XMLIn the submitted declaration
<Ekatte>1000</Ekatte><ekatte>68134</ekatte>

A value that is not a known postal code is left blank on purpose, so the declaration fails validation instead of being submitted with a wrong EKATTE. Passing an EKATTE code directly (68134) therefore drops the field.

The browser importer is more forgiving: when the lookup fails it leaves the raw value in the form field. The SAP folder path does not.

Affects LoadEkatte, TranshipmentEkatte, TransferEkatte and Address/Ekatte.

1. Flat XML element reference by declaration type

Flat XML elementXSD fieldImport (9)Export (10)Internal (13)ThirdCountry (14)
RecipientIdentrecipient/identREQREQ--
RecipientIdentTyperecipient/identtypeREQREQ--
ShipperIdentshipper/ident--REQREQ
ShipperIdentTypeshipper/identtype--REQREQ
IsSrissr-REQ--
CustomsOfficecustoms/customsoffice---REQ
CustomsDocumentcustoms/document---REQ
CustomsDatecustomsdate---REQ
CustomsTimecustomstime---REQ (empty becomes 00:00)
CustomsLocationcustomslocation---REQ
HasCarrier, CarrierIsPerson, CarrierName, CarrierIdent, CarrierIdentTypecarrieroptoptoptopt
HasOrganizer, OrganizerIsPerson, OrganizerName, OrganizerIdent, OrganizerIdentTypeorganizeroptoptoptopt
RegVehicleregvehicleREQREQREQREQ
RegTrailer1regtrailer1optoptoptopt
RegTrailer2regtrailer2optoptoptopt
LoadLocalAddress, LoadEkattereceivedaddress / loadaddress-REQREQ-
LoadStreet, LoadNumberreceivedaddress / loadaddress-optopt-
LoadDatereceiveddate / loaddate-REQREQ-
LoadTimereceivedtime / loadtime-optREQ (empty becomes 00:00)-
IsTranshipmenttranshipment/istranshipmentoptoptopt-
TranshipmentTransportTypetranshipment/transporttypeoptoptopt-
TranshipmentDatetranshipment/transdateoptoptopt-
TranshipmentTimetranshipment/transtimeoptoptopt-
TranshipmentLocalAddress, TranshipmentStreet, TranshipmentNumber, TranshipmentEkattetranshipment/transaddressoptoptopt-
IsTransferistransferREQREQREQREQ
TransferLocalAddress, TransferStreet, TransferNumber, TransferEkattetransferaddressoptoptoptopt
TransferDatetransferdateoptoptoptopt
TransferTimetransfertimeoptoptoptopt
TransCarrierIsPerson, TransCarrierName, TransCarrierIdent, TransCarrierIdentTypetranscarrieroptoptoptopt
TransRegVehicletransregvehicleoptoptoptopt
TransRegTrailer1transregtrailer1optoptoptopt
TransRegTrailer2transregtrailer2optoptoptopt
ContactNamecnameautoautoautoauto
ContactPhonecphoneautoautoautoauto
ContactPhoneCodecphonecodeautoautoautoauto
ContactEmailcpemailautoautoautoauto
DeclarantNamednameautoautoautoauto

auto = optional in the file; filled from the signer settings and rewritten per signer at signing time.

The transhipment block is ignored unless IsTranshipment is true; the transfer block unless IsTransfer is true; carrier and organizer unless the matching Has... flag is true and the corresponding ...Ident is non-empty. The transfer carrier is skipped when TransCarrierIdent is empty.

2. Counterparties (Import, Internal, ThirdCountry)

These declaration types have no Country element - it exists only under Buyer in Export.

Flat XML elementXSD fieldRequired
Counterparty/Identcr/rowenum/cridentREQ
Counterparty/IdentTypecr/rowenum/cridenttypeREQ
Counterparty/Namecr/rowenum/crnameREQ
Counterparty/TIdentcr/rowenum/tidentopt
Counterparty/TIdentTypecr/rowenum/tidenttypeopt
Counterparty/TNamecr/rowenum/tnameopt
Address/LocalAddressaddress/rowenum/receivedaddress/localaddressREQ
Address/Streetaddress/rowenum/receivedaddress/streetopt
Address/Numberaddress/rowenum/receivedaddress/numbopt
Address/Ekatteaddress/rowenum/receivedaddress/ekatteREQ - postal code
Address/ReceivedDateaddress/rowenum/receiveddateREQ
Address/ReceivedTimeaddress/rowenum/receivedtimeopt

3. Buyers (Export only)

Flat XML elementXSD fieldRequired
Buyer/Identcr/rowenum/cridentREQ
Buyer/IdentTypecr/rowenum/cridenttypeREQ
Buyer/Namecr/rowenum/crnameREQ
Buyer/TIdentcr/rowenum/tidentopt
Buyer/TIdentTypecr/rowenum/tidenttypeopt
Buyer/TNamecr/rowenum/tnameopt
Buyer/Countrycr/rowenum/countryREQ - 2-letter ISO code (DE, not Germany)

4. Goods (all types)

Flat XML elementXSD fieldRequired
Good/Codegoods/rowenum/codeREQ
Good/QuantityTypegoods/rowenum/quantitytypeopt - see below
Good/QuantityNetgoods/rowenum/quantitynetREQ
Good/QuantityGrossgoods/rowenum/quantitygrossopt - omitted when 0
Good/Pricegoods/rowenum/priceREQ
Good/Purposegoods/rowenum/purposeREQ
Good/PurposeOthergoods/rowenum/purposeotheropt - only with purpose 06

Quantity type

In the flat XMLSubmitted as
kgкг
m2м2
pcsброя
emptyкг

Any other value is passed through unchanged and will fail validation.

Purpose codes by type

CodeDescriptionImportExportInternalThirdCountry
01DeliveryYESYESYESYES
02ComplaintYESYESYES-
03DonationYESYESYES-
04ProcessingYESYESYES-
05Storage until demandYESYES--
06OtherYESYESYESYES
07Transit with transshipmentYESYES-YES

5. Identifier types

Main identifier (recipient/shipper)

CodeType
1Bulstat
2PIN
3FPN/PN
5NRA Service Number

Person identifier (carrier/organizer/transfer carrier as person)

CodeType
2PIN
3FPN/PN
5NRA Service Number
6Other

Firm identifier (carrier/organizer/transfer carrier as firm, counterparty, buyer)

CodeType
1Bulstat
5NRA Service Number
6Other
9VIN

6. Annul (OperationType 11) - separate format

Flat XML elementXSD fieldRequired
Identpart1/identREQ
IdentTypepart1/identtypeREQ
UINpart1/uinREQ - read from the root, not from the Header
IsCorrectpart1/iscorrectauto - always sent as true

7. Confirm (OperationType 12) - separate format

Flat XML elementXSD fieldRequired
Identpart1/identREQ
IdentTypepart1/identtypeREQ
IsReceivedpart1/isreceivedopt
UinReceivedpart1/uinreceivedopt
IsSentpart1/issentopt
UinSentpart1/uinsentopt
IsCorrectpart1/iscorrectauto - always sent as true