Unify
Overview
The Unify API allows you to validate and process Business-to-Business (B2B) invoices. The API supports various document types such as invoices, credit notes, and debit notes and self-billed invoices ensures compliance with relevant tax and invoicing regulations.
e-Invoice Types
Code | Examples | Acceptable Values |
---|---|---|
01 | Invoice | INV |
02 | Credit Note | CRD |
03 | Debit Note | DBT |
04 | Refund Note | RFD |
11 | Self-billed Invoice | SLF_INV |
12 | Self-billed Credit Note | SLF_CRD |
13 | Self-billed Debit Note | SLF_DBT |
14 | Self-billed Refund Note | SLF_REF |
API URLs
Property | Value |
---|---|
Sandbox | https://malaysia-sandbox.complyance.io |
Production | https://malaysia-prod.complyance.io/ |
Endpoint | /unify |
Method | POST |
This endpoint validates and processes invoice data, including seller and buyer details, line items, and tax information.
Headers
Header | Type | Description | Example | Conditionality |
---|---|---|---|---|
x-api-key | string | Your API key | 1aN3AQ8ZsggJ0UABAHXVB | Mandatory |
invoiceMethod | string | Specify the invoice method (e.g., non-peppol , peppol ) | non-peppol | optional |
Content-Type | string | Set as application/json | application/json | optional |
- Shell
- Javascript
- Ruby
- Python
- PHP
- Java
- Go
curl --location 'https://malaysia-prod.complyance.io/unify' \
--header 'x-api-key: k4PW_J0s8DtBSdvYnadXn' \
--header 'Content-Type: application/json'
const headers = {
'x-api-key': 'k4PW_J0s8DtBSdvYnadXn',
'Content-Type': 'application/json'
};
fetch('https://malaysia-prod.complyance.io/unify', {
method: 'POST',
headers: headers
})
.then(function(response) {
return response.json();
}).then(function(body) {
console.log(body);
});
require 'rest-client'
headers = {
'x-api-key' => 'k4PW_J0s8DtBSdvYnadXn',
'Content-Type' => 'application/json'
}
response = RestClient.post 'https://malaysia-prod.complyance.io/unify', {}, headers
puts response.body
import requests
headers = {
'x-api-key': 'k4PW_J0s8DtBSdvYnadXn',
'Content-Type': 'application/json'
}
response = requests.post('https://malaysia-prod.complyance.io/unify', headers=headers)
print(response.json())
<?php
$headers = [
'x-api-key' => 'k4PW_J0s8DtBSdvYnadXn',
'Content-Type' => 'application/json'
];
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://malaysia-prod.complyance.io/unify', [
'headers' => $headers
]);
echo $response->getBody()->getContents();
?>
URL url = new URL("https://malaysia-prod.complyance.io/unify");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("x-api-key", "k4PW_J0s8DtBSdvYnadXn");
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{"k4PW_J0s8DtBSdvYnadXn"},
"Content-Type": []string{"application/json"},
}
req, err := http.NewRequest("POST", "https://malaysia-prod.complyance.io/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()
}
Example Request:
{
"invoiceDataList": [
{
"documentType": "INV",
"documentId": "Invoice-01",
"originalEInvoiceReferenceNumber": "",
"documentIssueDate": "2025-01-06",
"documentIssueTime": "02:30:00Z",
"currency": "MYR",
"currencyExchangeRate": "1",
"supplierId": "1",
"sellerTinNumber": "C58794843040",
"sellerRegistrationIdType": "BRN",
"sellerRegistrationId": "198801006871",
"supplierSstRegistrationNumber": "A01-2345-67891012",
"supplierTourismTaxRegistrationNumber": "123-4567-89012345",
"buyerId": "1",
"buyerTinNumber": "C21540299050",
"buyerRegistrationIdType": "BRN",
"buyerRegistrationId": "200901037548",
"buyerSstRegistrationNumber": "234234234",
"isShippingAndBuyerAddressSame": false,
"shippingRecipientName": "Greenz Sdn. Bhd.",
"shippingRecipientTin": "C21540299050",
"shippingRecipientRegistrationType": "BRN",
"shippingRecipientRegistrationNumber": "200901037548",
"totalExcludingTax": "1000",
"taxTotal": "60",
"documentTotal": "1060",
"invoiceAmountExemptedFromTax": "0",
"invoiceTaxExemptionReason": "Goods acquired with SST exemption under Sales Tax Act 2018. Reference No: (C01-2345-67890123)",
"invoiceAdditionalDiscountAmount": "0",
"invoiceAdditionalChargeAmount": "0",
"totalPayableAmount": "1060",
"paymentMeans": "1",
"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": "Name of Supplier",
"email": "email@supplier.com",
"industryCode": "01111",
"industryDescription": "Growing of maize",
"phoneNumber": "+60-123456789"
},
"buyerDetails": {
"organizationName": "ABC company",
"email": "name@buyer.com",
"phoneNumber": "+60-123456789"
},
"documentLineItems": [
{
"lineItemId": "1",
"commodityClassificationCode": "1",
"description": "BOP JETTING SUB, SLEEVE, 8\", REV E, BJS-8000-002 (BJS-8000-002-E)",
"unitPrice": "100",
"quantity": "10",
"lineItemSubtotal": "1000",
"discountPercent": "0",
"discountAmount": "0",
"chargePercent": "0",
"chargeAmount": "0",
"lineTotalExcludingTax": "1000",
"taxType": "1",
"taxPercentage": "6",
"totalTax": "60",
"taxExemptionReason": "Goods acquired with SST exemption under Sales Tax Act 2018. Reference No: (C01-2345-67890123)",
"amountExemptedFromTax": "0",
"lineItemTotal": "1060"
}
]
}
]
}
Request Parameter Fields
Invoice Details
Invoice Data List
ObjectName | Field Name | Conditionality | Informatics | Field Max Length | Sample Value |
---|---|---|---|---|---|
invoiceDataList | documentType | Mandatory | Identify the document type (e.g., INV, CRD, DBT, RFD, SLF_INV, SLF_CRD, SLF_DBT, SLF_REF.) | 3 to 7 | |
invoiceDataList | documentId | Mandatory | Document reference number used by Supplier for internal tracking purpose | 50 | |
invoiceDataList | originalEInvoiceReferenceNumber | Mandatory where applicable | LHDNM Unique Identifier Number of the original invoice/document that is being affected/adjusted. | 26 | |
invoiceDataList | documentIssueDate | Mandatory | Date of issuance of the e-Invoice (Note that the date must be the current date) | 10 (format: yyyy-mm-dd) | |
invoiceDataList | documentIssueTime | Mandatory | Time of issuance of the e-Invoice (Note that the time must be the UTC time) | 15 (format: hh:mm:ss) | |
invoiceDataList | currency | Mandatory | Specific currency that is used to represent the monetary value stated in the e-Invoice | 3 | |
invoiceDataList | invoiceStartDate | Optional | Start date of the transaction interval | 10 (format: yyyy-mm-dd) | |
invoiceDataList | invoiceEndDate | Optional | End date of the transaction interval | 10 (format: yyyy-mm-dd) | |
invoiceDataList | invoiceFrequency | Optional | Frequency of the invoice (e.g., Daily, Weekly, Biweekly, Monthly, Bimonthly, Quarterly, Half-yearly, Yearly, Others / Not Applicable) | 50 | |
invoiceDataList | supplierId | Optional | Identification Number of a Specific Supplier in an Invoice | 20 | |
invoiceDataList | sellerTinNumber | Mandatory | Supplier’s TIN assigned by LHDNM | 14 | |
invoiceDataList | sellerRegistrationIdType | Mandatory | Supplier’s Registration / Identification Number / Passport Number | ||
invoiceDataList | sellerRegistrationId | Mandatory | For businesses: Business registration number. For Malaysian individual: MyKad / MyTentera identification number. For non-Malaysian individual: Passport number / MyPR / MyKAS identification number. Note: For MyPR and MyKAS to use NRIC scheme. | ||
invoiceDataList | supplierSstRegistrationNumber | Mandatory where applicable | SST registration number of the Supplier. This is not applicable to Supplier that are not SST-registered. The input of special characters is not allowed, except for dash (-) and semicolon (;). A maximum of two SST registration numbers is allowed, separated by a semicolon. Supplier to input “NA” if supplier is not registered for SST. | 35 | |
invoiceDataList | supplierTourismTaxRegistrationNumber | Mandatory where applicable | Tourism tax registration number of the Supplier. This is only applicable to tourism tax registrant, which may consist of hotel operators and online travel operators. The input of special characters is not allowed, except for dash (-). Supplier to input “NA” if supplier is not registered for tourism tax. | 17 | |
invoiceDataList | buyerId | Optional | Identification Number of a Specific Buyer in an Invoice | ||
invoiceDataList | buyerTinNumber | Mandatory | Buyer’s TIN assigned by LHDNM | 14 | |
invoiceDataList | buyerRegistrationIdType | Mandatory | Buyer’s Registration / Identification Number / Passport Number | ||
invoiceDataList | buyerSstRegistrationNumber | Mandatory | SST registration number of the Buyer. This is not applicable to Buyers that are not SST-registered. The input of special characters is not allowed, except for dash (-) and semicolon (;). A maximum of two SST registration numbers is allowed, separated by a semicolon. Supplier to input “NA” if buyer’s SST registration number is not available or not provided. | ||
invoiceDataList | isShippingAndBuyerAddressSame | Mandatory | Indicates whether the shipping and buyer address are the same | Boolean value | |
invoiceDataList | shippingRecipientName | Mandatory where applicable | Name of shipping recipient of the products included in the e-Invoice in a commercial transaction | 300 | |
invoiceDataList | shippingRecipientTin | Mandatory where applicable | TIN of the shipping recipient assigned by LHDNM | 14 | |
invoiceDataList | shippingRecipientRegistrationType | Mandatory where applicable | Supplier’s Registration / Identification Number / Passport Number | ||
invoiceDataList | shippingRecipientRegistrationNumber | Mandatory where applicable | SST registration number of the Buyer. This is not applicable to Buyers that are not SST-registered. The input of special characters is not allowed, except for dash (-) and semicolon (;). A maximum of two SST registration numbers is allowed, separated by a semicolon. Supplier to input “NA” if buyer’s SST registration number is not available or not provided. | ||
invoiceDataList | invoiceAdditionalDiscountAmount | Mandatory where applicable | Amount deducted from the original price of a product or service. Please add currencyID attribute to the XML element. | ||
invoiceDataList | invoiceAdditionalChargeAmount | Mandatory where applicable | Charge associated with the product or service (be it in the form of percentage (%) or prevailing specified rate) imposed before tax. Please add currencyID attribute to the XML element. | ||
invoiceDataList | totalExcludingTax | Mandatory | Sum of amount payable (inclusive of applicable discounts and charges), excluding any applicable taxes (e.g., sales tax, service tax). Please add currencyID attribute to the XML. | ||
invoiceDataList | taxTotal | Mandatory | Total amount of tax payable | ||
invoiceDataList | documentTotal | Mandatory | Invoice Total Amount Including Tax | ||
invoiceDataList | invoiceAmountExemptedFromTax | Mandatory where applicable | Total amount of tax exempted for sales tax or service tax purposes on the invoice level. | ||
invoiceDataList | invoiceTaxExemptionReason | Mandatory where applicable | Description of tax exemption applicable on the invoice level (e.g., Buyer’s sales tax exemption certificate number, special exemption as per gazette orders, etc.). The input is limited to the following special characters: period “.”, dash “-“, comma “,” and parenthesis “()”. | ||
invoiceDataList | totalPayableAmount | Mandatory | Sum of amount payable (inclusive of total taxes chargeable and any rounding adjustment) excluding any amount paid in advance. Please add currencyID attribute to the XML element. | ||
invoiceDataList | paymentMeans | Optional | Chosen mechanism through which funds are transferred from buyer to supplier (e.g., cash, cheque, bank transfer, credit card, debit card, e-Wallet/ Digital Wallet, etc.) | 2 |
Supplier Details
ObjectName | Field Name | Conditionality | Informatics | Field Max Length | Sample Value |
---|---|---|---|---|---|
supplierDetails | organizationName | Mandatory | Name of business or individual who will be the supplier providing the goods / services in a commercial transaction. | 300 | |
supplierDetails | Optional | E-mail address of the Supplier (Following the email standards (RFC 5321 and RFC 5322)). | 320 | ||
supplierDetails | industryCode | Mandatory | 5-digit numeric code that represents the Supplier’s business nature and activity | 5 | |
supplierDetails | industryDescription | Mandatory | Description of the Supplier’s business activity | 300 | |
supplierDetails | phoneNumber | Mandatory | The telephone number of the Supplier (e.g., office, mobile, fax) | 20 |
Seller's Address
ObjectName | Field Name | Conditionality | Informatics | Field Max Length | Sample Value |
---|---|---|---|---|---|
sellerAddress | addressLine1 | Mandatory | This is the main address line in an address structure that can be used to give the main address line information. A possible value for this field is “NA” and then all other address fields would not be provided except for the state field which would is mapped to the field. | 150 | |
sellerAddress | addressLine2 | Optional | An additional address line in an address that can be used to give further details supplementing the main line. | 150 | |
sellerAddress | addressLine3 | Optional | An additional address line in an address that can be used to give further details supplementing the main line. | 150 | |
sellerAddress | postalCode | Optional | The identifier for an addressable group of properties according to the relevant postal service. | 50 | |
sellerAddress | city | Mandatory | The common name of the city, town or village, where the Supplier, Buyer and Shipping Recipient address is located. | 50 | |
sellerAddress | state | Mandatory | The state of a country. | 50 | |
sellerAddress | country | Mandatory | A code that identifies the country. | 3 |
Buyer’s 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 |
Shipping Details
ObjectName | Field Name | Conditionality | Informatics | Field Max Length | Sample Value |
---|---|---|---|---|---|
shippingRecipientAddress | addressLine1 | Mandatory where applicable | This is the main address line in an address structure that can be used to give the main address line information. A possible value for this field is “NA” and then all other address fields would not be provided except for the state field which would is mapped to the field. | 150 | |
shippingRecipientAddress | addressLine2 | Optional | An additional address line in an address that can be used to give further details supplementing the main line. | 150 | |
shippingRecipientAddress | addressLine3 | Optional | An additional address line in an address that can be used to give further details supplementing the main line. | 150 | |
shippingRecipientAddress | postalCode | Optional | The identifier for an addressable group of properties according to the relevant postal service. | 50 | |
shippingRecipientAddress | city | Mandatory where applicable | The common name of the city, town or village, where the Supplier, Buyer and Shipping Recipient address is located. | 50 | |
shippingRecipientAddress | state | Mandatory where applicable | The state of a country. | 50 | |
shippingRecipientAddress | country | Mandatory where applicable | A code that identifies the country. | 3 |
Invoice Line Item
ObjectName | Field Name | Conditionality | Informatics | Field Max Length | Sample Value |
---|---|---|---|---|---|
documentLineItems.lineItemId | Line ID | Optional | 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 | 4 | |
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 | |
documentLineItems.lineItemTotal | lineItemTotal | Mandatory | Sum of amount payable inclusive of total taxes chargeable | 1060 | |
invoiceAdditionalChargeAmount | Optional | Additional Charges at Invoice Level | |||
invoiceAdditionalDiscountAmount | Optional | Additional Discount at Invoice Level | |||
invoiceAmountExemptedFromTax | Amount Exempted from Tax | Mandatory if tax exemption is applicable | Total amount of tax exempted for sales tax or service tax purposes. Please add currencyID attribute to the XML element. | 10 | |
invoiceTaxExemptionReason | TaxExemptionReason | Mandatory if tax exemption is applicable | Description of tax exemption applicable on the invoice level. (e.g., Buyer’s sales tax exemption certificate number, special exemption as per gazette orders, etc.). | Goods acquired with SST exemption under Sales Tax Act 2018. Reference No: ABC.TAX(S)012-3/4/56(7) | |
paymentMeans | PaymentMeansCode | Optional | Chosen mechanism through which funds are transferred from buyer to supplier (e.g., cash, cheque, bank transfer, credit card, debit card, e-Wallet/ Digital Wallet, etc.) | 1 | |
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 | |
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 Schema
Parameter Name | Type | Length | Description |
---|---|---|---|
submissionUid | string | NA | The number generated by LHDN and serves as the official identifier for submissions. |
documentUlid | string | The number generated on the compliance side for internal tracking purposes and is primarily useful for internal operations. | |
uuid | string | Government acknowledgment number for the invoice triggered to LHDN. | |
invoiceCodeNumber | string | Document reference number used by Supplier for internal tracking purpose. |
Success Handling:
Success Response Example
When a submission is successful, the system returns a JSON response with details of the accepted documents.
{
"submissionUid": "RX6B21HC498ZENSDT46CDD7J10",
"acceptedDocuments": [
{
"documentUlid": "01J7DDBTBYG1G5JQEDVY8C1H6S",
"uuid": "3A2FR8X29FZ3H12ET46CDD7J10",
"invoiceCodeNumber": "ML-ST-2424",
"xmlEncoded": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/Pgo8SW52b2ljZSB4bWxucz0idXJuOm9hc2lzOm5hbWVzOnNwZWNpZmljYXRpb246dWJsOnNjaGVtYTp4c2Q6SW52b2ljZS0yIiB4bWxuczpjYWM9InVybjpvYXNpczpuYW1lczpzcGVjaWZpY2F0aW9uOnVibDpzY2hlbWE6eHNkOkNvbW1vbkFnZ3JlZ2F0ZUNvbXBvbmVudHMtMiIgeG1sbnM6Y2JjPSJ1cm46b2FzaXM6bmFtZXM6c3BlY2lmaWNhdGlvbnU6dWJsOnNjaGVtYTp4c2Q6Q29tbW9uQmFzaWNDb21wb25lbnRzLTIiIHhtbG5zOm5zND0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2ljIj4KCTxVQkxFeHRlbnNpb25zIHhtbG5zPSJ1cm46b2FzaXM6bmFtZXM6c3BlY2lmaWNhdGlvbnU6dWJsOnNjaGVtYTp4c2Q6Q29tbW9uRXh0ZW5zaW9uQ29tcG9uZW50cy0yIiB4bWxuczppbmZvPSJodHRwOi8vd3d3LmV4YW1wbGUuY29tL2luZm8uYXNkIj4KCQk8VGVzdERhdGE+U29tZSBkYXRhIGhlcmUuPC9UZXN0RGF0YT4KCQk8U2lnbmF0dXJlPgoJCQk8U2lnbmF0dXJlSW5mbz5EYXRhPC9TaWduYXR1cmVJbmZvPgoJCTwvU2lnbmF0dXJlPgo8L0ludm9pY2U+Cg=="
}
],
"rejectedDocuments": [],
"timestamp": "2023-08-14T08:15:30Z"
}
Error Handling:
Error Response Example
When an error occurs during submission, the system returns a JSON response containing details of the error.
{
"errorMessages": {
"0": {
"invoiceDataList[0]-buyerAddress-postalCode": "Buyer postalcode cannot be empty",
"invoiceDataList[0]-sellerAddress-state": "seller State must be a valid 2 digit number from 00 to 17",
"invoiceDataList[0]-sellerAddress-postalCode": "seller postalcode cannot be empty"
}
},
"batchId": null,
"errorCode": null
}
The API may return the following error responses depending on the validation result or request issues:
Error Code | Description |
---|---|
400 | Bad Request – Invalid data in the request. |
401 | Unauthorized – Invalid or missing API key. |
500 | Internal Server Error – Server encountered an error. |
The API may return the following success responses depending on the validation result or submission status:
Status Code | Description |
---|---|
200 | Success – The request was processed successfully. |
202 | Accepted – The request has been accepted but is still processing. |
- Ensure that your document types are accepted based on the specifications of your jurisdiction.
- Confirm that the invoice format complies with the standards to avoid any delays.