Malaysia v2: Peppol Unify API
Validate and send B2B and B2C invoices, credit notes and self-billed documents over Peppol with the Malaysia Unify API v2 (legacy): endpoint, headers, request fields and responses.
The Unify API validates and processes business-to-business (B2B) and business-to-consumer (B2C) invoices sent over Peppol. It supports invoices, credit notes and self-billed documents, and checks them against the tax and invoicing rules.
Document types
| Code | Document | Value to send |
|---|---|---|
| 01 | Invoice | INV |
| 02 | Credit Note | CRD |
| 11 | Self-billed Invoice | SLF_INV |
| 12 | Self-billed Credit Note | SLF_CRD |
Endpoint
POST https://malaysia-sandbox.complyance.io/unifyThis endpoint validates and processes invoice data, including seller and buyer details, line items and tax information.
Headers
| Header | Description |
|---|---|
x-api-key | Your API key. |
invoiceMethod | The invoice method. Use peppol. |
Content-Type | Set as application/json. |
Code examples
These examples show the URL and headers. Send the request body as JSON.
curl --location 'https://malaysia.complyance.io/dev/unify' \
--header 'x-api-key: your-api-key' \
--header 'Content-Type: application/json'const headers = {
'x-api-key': 'your-api-key',
'Content-Type': 'application/json'
};
fetch('https://malaysia.complyance.io/dev/unify', {
method: 'POST',
headers: headers
})
.then(function(response) {
return response.json();
}).then(function(body) {
console.log(body);
});require 'rest-client'
headers = {
'x-api-key' => 'your-api-key',
'Content-Type' => 'application/json'
}
response = RestClient.post 'https://malaysia.complyance.io/dev/unify', {}, headers
puts response.bodyimport requests
headers = {
'x-api-key': 'your-api-key',
'Content-Type': 'application/json'
}
response = requests.post('https://malaysia.complyance.io/dev/unify', headers=headers)
print(response.json())<?php
$headers = [
'x-api-key' => 'your-api-key',
'Content-Type' => 'application/json'
];
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://malaysia.complyance.io/dev/unify', [
'headers' => $headers
]);
echo $response->getBody()->getContents();
?>URL url = new URL("https://malaysia.complyance.io/dev/unify");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("x-api-key", "your-api-key");
con.setRequestProperty("Content-Type", "application/json");
int responseCode = con.getResponseCode();
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());package main
import (
"net/http"
)
func main() {
headers := map[string][]string{
"x-api-key": []string{"your-api-key"},
"Content-Type": []string{"application/json"},
}
req, err := http.NewRequest("POST", "https://malaysia.complyance.io/dev/unify", nil)
if err != nil {
// Handle error
}
for key, values := range headers {
for _, value := range values {
req.Header.Add(key, value)
}
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
// Handle error
}
defer resp.Body.Close()
}Request body
{
"invoiceDataList": [
{
"documentType": "INV",
"documentId": "Peppol EINV-0222",
"originalEInvoiceReferenceNumber": "",
"originalEInvoiceReferenceUUID": "",
"documentIssueDate": "2025-06-17",
"documentIssueTime": "02:30:00Z",
"currency": "MYR",
"currencyExchangeRate": "1",
"invoiceFrequency": "MONTHLY",
"invoiceStartDate": "2024-10-01",
"invoiceEndDate": "2024-10-23",
"supplierId": "",
"supplierParticipantId": "0230:01998877665544",
"sellerTinNumber": "C20000000000",
"sellerRegistrationIdType": "BRN",
"sellerRegistrationId": "202001234567",
"supplierSstRegistrationNumber": "",
"supplierTourismTaxRegistrationNumber": "",
"buyerId": "",
"buyerParticipantId": "0230:0245622",
"buyerTinNumber": "C30000000000",
"buyerRegistrationIdType": "BRN",
"buyerRegistrationId": "201901234568",
"buyerSstRegistrationNumber": "",
"isShippingAndBuyerAddressSame": true,
"shippingRecipientName": "Example Logistics Sdn Bhd",
"shippingRecipientTin": "C40000000000",
"shippingRecipientRegistrationType": "BRN",
"shippingRecipientRegistrationNumber": "234234234",
"totalExcludingTax": "2000",
"totalTaxableAmount": "2000",
"taxTotal": "0",
"documentTotal": "2000",
"invoiceAmountExemptedFromTax": "0",
"invoiceTaxExemptionReason": "Goods acquired with SST exemption under Sales Tax Act 2018. Reference No: (C01-2345-67890123)",
"invoiceAdditionalDiscountAmount": "0",
"invoiceAdditionalChargeAmount": "0",
"totalPayableAmount": "2000",
"roundingAmount": "0",
"paymentMeans": "1",
"supplierBankAccountNumber": "1234567890123",
"sellerAddress": {
"addressLine1": "Lot 66",
"addressLine2": "Bangunan Merdeka",
"addressLine3": "Persiaran Jaya",
"postalCode": "50480",
"city": "Kuala Lumpur",
"state": "14",
"country": "MYS"
},
"buyerAddress": {
"addressLine1": "Lot 66",
"addressLine2": "Bangunan Merdeka",
"addressLine3": "Persiaran Jaya",
"postalCode": "50480",
"city": "Kuala Lumpur",
"state": "14",
"country": "MYS"
},
"shippingRecipientAddress": {
"addressLine1": "Lot 66",
"addressLine2": "Bangunan Merdeka",
"addressLine3": "Persiaran Jaya",
"postalCode": "50480",
"city": "Kuala Lumpur",
"state": "14",
"country": "MYS"
},
"supplierDetails": {
"organizationName": "Acme Trading Sdn Bhd",
"email": "finance@acme.example",
"industryCode": "01111",
"industryDescription": "Growing of maize",
"phoneNumber": "+60-123456789"
},
"buyerDetails": {
"organizationName": "Example Buyer Sdn Bhd",
"email": "accounts@buyer.example",
"phoneNumber": "+60-123456789"
},
"documentLineItems": [
{
"lineItemId": "1",
"commodityClassificationCode": "1",
"description": "Laptop peripherals",
"unitPrice": "200",
"quantity": "10",
"lineItemSubtotal": "2000",
"discountPercent": "0",
"discountAmount": "0",
"chargePercent": "0",
"chargeAmount": "0",
"lineTotalExcludingTax": "2000",
"taxType": "6",
"taxPercentage": "0",
"totalTax": "0",
"taxExemptionReason": "Goods acquired with SST exemption under Sales Tax Act 2018. Reference No: (C01-2345-67890123)",
"amountExemptedFromTax": "0",
"lineItemTotal": "2000"
}
],
"invoiceMethod": "peppol"
}
]
}Request fields
Invoice details
| ObjectName | Field Name | Conditionality | Informatics | Field Max Length | Sample Value |
|---|---|---|---|---|---|
| documentType | e-Invoice Type Code | Mandatory | Identifies the document type (e.g., INV, CRD,SLF, SLF_CRD.) | 2 | INV |
| documentId | e-Invoice Code / Number | Mandatory | Document reference number used by Supplier for internal tracking purpose | 50 | INV12345 |
| documentIssueDate | e-Invoice Date | Mandatory | Date of issuance of the e-Invoice (Note that the date must be the current date) | 10 | 2017-11-26 |
| documentIssueTime | e-Invoice Time | Mandatory | Time of issuance of the e-Invoice (Note that the time must be the current time) | 12 | 15:30:00.0Z |
| documentCurrencyCode | Invoice Currency Code | Mandatory | Specific currency that is used to represent the monetary value stated in the e-Invoice | 3 | MYR |
| invoiceFrequency | Frequency of Billing | Optional | Frequency of the invoice (e.g., Daily, Weekly, Monthly, Bimonthly, Quarterly, Half-yearly, Yearly, Others) | 50 | Monthly |
| invoiceStartDate | Billing Period Start Date | Optional | Interval of the transaction | 10 | 2017-11-26 |
| invoiceEndDate | Billing Period End Date | Optional | End date of the transaction interval | 10 | 2017-11-30 |
Supplier details
| ObjectName | Field Name | Conditionality | Informatics | Field Max Length | Sample Value |
|---|---|---|---|---|---|
| supplierId | Supplier ID | Optional | Identification Number of a Specific Supplier in an Invoice | 20 | 1 |
| supplierSstRegistrationNumber | supplierSstRegistrationNumber | Mandatory | Sales tax / service tax (SST) registration number of the Supplier (input “NA” if not registered for SST) | A01-2345-67891012 | |
| supplierDetails.organizationName | Supplier’s Name | Mandatory | Name of business or individual who will be the issuer of the e-Invoice in a commercial transaction | 300 | Acme Trading Sdn Bhd |
| sellerTinNumber | Supplier’s TIN | Mandatory | Supplier’s (i.e., issuer’s) TIN assigned by IRBM | 14 | C20000000000 |
| sellerRegistrationIdType | Supplier’s Registration scheme ID | Mandatory | Business registration number / MyKad / Passport number depending on entity | 12 | BRN |
| sellerRegistrationId | Supplier’s Registration / Identification Number / Passport Number | Mandatory | Business registration number / MyKad / Passport number depending on entity | 20 | BRN: 202001234567 |
| supplierDetails.email | Supplier’s e-mail | Optional | E-mail address of the Supplier (Provide “NA” if unavailable) | 320 | finance@acme.example |
| supplierDetails.industryCode | Supplier’s MSIC Code | Mandatory | 5-digit numeric code representing the Supplier’s business nature and activity | 5 | 1111 |
| supplierDetails.industryDescription | Supplier’s Business Activity Description | Mandatory | Description of the Supplier’s business activity | 300 | Growing of maize |
| supplierDetails.phoneNumber | Supplier’s Contact Number | Mandatory | The telephone number of the Supplier | 15 | -123456729 |
Supplier address
| ObjectName | Field Name | Conditionality | Informatics | Field Max Length | Sample Value |
|---|---|---|---|---|---|
| sellerAddress.addressLine1 | Address Line 1 | Mandatory | The main address line in an address structure. Input “NA” if unavailable | 150 | Lot 66 |
| sellerAddress.addressLine2 | Address Line 2 | Optional | An additional address line for further details | 150 | Bangunan Merdeka |
| sellerAddress.addressLine3 | Address Line 3 | Optional | An additional address line for further details | 150 | Persiaran Jaya |
| sellerAddress.postalCode | Postal Zone | Optional | The identifier for a postal zone | 50 | 50480 |
| sellerAddress.city | City Name | Mandatory | The common name of the city | 50 | Kuala Lumpur |
| sellerAddress.state | State | Mandatory | The state of a country | 50 | 14 |
| sellerAddress.country | Country | Mandatory | A code identifying the country | 3 | MYS |
Buyer details
| ObjectName | Field Name | Conditionality | Informatics | Field Max Length | Sample Value |
|---|---|---|---|---|---|
| buyerId | Buyer ID | Optional | Identification Number of a Specific Buyer in an Invoice | 20 | 1 |
| buyerDetails.organizationName | Buyer’s Name | Mandatory | Name of the recipient of the e-Invoice in a commercial transaction | 300 | Example Buyer Sdn Bhd |
| buyerTinNumber | Buyer’s TIN | Mandatory | Buyer’s (i.e., issuer’s) TIN assigned by IRBM | 14 | C30000000000 |
| buyerRegistrationIdType | Buyer’s Registration / Identification Number / Passport Scheme ID | Mandatory | Business registration number / MyKad / Passport number depending on entity | 12 | BRN |
| buyerRegistrationId | Buyer’s Registration / Identification Number / Passport Number | Optional | Business registration number / MyKad / Passport number depending on entity | 20 | BRN: 202001234567 |
| buyerDetails.email | Buyer’s e-mail | Optional | E-mail address of the Buyer (Provide “NA” if unavailable) | 320 | accounts@buyer.example |
| buyerDetails.phoneNumber | Buyer’s Contact Number | Mandatory | The telephone number of the Buyer | 15 | -123456729 |
Buyer address
| ObjectName | Field Name | Conditionality | Informatics | Field Max Length | Sample Value |
|---|---|---|---|---|---|
| buyerAddress.addressLine1 | Address Line 1 | Mandatory | The main address line in an address structure. Input “NA” if unavailable | 150 | Lot 66 |
| buyerAddress.addressLine2 | Address Line 2 | Optional | An additional address line for further details | 150 | Bangunan Merdeka |
| buyerAddress.addressLine3 | Address Line 3 | Optional | An additional address line for further details | 150 | Persiaran Jaya |
| buyerAddress.postalCode | Postal Zone | Optional | The identifier for a postal zone | 50 | 50480 |
| buyerAddress.city | City Name | Mandatory | The common name of the city | 50 | Kuala Lumpur |
| buyerAddress.state | State | Mandatory | The state of a country | 50 | 14 |
| buyerAddress.country | Country | Mandatory | A code identifying the country | 3 | MYS |
Line items
| ObjectName | Field Name | Conditionality | Informatics | Field Max Length | Sample Value |
|---|---|---|---|---|---|
| documentLineItems.lineItemId | Line ID | Mandatory | Identification of a Specific Line in an Invoice | 20 | 1 |
| documentLineItems.commodityClassificationCode | Classification | Mandatory | Category of products or services being billed | 3 | 1 |
| documentLineItems.description | Description of Product or Service | Mandatory | Details of products or services being billed | 300 | Laptop Peripherals |
| documentLineItems.unitPrice | Unit Price | Mandatory | Price assigned to a single unit of a product or service | 17 | |
| documentLineItems.quantity | Quantity | Optional | Number of units of a product or service | 1 | |
| documentLineItems.lineItemSubtotal | Subtotal | Mandatory | Amount of each individual item, excluding any taxes or charges | 100 | |
| documentLineItems.lineTotalExcludingTax | Total Excluding Tax | Mandatory | Sum of amount payable excluding any applicable taxes | 1436.5 | |
| documentLineItems.taxType | Tax Type | Mandatory | Type of taxes that will be applicable | 2 | 1 |
| documentLineItems.taxPercentage | Tax Rate | Mandatory | The appropriate tax rate that is applicable | 6 | |
| documentLineItems.totalTax | Tax Amount | Mandatory | The amount of tax payable | 292.2 | |
| documentLineItems.taxCode | Details of Tax Exemption | Optional | Description of tax exemption applicable | 300 | SST exemption |
| documentLineItems.taxExemptionReason | Amount Exempted from Tax | Conditional Mandatory | Total amount of tax exempted for SST purposes | 1460.5 | |
| documentLineItems.chargeAmount | Charge Amount | Optional | Charge associated with the product or service imposed after tax | 1000 | |
| documentLineItems.discountAmount | Discount Amount | Optional | Amount deducted from the original price of a product | 1000 |
Peppol data
| ObjectName | Field Name | Conditionality | Informatics | Field Max Length | Sample Value |
|---|---|---|---|---|---|
| supplierId | Peppol Id of the supplier | Conditional Mandatory | Supplier or Seller’s participant id in the Peppol network | 0230:05TESTID | |
| buyerId | Peppol Id of the buyer | Conditional Mandatory | Buyer’s participant id in the Peppol network | 0230:05TESTID | |
| supplierTradingName | Registered business name | Conditional Mandatory | Supplier business name registered in SSM | Company Name Sdn. Bhd. | |
| sellerPointOfContact | Seller name | Conditional Mandatory | Seller point of contact name | John | |
| buyerPointOfContact | Buyer Name | Conditional Mandatory | Buyer point of contact name | John | |
| shippingRecipientLocationId | Shipping location ID | Conditional Mandatory | An identifier for the location at which the goods and services are delivered | ||
| buyerAccountingLedgerReference | Ledger reference | Conditional Mandatory | Buyer Accounting or Ledger Reference | ||
| deliveryDate | Delivery Date | Conditional Mandatory | The date on which the supply of goods or services was made or completed |
Summary
| ObjectName | Field Name | Conditionality | Informatics | Field Max Length | Sample Value |
|---|---|---|---|---|---|
| invoiceAdditionalChargeAmount | Charge Amount | Optional | Additional Discount at Invoice Level | 1000 | |
| invoiceAdditionalDiscountAmount | Discount Amount | Optional | Additional Charges at Invoice Level | 1000 | |
| totalExcludingTax | Total Excluding Tax | Mandatory | Sum of amount payable excluding any applicable taxes | 1436.5 | |
| usedTaxTypes.taxType | Tax Type | Mandatory | Type of taxes that will be applicable (e.g., sales tax, service tax, etc.) | 2 | 1 |
| usedTaxTypes.taxableAmount | Total Taxable Amount Per Tax Type | Optional | Sum of amount chargeable for each tax type | 1460.5 | |
| usedTaxTypes.taxAmount | Total Tax Amount Per Tax Type | Mandatory | Sum of amount chargeable for each tax type | 1460.5 | |
| usedTaxTypes.taxExemptionReason | Details of Tax Exemption | Optional | Description of tax exemption applicable at invoice level | SST exemption | |
| taxTotal | Total Tax Amount | Mandatory | Total amount of tax payable | 1234 | |
| documentTotal | Invoice Total Amount Including Tax | Mandatory | Sum of amount payable inclusive of total taxes chargeable | 1436.5 | |
| totalPayableAmount | Total Payable Amount | Mandatory | Sum of amount payable excluding any amount paid in advance and rounding | 1436.5 |
Response
Success response
When the submission succeeds, the response lists the accepted documents. The xmlEncoded value is the Base64-encoded XML of the document, shortened here.
{
"submissionUid": "KMNPQRSTVW0123456789ABCD10",
"acceptedDocuments": [
{
"documentUlid": "01HZEXAMPLE000000000000001",
"uuid": "ABCDEFGHJK0123456789ABCD10",
"invoiceCodeNumber": "ML-ST-2424",
"xmlEncoded": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/Pgo…"
}
],
"rejectedDocuments": [],
"timestamp": "2023-08-14T08:15:30Z"
}| Status code | Description |
|---|---|
200 | Success: the request was processed. |
202 | Accepted: the request was accepted and is still processing. |
Error response
When the submission fails, the response lists the rejected documents with an error code and message. See Peppol errors for the messages you can receive.
{
"submissionUid": "KMNPQRSTVW0123456789ABCD10",
"rejectedDocuments": [
{
"documentUlid": "01HZEXAMPLE000000000000002",
"uuid": "ABCDEFGHJK0123456789ABCD10",
"status": "Rejected",
"errorCode": "ERR123",
"errorMessage": "Invalid Tax ID format"
}
],
"acceptedDocuments": [],
"timestamp": "2023-08-14T08:15:30Z"
}| Error code | Description |
|---|---|
400 | Bad Request: invalid data in the request. |
401 | Unauthorized: invalid or missing API key. |
500 | Internal Server Error: the server encountered an error. |
Notes
- Check that your document types are accepted in your jurisdiction.
- Check that the invoice format meets the standards, to avoid delays.