Malaysia: request and response examples

Send Malaysian e-invoices, credit notes and consumer receipts in GETS and read each response up to LHDN's result. Start with a sandbox API key and a Malaysian company's onboarded source.

Save the request

Save this body as malaysia-invoice.json. It is an ordinary business-to-business e-invoice for LHDN MyInvois with one service line charged with service tax. An ordinary B2B invoice takes no modifier, so documentType.modifiers stays empty.

malaysia-invoice.jsonjson
{
  "country": "MY",
  "environment": "sandbox",
  "purpose": "invoicing",
  "source": "acme-erp:1.0.0",
  "documentType": { "base": "tax_invoice", "modifiers": [] },
  "payload": {
    "header": {
      "documentType": { "base": "tax_invoice" },
      "documentNumber": "MY-2026-00217",
      "issueDate": "2026-10-01",
      "issueTime": "09:30:00Z",
      "currency": "MYR"
    },
    "parties": {
      "seller": {
        "name": "Selangor Tech Sdn Bhd",
        "address": {
          "addressLine1": "Level 8, 12 Jalan Contoh",
          "city": "Kuala Lumpur",
          "postalCode": "50450",
          "country": "MY",
          "extensions": { "my_countrySubentityCode": "14" }
        },
        "contact": {
          "name": "Accounts Receivable",
          "email": "billing@example.com",
          "phone": "+60312345678"
        },
        "taxIds": [{ "type": "TIN", "value": "C20880050010" }],
        "registrationNumbers": [{ "type": "BRN", "value": "202001234567" }],
        "industryClassification": {
          "code": "62010",
          "description": "Computer programming activities"
        }
      },
      "buyer": {
        "name": "Petaling Retail Sdn Bhd",
        "address": {
          "addressLine1": "No 5, Jalan Sampel 3",
          "city": "Petaling Jaya",
          "postalCode": "46050",
          "country": "MY",
          "extensions": { "my_countrySubentityCode": "10" }
        },
        "contact": { "phone": "+60378765432" },
        "taxIds": [{ "type": "TIN", "value": "C20880050004" }],
        "registrationNumbers": [{ "type": "BRN", "value": "201901012345" }]
      }
    },
    "lineItems": [
      {
        "id": "1",
        "name": "Software support",
        "description": "Monthly software support, September 2026",
        "quantity": 10,
        "unitCode": "HUR",
        "price": { "amount": 150 },
        "lineTaxableValue": 1500,
        "taxCategory": "02",
        "taxRate": 8,
        "taxAmount": 120,
        "lineTotal": 1620,
        "extensions": {
          "my_itemPriceExtension": 1500,
          "my_commodityClassificationClass": "022"
        }
      }
    ],
    "taxTotals": [
      {
        "taxAmount": 120,
        "taxSubtotals": [
          {
            "taxableAmount": 1500,
            "taxAmount": 120,
            "taxCategory": "02",
            "percent": 8
          }
        ]
      }
    ],
    "totals": {
      "totalLineTaxableAmount": 1500,
      "totalAmountExcludingTax": 1500,
      "totalTaxAmount": 120,
      "totalAmountIncludingTax": 1620,
      "amountDue": 1620
    }
  }
}

Replace source with the Malaysian company’s own name:version, and use an unused documentNumber. Keep environment: "sandbox" with a sandbox key. The envelope’s documentType decides which rules apply; Complyance copies it into payload.header.documentType, replacing any value there. These values are specific to Malaysia:

  • Issue date and time. Set issueDate and issueTime to when you issue the invoice, with the time in UTC as HH:mm:ssZ, such as 09:30:00Z. Change the sample date to today before you send it: LHDN does not accept a document issued more than 72 hours before it is submitted (LHDN FAQ), and neither value can be in the future.
  • Identifiers. Both parties need a TIN (tax identification number) in taxIds and a BRN (business registration number) in registrationNumbers. The seller and buyer TINs must differ.
  • Phone numbers. Both parties need a phone number: digits only, with one optional leading +, 8 to 20 characters long.
  • State code. address.extensions.my_countrySubentityCode is the LHDN state code, such as 14 for Kuala Lumpur and 10 for Selangor.
  • Seller activity. industryClassification holds the seller’s MSIC code and its business activity description.
  • Lines. taxCategory is an LHDN tax type, such as 02 for service tax. Use the rate that applies to the service; the sample uses 8%. my_commodityClassificationClass is the LHDN classification code for the item, and my_itemPriceExtension is the line amount before tax. lineTotal is the line amount including tax (rule MY-LINE-TOTAL). Send exactly one entry in taxTotals.

Read the Malaysia field reference for other document types and conditional fields.

Send the request

