Sending outbound messages

There are three key steps in correctly sending and handling outbound messages:

  1. Creating the message.
    Messages are created by uploading business document data and providing the information necessary for message processing and delivery.
    Depending on the format of the document and your needs, we offer three approaches, as described in Creating messages.
  2. Adding more documents to the message.
    This step is optional.
    Users can add as many attachments as needed.
    The message processing does not start until all documents have been uploaded.
  3. Monitoring the message processing status.
    After the message has been delivered to the sender's outbox, its status is set to received.
    Follow the status through webhooks until the message is delivered or has failed, as described in Monitoring outbound message status.

Creating messages

The Messaging API supports three different ways of creating messages.
Each group of calls takes a different type of data, both in terms of document format and content.

The following section should help guide you through successfully creating new messages.

Create using metadata

The /transactions calls create a business document from the metadata structure in the correct syntax format based on the information about the receiver's ability to handle different document specifications.
These calls are the following:

You submit the metadata as the request body payload in JSON format.

If the receiver is not able to receive any of the formats that they support or any documents electronically at all, the document is delivered to the provided receiver's email address.

For more detailed instructions on how to prepare metadata correctly, see Metadata.
Full metadata examples in JSON format can be found in the description for each call.

Metadata

The following section should help you provide all the necessary information in the metadata.

Message handling

We rely on the information from the messageHandling section to make sure that the business document is delivered to your business partner.

  • receiverIdentifier: Must be set to the party identifier of the receiver.
    The format is {Type}:{Identifier}, where Type is the type of the party identifier, and Identifier is the identifier value.
    When you are sending an order, a remittance advice, or a quotation request, receiverIdentifier must match the identifier of the supplier.
    For invoices, credit notes, and quotations, this is the identifier of the customer.
    For billing responses, it corresponds to the identifier of the receiver, which is always the issuer of the invoice or the credit note (the seller).
  • fallbackEmailAddress: Must be a valid email address.
  • fallbackContactName: Optional but recommended.
Document references

For invoices and credit notes, the billingReferences section lets you specify the invoices and credit notes related to the document that you want to create.
The order based on which the billing document was made can be referenced in orderReference.

In the BISENUBL syntax, invoices must include one of these two elements:

  • orderReference: A reference to the relevant purchase order.
    Comprises the identifying number of the order and its issue date.
  • buyerReference: An internal identifier of the buyer.

The documentReferences section is reserved for other types of associated documents, such as despatch advice, contract, and more.
However, although supported in the BISENUBL document specification, keep in mind that this type of references might not be represented in other syntaxes.

In billing responses, documentReference refers to the relevant invoice or credit note in response to which the billing response has been sent.

In quotations, the quotationRequestReference section is used to indicate the relevant quotation request.

Supplier and customer details

The customer and supplier sections include information about the company name, its ISO identifier, postal address, and contact details.
The required elements depend on the document type.

  • identifier: The ISO identifier of the party.
    Always follows the same format: {Type}:{Identifier}, where Type is the type of the identifier and the identifier value is provided in Identifier.
  • vatNumber: The VAT number of the supplier is required in invoices and credit notes.
  • countryCode: Must comply with the ISO 3166 standard.
  • contact: Contact details are optional.
Address information

You can specify the address of the sender or the receiver in one of the two ways:

  1. Using structured address information.

    In this case, each address element is provided using a specific property: streetNameAndNumber, city, postalZone, countryCode.

    If needed, any additional information is supplied using the addressLine2 and addressLine3 properties, as shown in the example.

    {
        "address": {
            "streetNameAndNumber": "42nd Street 1",
            "city": "New York",
            "addressLine2": "PO Box 45",
            "postalZone": "10036",
            "countryCode": "US"
        }
    }
  2. Using unstructured address information.

    You can also set address information using streetNameAndNumber, addressLine2, addressLine3, and countryCode.
    In this case, addressLine2 and addressLine3 contain freely-structured text, as shown in the following example.

    {
        "address": {
            "streetNameAndNumber": "42nd Street 1",
            "addressLine2": "PO Box 45, 10036 New York",
            "countryCode": "US"
        }
    }

streetNameAndNumber and countryCode are required in both cases.

