My App
Guides

Submit Your First Invoice

Step-by-step guide to creating and submitting an e-invoice to LHDN

This guide walks you through creating an invoice, submitting it to LHDN via the BizCARE Books e-Invoicing API, and checking its validation status.

Prerequisites

  • Your company is registered and fully configured (see Getting Started)
  • You have a valid API key (with biz_ prefix)
  • Your LHDN client credentials (clientId / clientSecret) are set up on your company

Step 1: Verify Your Company Is Ready

Before creating an invoice, confirm that your company profile is complete and ready for submissions.

Check company readiness
curl -X GET https://api.bizcare.my/api/v1/companies \
  -H "X-Api-Key: biz_test_your-api-key"

In the response, check that isCompanyReady is true:

{
  "data": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "name": "TechVenture Sdn Bhd",
    "tinCode": "C20948240010",
    "registrationType": "BRN",
    "registrationNumber": "202301045678",
    "isCompanyReady": true,
    "asBuyer": { ... },
    "asSupplier": { ... }
  }
}

If isCompanyReady is false, you are missing required fields such as LHDN credentials, MSIC code, or address. Complete your company profile in the dashboard before proceeding.

Step 2: Create an Invoice

Create a standard invoice with buyer details and line items. Invoice codes are sequential integers unique to your company.

Replace the date placeholder

invoiceDateTime.date must be today or up to 3 days back on the Malaysian calendar. It can never be in the future. Replace <today, YYYY-MM-DD> in the examples below with a real date in that window, or the call fails with 400 VALIDATION_ERROR. See Issue dates.

Create an invoice
curl -X POST https://api.bizcare.my/api/v1/invoices \
  -H "X-Api-Key: biz_test_your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "INVOICE",
    "invoiceCode": 1001,
    "invoiceDateTime": {
      "date": "<today, YYYY-MM-DD>",
      "time": "14:30:00Z"
    },
    "supplier": {
      "name": "TechVenture Sdn Bhd",
      "tin": "C20948240010",
      "registrationType": "BRN",
      "registrationNumber": "202301045678",
      "contactNumber": "+60312345678",
      "email": "billing@techventure.com.my",
      "partyType": "LOCAL_BUSINESS_AGENT_DEALER_DISTRIBUTOR",
      "msic": "62011",
      "businessActivityDescription": "Software development and IT consulting",
      "address": {
        "addressLine0": "Level 15, Menara TechVenture",
        "addressLine1": "Jalan Bangsar",
        "cityName": "Kuala Lumpur",
        "state": "14",
        "country": "MYS",
        "postalZone": "59200"
      }
    },
    "buyer": {
      "name": "GlobalTrade Sdn Bhd",
      "tin": "C25845670020",
      "registrationType": "BRN",
      "registrationNumber": "201901067890",
      "contactNumber": "+60387654321",
      "email": "accounts@globaltrade.com.my",
      "partyType": "LOCAL_BUSINESS_AGENT_DEALER_DISTRIBUTOR",
      "address": {
        "addressLine0": "No. 42, Jalan Sultan Ismail",
        "cityName": "Kuala Lumpur",
        "state": "14",
        "country": "MYS",
        "postalZone": "50250"
      }
    },
    "lineItems": [
      {
        "id": "1",
        "description": "Custom ERP Module - Inventory Management",
        "unit": {
          "count": 1,
          "price": 15000.00,
          "code": "EA"
        },
        "taxDetails": [
          {
            "taxType": "01",
            "taxRate": {
              "percentage": 10
            }
          }
        ],
        "classifications": ["022"]
      },
      {
        "id": "2",
        "description": "Annual Software Maintenance & Support",
        "unit": {
          "count": 12,
          "price": 500.00,
          "code": "MON"
        },
        "taxDetails": [
          {
            "taxType": "01",
            "taxRate": {
              "percentage": 10
            }
          }
        ],
        "classifications": ["022"]
      }
    ],
    "payment": {
      "mode": "03",
      "terms": "Net 30"
    }
  }'

A successful response returns the full invoice in data. Read data.id for the invoice ID. The example below is shortened:

{
  "success": true,
  "message": "Created successfully",
  "data": {
    "id": "f7e6d5c4-b3a2-1098-7654-321fedcba098",
    "invoiceCode": 1001,
    "type": "INVOICE",
    "status": "Pending",
    "latestSubmission": null
  }
}