Sandbox and production use the same host, https://prod.gets.complyance.io. The "environment": "sandbox" field in the request body is what sends this invoice to sandbox.

Submit a Malaysian invoice in sandboxbash
curl --request POST 'https://prod.gets.complyance.io/api/v3/unify' \
  --header "Authorization: Bearer ${COMPLYANCE_API_KEY}" \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json' \
  --header 'new-api: true' \
  --data @malaysia-invoice.json

Read the response

HTTP 200 means the invoice passed validation and was stored. This illustrative response includes a short Base64-encoded XML fragment to show the shape; the actual Base64XML contains the generated invoice, not this fragment.

Validated invoice — HTTP 200json
{
  "documentId": "01K6EXAMPLE00000000000217",
  "documentNumber": "MY-2026-00217",
  "message": "Your invoice was validated and is ready for submission.",
  "Base64XML": "PEludm9pY2U+PElEPk1ZLTIwMjYtMDAyMTc8L0lEPjwvSW52b2ljZT4="
}

If the request returns HTTP 422, inspect every entry in errors. This sample shows the response for a request sent without the buyer’s TIN; the messages in your response can differ.

Missing buyer TIN — HTTP 422json
{
  "documentId": "01K6EXAMPLE00000000000218",
  "documentNumber": "MY-2026-00217",
  "message": "Your invoice could not be validated. Review the errors and try again.",
  "validationStage": "gets",
  "errors": [
    {
      "code": "MY-PARTY-001",
      "getsPath": "parties.buyer.taxIds",
      "payloadPath": "parties.buyer.taxIds",
      "message": "MY: Buyer TIN is mandatory.",
      "severity": "error",
      "ruleSet": "my:tax_invoice"
    }
  ]
}

Correct the field named by getsPath, then send the request again. The Malaysia validation rules explain the checks LHDN applies after submission. For 404, confirm your source name and version; for 403, check that the key’s environment matches environment. See Unify errors for other statuses.

Check LHDN’s result

A 200 is not LHDN’s answer. Follow the document by documentId, as described in Submit and retrieve, until isTerminal is true. This response is shortened: government, which holds LHDN’s record of the document, and artifacts are left out.

Validated by LHDN — HTTP 200json
{
  "success": true,
  "data": {
    "documentId": "01K6EXAMPLE00000000000217",
    "documentNumber": "MY-2026-00217",
    "country": "MY",
    "environment": "sandbox",
    "state": "final_valid",
    "isTerminal": true,
    "lastUpdatedAt": "2026-10-01T09:31:12.000Z",
    "errors": [],
    "validationResults": {
      "status": "Valid",
      "validationSteps": [
        { "name": "Validation Passed", "status": "Valid", "error": null },
        { "name": "Queue Admitted", "status": "Valid", "error": null },
        {
          "name": "Delivery Processing Started",
          "status": "Valid",
          "error": null
        },
        { "name": "Final Valid", "status": "Valid", "error": null }
      ]
    }
  }
}

final_valid means LHDN marked the document valid. From that moment the issuer can cancel it, and the buyer can reject it, for 72 hours; see the life of a Malaysian e-invoice. final_invalid means LHDN marked it invalid; read LHDN’s reason in government.

Other document types

Each request below is complete and passes Unify’s validation as written, once you set its dates to today. Send it the same way.

Credit note

A credit note reduces an invoice that LHDN has already validated. It names the original invoice’s number in header.referenceId and its LHDN document UUID in extensions.my_originalReferenceUuid. Use the UUID LHDN gave the original invoice, not this sample value.