Line information
  • itemNo and name: These properties are used for identifying items.
    In orderLines, only one of the two properties is required, but you can also set both of these values.
    In invoiceLines and creditNoteLines only the name of the item (name) is required; the item number (itemNo) is optional.
    In quotationLines, if you are not using commodityClassification, you need to supply both properties.
  • taxCategoryType, taxableAmount, taxAmount, taxPercentage: In invoices and credit notes, all tax information is required.
    In orders, tax information can be omitted.
    However, if you provide one of these elements, you need to provide all four.
  • taxCategoryType: Must use one of the tax category values listed in the request body of each call, for example StandardRated, ZeroRated or ReverseCharged.
    See POST /transactions/submit-invoice for the full list.
  • quantity: Decimal number, for example 1.5.
  • unitOfMeasure: In unitOfMeasure, the unit property must use one these values: One, Piece, Kilogram, Rec20, Rec21, Month, Package, Year, Day, Hour, Kilometre, Metre, Litre, SquareMetre, CubicMetre, Tonne, KiloWattHour.
    If unit is set to Rec20 or Rec21, you need to set the code property too.
    For more information about accepted values, see Unit of measure.
  • unitPriceAmount, taxableAmount, taxAmount: Decimal numbers, for example 9500.50.
  • taxPercentage: Decimal number, for example 24 or 5.5.
    Do not add a percent sign.
  • discountValue: Requires a number provided as a string.
    To set a percentage discount, the numeric value must include a percent sign.
    To set a fixed discount amount, provide only a numeric value.
  • prepaidAmount: Decimal number, optional.
  • payableAmount: Decimal number, optional.
    If provided, the value must be correctly stated, otherwise an error is returned that indicates the expected amount.
    If the value is not provided, it is calculated based on the line information.
  • currencyCode: Must adhere to the ISO 4217 standard.
    If that is not the case, a document validation error occurs.

In billing responses, the following properties need to use specific values:

  • status: Refers to the processing status of the business document.
    These are the possible values: MessageAcknowledgement, Accepted, Rejected, InProcess, UnderQuery, ConditionallyAccepted, Paid, ResponseExpected.
    To learn more, see Billing response elements.
  • reasons: Supplies additional information about the document status by defining the issues reported.
    In each entry, reason must have one of these values: NoIssue, ReferencesIncorrect, LegalInformationIncorrect, ReceiverUnknown, ItemQualityInsufficient, DeliveryIssues, PricesIncorrect, QuantityIncorrect, ItemsIncorrect, PaymentTermsIncorrect, NotRecognized, FinanceIncorrect, Other.
    To find out more, see Billing response elements.
  • actions: Indicates what the receiver needs to do to correct the issue reported.
    In each entry, action must have one of these values: NoActionRequired, ProvideInformation, IssueNewInvoice, CreditFully, CreditPartially, CreditTheAmount, Other.
    For more information, go to Billing response elements.

In quotation requests, different parameters can be mandatory depending on whether the customer creates a quotation request based on the supplier's catalog or not.
To learn more, go to Quotation request: Use cases.

When a quotation is created based on a quotation request that was delivered through the application, the quotation needs to reference that quotation request.
For more information, see Quotation: Use cases.

Example: a complete invoice

The following request body for POST /transactions/submit-invoice contains the required elements and two invoice lines.
The second line has no item number and a decimal quantity.
payableAmount is left out, so it is calculated from the lines.

{
    "messageHandling": {
        "receiverIdentifier": "0196:5504030000",
        "fallbackEmailAddress": "[email protected]",
        "fallbackContactName": "Anna Jónsdóttir"
    },
    "invoice": {
        "invoiceNo": "INV-2026-0123",
        "issueDate": "2026-10-05T00:00:00Z",
        "dueDate": "2026-10-20T00:00:00Z",
        "currencyCode": "ISK",
        "buyerReference": "PO-4711",
        "supplier": {
            "name": "Example Supplier ehf.",
            "identifier": "0196:6511230889",
            "vatNumber": "IS123456",
            "address": {
                "streetNameAndNumber": "Main Street 326",
                "city": "Reykjavík",
                "postalZone": "101",
                "countryCode": "IS"
            },
            "contact": {
                "name": "Jóhann Jónsson",
                "electronicMail": "[email protected]"
            }
        },
        "customer": {
            "name": "Example Buyer hf.",
            "identifier": "0196:5504030000",
            "address": {
                "streetNameAndNumber": "East Street 94",
                "city": "Reykjavík",
                "postalZone": "108",
                "countryCode": "IS"
            }
        },
        "invoiceLines": [
            {
                "itemNo": "T302",
                "name": "Adjustable height standing desk",
                "quantity": 2,
                "unitOfMeasure": {
                    "unit": "One"
                },
                "unitPriceAmount": 49900.00,
                "taxCategoryType": "StandardRated",
                "taxableAmount": 99800.00,
                "taxAmount": 23952.00,
                "taxPercentage": 24
            },
            {
                "name": "Assembly service",
                "quantity": 1.5,
                "unitOfMeasure": {
                    "unit": "Hour"
                },
                "unitPriceAmount": 9500.00,
                "taxCategoryType": "StandardRated",
                "taxableAmount": 14250.00,
                "taxAmount": 3420.00,
                "taxPercentage": 24
            }
        ]
    }
}