Send an Idempotency-Key header on every create so a retry never makes a second invoice. If the code is already taken, you get 409 CODE_EXISTS. Invoice codes are unique across both test and live, so a test invoice with code 1001 blocks 1001 in live. See Error handling.

The supplier field is optional if your company profile is complete -- BizCARE will auto-populate it from your company details. You can override specific supplier fields by providing them explicitly.

Step 3: Submit to LHDN

Submit the invoice to LHDN for validation.

Submit invoice to LHDN
curl -X POST https://api.bizcare.my/api/v1/invoices/f7e6d5c4-b3a2-1098-7654-321fedcba098/submit-to-myinvois \
  -H "X-Api-Key: biz_test_your-api-key"
{
  "success": true,
  "message": "Submitted successfully",
  "data": {
    "submissionId": "HJSDHSA...",
    "accepted": 1,
    "rejected": 0,
    "results": [
      { "invoiceId": "f7e6d5c4-b3a2-1098-7654-321fedcba098", "code": "1001", "outcome": "accepted" }
    ]
  }
}

HTTP 200 does not mean LHDN accepted the invoice

The call returns 200 even when LHDN rejects the document at intake. Check data.rejected and each results[].outcome (accepted or rejected, with a reason when rejected). Even an accepted result only means LHDN took the document for processing. The final answer (Valid or Invalid) comes later.

Demo organizations cannot submit to LHDN and get 409.

Step 4: Check Submission Status

Right after a submit, the invoice status is Submitted, not Valid. LHDN validates the document in the background, usually within seconds to minutes. Either poll as shown below, or use webhooks. See how statuses stay fresh.

Check the status by retrieving the submitted documents for your invoice.

Check submitted document status
curl -X GET https://api.bizcare.my/api/v1/invoices/f7e6d5c4-b3a2-1098-7654-321fedcba098/submitted-documents \
  -H "X-Api-Key: biz_test_your-api-key"
{
  "data": [
    {
      "id": "d1c2b3a4-5678-90ab-cdef-123456789abc",
      "uuid": "LHDN-DOC-UUID-HERE",
      "status": "Valid",
      "code": "1001",
      "type": "INVOICE",
      "longId": "LHDN-LONG-ID-FOR-PUBLIC-QUERIES",
      "failReason": null,
      "failDetails": null,
      "createdAt": "2026-03-19T14:31:00.000Z"
    }
  ]
}

A Valid status means LHDN has accepted the invoice as a legally compliant e-invoice.

If the status is Invalid, check the failReason and failDetails fields for specific validation errors from LHDN, fix the issues, and resubmit.

Alternative: Create and Submit in One Step

You can combine invoice creation and submission into a single request by passing submitImmediately: true:

Create and submit in one step
curl -X POST https://api.bizcare.my/api/v1/invoices \
  -H "X-Api-Key: biz_test_your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "INVOICE",
    "invoiceCode": 1002,
    "invoiceDateTime": {
      "date": "<today, YYYY-MM-DD>",
      "time": "15:00:00Z"
    },
    "buyer": {
      "name": "GlobalTrade Sdn Bhd",
      "tin": "C25845670020",
      "registrationType": "BRN",
      "registrationNumber": "201901067890",
      "contactNumber": "+60387654321",
      "partyType": "LOCAL_BUSINESS_AGENT_DEALER_DISTRIBUTOR",
      "address": {
        "addressLine0": "No. 42, Jalan Sultan Ismail",
        "cityName": "Kuala Lumpur",
        "state": "14",
        "country": "MYS",
        "postalZone": "50250"
      }
    },
    "lineItems": [
      {
        "id": "1",
        "description": "IT Consulting Services - March 2026",
        "unit": {
          "count": 40,
          "price": 250.00,
          "code": "HUR"
        },
        "taxDetails": [
          {
            "taxType": "02",
            "taxRate": {
              "percentage": 8
            }
          }
        ]
      }
    ],
    "submitImmediately": true
  }'

The response data is the full invoice object (shortened here). Read data.id. The status is Submitted until LHDN validates it.

{
  "success": true,
  "message": "Submitted successfully",
  "data": {
    "id": "a9b8c7d6-e5f4-3210-9876-543210fedcba",
    "invoiceCode": 1002,
    "status": "Submitted",
    "latestSubmission": { "status": "Submitted", "uuid": "..." }
  }
}

When using submitImmediately, if the invoice is created successfully but submission to LHDN fails, you will receive a response with "message": "Created but submission failed". The invoice still exists and you can submit it separately via the submit endpoint.

Next Steps

On this page