malaysia-credit-note.jsonjson
{
  "country": "MY",
  "environment": "sandbox",
  "purpose": "invoicing",
  "source": "acme-erp:1.0.0",
  "documentType": { "base": "credit_note", "modifiers": [] },
  "payload": {
    "header": {
      "documentType": { "base": "credit_note" },
      "documentNumber": "MY-CN-2026-00012",
      "referenceId": "MY-2026-00217",
      "issueDate": "2026-10-03",
      "issueTime": "02:15:00Z",
      "currency": "MYR"
    },
    "parties": {
      "seller": {
        "name": "Selangor Tech Sdn Bhd",
        "address": {
          "addressLine1": "Level 8, 12 Jalan Contoh",
          "city": "Kuala Lumpur",
          "postalCode": "50450",
          "country": "MY",
          "extensions": { "my_countrySubentityCode": "14" }
        },
        "contact": {
          "name": "Accounts Receivable",
          "email": "billing@example.com",
          "phone": "+60312345678"
        },
        "taxIds": [{ "type": "TIN", "value": "C20880050010" }],
        "registrationNumbers": [{ "type": "BRN", "value": "202001234567" }],
        "industryClassification": {
          "code": "62010",
          "description": "Computer programming activities"
        }
      },
      "buyer": {
        "name": "Petaling Retail Sdn Bhd",
        "address": {
          "addressLine1": "No 5, Jalan Sampel 3",
          "city": "Petaling Jaya",
          "postalCode": "46050",
          "country": "MY",
          "extensions": { "my_countrySubentityCode": "10" }
        },
        "contact": { "phone": "+60378765432" },
        "taxIds": [{ "type": "TIN", "value": "C20880050004" }],
        "registrationNumbers": [{ "type": "BRN", "value": "201901012345" }]
      }
    },
    "lineItems": [
      {
        "id": "1",
        "name": "Software support",
        "description": "Credit for 2 hours not delivered, September 2026",
        "quantity": 2,
        "unitCode": "HUR",
        "price": { "amount": 150 },
        "lineTaxableValue": 300,
        "taxCategory": "02",
        "taxRate": 8,
        "taxAmount": 24,
        "lineTotal": 324,
        "extensions": {
          "my_itemPriceExtension": 300,
          "my_commodityClassificationClass": "022"
        }
      }
    ],
    "taxTotals": [
      {
        "taxAmount": 24,
        "taxSubtotals": [
          {
            "taxableAmount": 300,
            "taxAmount": 24,
            "taxCategory": "02",
            "percent": 8
          }
        ]
      }
    ],
    "totals": {
      "totalLineTaxableAmount": 300,
      "totalAmountExcludingTax": 300,
      "totalTaxAmount": 24,
      "totalAmountIncludingTax": 324,
      "amountDue": 324
    },
    "supportingDocuments": [
      { "id": "MY-2026-00217", "documentType": "precedingInvoiceReference" }
    ],
    "extensions": { "my_originalReferenceUuid": "F9D425P6DS7D8IU8J3H2K1L0A" }
  }
}

Receipt for a consumer sale

A receipt records a sale to a consumer who does not ask for an e-invoice. Add the is_receipt modifier and leave the buyer out. Unify validates the receipt and stores it in the B2C Vault, which later combines it with the month’s other receipts into one consolidated e-invoice for LHDN.

malaysia-receipt.jsonjson
{
  "country": "MY",
  "environment": "sandbox",
  "purpose": "invoicing",
  "source": "acme-erp:1.0.0",
  "documentType": { "base": "tax_invoice", "modifiers": ["is_receipt"] },
  "payload": {
    "header": {
      "documentType": { "base": "tax_invoice", "modifiers": ["is_receipt"] },
      "documentNumber": "RCPT-2026-104233",
      "issueDate": "2026-10-01",
      "issueTime": "05:48:00Z",
      "currency": "MYR"
    },
    "parties": {
      "seller": {
        "name": "Selangor Tech Sdn Bhd",
        "address": {
          "addressLine1": "Level 8, 12 Jalan Contoh",
          "city": "Kuala Lumpur",
          "postalCode": "50450",
          "country": "MY",
          "extensions": { "my_countrySubentityCode": "14" }
        },
        "contact": {
          "name": "Accounts Receivable",
          "email": "billing@example.com",
          "phone": "+60312345678"
        },
        "taxIds": [{ "type": "TIN", "value": "C20880050010" }],
        "registrationNumbers": [{ "type": "BRN", "value": "202001234567" }],
        "industryClassification": {
          "code": "62010",
          "description": "Computer programming activities"
        }
      }
    },
    "lineItems": [
      {
        "id": "1",
        "name": "USB-C charger",
        "description": "USB-C charger, 65 W",
        "quantity": 1,
        "unitCode": "C62",
        "price": { "amount": 89 },
        "lineTaxableValue": 89,
        "taxCategory": "01",
        "taxRate": 10,
        "taxAmount": 8.9,
        "lineTotal": 97.9,
        "extensions": {
          "my_itemPriceExtension": 89,
          "my_commodityClassificationClass": "022"
        }
      }
    ],
    "taxTotals": [
      {
        "taxAmount": 8.9,
        "taxSubtotals": [
          {
            "taxableAmount": 89,
            "taxAmount": 8.9,
            "taxCategory": "01",
            "percent": 10
          }
        ]
      }
    ],
    "totals": {
      "totalLineTaxableAmount": 89,
      "totalAmountExcludingTax": 89,
      "totalTaxAmount": 8.9,
      "totalAmountIncludingTax": 97.9,
      "amountDue": 97.9
    }
  }
}

A receipt is not submitted to LHDN on its own, so the response has no XML:

Receipt stored — HTTP 200json
{
  "documentId": "01K6EXAMPLE00000000004233",
  "documentNumber": "RCPT-2026-104233",
  "message": "Receipt created successfully.",
  "Base64XML": ""
}