Create as a transaction

The POST /messages/create-business-transaction call takes a business document in raw format and requires that you check the receiving capabilities of your business partner before making the request.
The document must be an XML document formatted according to a business document specification.

To check which document syntax the receiver understands, use the GET /parties/:pid/transactions call.
This retrieves a list of all business transactions that a participant supports for a specific business transaction type (for example, SubmitInvoice), such as this one:

[
    {
        "uniqueId": "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0",
        "profileId": "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0",
        "customizationId": "urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0",
        "transactionKeyName": "BISENUBL-3.0 SubmitInvoice",
        "profileKeyName": "BISENUBL-3.0",
        "documentIdentifier": "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0::2.1",
        "willBeTransformed": false
    },
    {
        "uniqueId": "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0",
        "profileId": "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0",
        "customizationId": "urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0",
        "transactionKeyName": "BISENCII-3.0 SubmitInvoice",
        "profileKeyName": "BISENCII-3.0",
        "documentIdentifier": "urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100::CrossIndustryInvoice##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0::D16B",
        "willBeTransformed": false
    },
    {
        "uniqueId": "urn:www.cenbii.eu:profile:bii05:ver1.0##urn:www.cenbii.eu:transaction:biicoretrdm010:ver1.0",
        "profileId": "urn:www.cenbii.eu:profile:bii05:ver1.0",
        "customizationId": "urn:www.cenbii.eu:transaction:biicoretrdm010:ver1.0",
        "transactionKeyName": "BII05-1.0 SubmitInvoice",
        "profileKeyName": "BII05-1.0",
        "documentIdentifier": "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##urn:www.cenbii.eu:transaction:biicoretrdm010:ver1.0::2.0",
        "willBeTransformed": true
    }
]

To successfully execute the POST /messages/create-business-transaction call, you need a valid XML document that fulfills the syntactic and semantic requirements of the corresponding business profile.
In other words, the document must be correctly formatted and contain all the required elements, and the information provided must comply with the predefined norms.

Uploading the document

Send the XML file as the raw request body with the Content-Type header set to application/octet-stream.
If you send the file as a Base64 string instead, use application/base64.
The message details are query parameters: messageId (a GUID that you create), transactionGroupIdentifier (for example SubmitInvoice) and more.

curl -X POST "https://mapi-sandbox.unimaze.com/api/v1/messages/create-business-transaction?messageId=3f2c9a52-7b1e-4c55-9a40-1d8e6b0f2a17&transactionGroupIdentifier=SubmitInvoice&more=false" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @invoice.xml

The call returns 201 Created.

Create as a generic message

If you need to send a different kind of document, such as an EDIFACT (text/plain) document, use the POST /messages/create-message call.

The documents sent this way do not undergo validation.
This lets you send images or business documents that do not follow a strict document structure.

However, the sender and the receiver must agree on the message envelope parameters to be able to exchange the document.

These parameters, such as service and action, contain information about how the document needs to be processed.

Upload the document the same way as in Uploading the document: the file is the raw request body (application/octet-stream or application/base64), and the message and document details are query parameters.
The contentType query parameter states the document's own type, for example text/plain for an EDIFACT document.

Adding documents

Messages contain at least one document, which is called core processing document.
Submitting additional documents is possible after the message core document has been added.
This is done using the POST /messages/:mid/documents call.
The file is the raw request body (application/octet-stream or application/base64).
The query parameters name and contentType name the document and state its own type, for example application/pdf.

Controlling whether additional documents can be added or not is achieved through the more parameter.
The parameter is used in the initial call when creating the message and in subsequent calls when adding documents to the same message.

If the value of the parameter is set to true, you can add more attachments to the message.
After the value of the parameter is set to false, no new documents can be added.

This also affects message processing because the processing does not start until the value of the parameter has been set to false.

Monitoring outbound message status

Messages that have been submitted to the server are processed asynchronously.
After a message is created on the server, its message status is one of the following:

  • notset: The message is waiting for more documents to be added.
  • received: The message is ready for processing.
  • pendingdelivery: The message is ready to be sent: it has been validated and is in the queue for sending. You get a deliveryNotified event, and the Acknowledgement (AB) message level response if your participant is set up for it. See Outbound: ready to be sent.
  • retrying: A delivery attempt failed, and the message will be tried again. The messageStatusChanged event for it carries the failure in errorMessage, for example that no endpoint was found for the receiver.

When the processing has been completed, the message status is set to one of these two statuses:

  • delivered: The message has been successfully processed and delivered.
  • failed: The message validation, processing or delivery failed. A message that fails validation becomes failed straight away: fix the document and send it as a new message.

delivered and failed are final. In rare cases manual handling delays the final state, see Delivery guarantees.

Track the outcome through webhooks: Unimaze sends your endpoint a messageStatusChanged event each time the message status changes. The event carries the former and new status, so you don't need to call MAPI to apply it. If the message is also reported to a tax authority, for example in Croatia or Slovakia, a taxReportingStatusChanged event tells you the outcome of the reporting. See Status events.

To check the status at any time, for example if you may have missed events, use the GET /messages/{messageId} call. Checking it repeatedly on a schedule (polling) is the legacy approach, see Polling (legacy).

The call returns a JSON object that contains information about the message and the business documents included in the message.
The message status information is stored as the status property.

{
    "uniqueId": "99bf2d71-01c4-4fa2-9f36-87df8d6405b0",
    "timeReceived": "2026-10-02T13:07:58.127",
    "timeDelivered": "2026-10-02T13:08:54.777",
    "documentNo": "INV-2026-0123",
    "status": "delivered",
    "transfer": "outbound",
    "validationStatus": "approved",
    "service": "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0",
    "action": "SubmitInvoice",
    "conversation": "261002:603727:0196:6511230889",
    "referenceInformation": "",
    "originParty": {
        "identifier": "0196:6511230889",
        "name": "Example Supplier ehf."
    },
    "destinationParty": {
        "identifier": "0196:5504030000",
        "name": "Example Buyer hf."
    },
    "documents": [
      {
        "index": 0,
        "name": "Invoice",
        "contentType": "text/xml",
        "encoding": "utf-8",
        "referenceId": "99bf2d7101c44fa29f3687df8d6405b0:0196:6511230889:0:6ndhnotgb5",
        "namespace": "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2",
        "attachmentType": "Core",
        "isTransformed": false
      }
    ]
}

For more details regarding the message delivery and services processing, use the GET /messages/:mid/status call.
The call returns information on when the message was received onto the server, when it was delivered(if it has been delivered),
different possible statuses of the message and an array of JSON objects that each includes information about the events that occurred during the message processing.

{
  "receivedTimestamp": "2026-10-02T11:50:47.277Z",
  "deliveredTimestamp": null,
  "messageStatus": "InProcess",
  "internalMessageStatus": "PendingDelivery",
  "validationStatus": "Valid",
  "traces": [
    {
      "timestamp": "2026-10-02T11:50:46.617Z",
      "sourceIp": "203.0.113.25",
      "sourceUser": "profile1",
      "sourcePartyName": "Example Supplier ehf.",
      "traceTypeKeyName": "CreateClosed",
      "traceMessage": "Message created (RemittanceAdvice, text/xml) - ready for processing",
      "traceDescription": ""
    },
    {
      "timestamp": "2026-10-02T11:50:47.323Z",
      "sourceIp": "",
      "sourceUser": "",
      "sourcePartyName": null,
      "traceTypeKeyName": "MovedToReceiverInbox",
      "traceMessage": "Message transferred to inbox of receiving party",
      "traceDescription": "Document moved to receiver's inbox"
    }
  ]
}

Did this page help you?