Complyance Logo

Global Unify API v3 — Integration Guide

Submit and manage invoices across supported countries with a single, unified endpoint.
Version: v3 · Protocol: REST / JSON · Countries: SA · MY · BE · AE · SG · DE

Overview

The Unify API is a global, unified endpoint that consolidates invoice management functionalities across supported countries. It encompasses validation for Business-to-Business (B2B), Business-to-Consumer (B2C), and Business-to-Government (B2G) transactions.

Key Features:

  • Single Endpoint — Submit invoices and manage documents across all supported countries with one consistent URL
  • Multi-Transaction Support — Handles validation for B2B, B2C, and B2G transactions
  • Validation & Submission — Comprehensive validation and government submission workflow
  • XML Response Support — Responses can be returned as XML files in addition to JSON format

After successfully onboarding, simply use the Unify API key to submit invoices. The system will handle validation, document transformation, and government submission based on the specified country and invoice type.

Endpoint

POST /api/v3/unify

Every request uses this same URL. The action field in the request body controls what the API does.

ActionDescription
"submit"Submit one or more invoices for processing and government submission. Supports single and bulk (up to 10 invoices per request).
"list"Retrieve document details for a previously submitted invoice. Currently supported for Malaysia (MY) only.

Authentication

All requests must include your API key as a Bearer token in the Authorization header.

Authorization: Bearer <YOUR_API_KEY>
Content-Type: application/json

Keep your API key secure. Never expose it in frontend code, public repositories, or logs. Use environment variables to store it server-side.

API key must match the environment. Your production key is required for "env": "production" or "prod". For other environments like "sandbox" and "simulation", you can use your mock key. Mismatches will return an auth error.

Environments

Every request includes an env field that tells the API which environment to use. This must match the environment your API key was issued for.

env valueUse for
sandboxDevelopment and testing. Requests are not submitted to any government system.
simulationEnd-to-end testing that mimics production behaviour without real submission.
production or prodLive submissions to government tax authorities.

Start with sandbox or simulation. Always build and test your integration using sandbox or simulation environments first. These environments may behave differently depending on the country and regulatory requirements. Switch to production only when you're ready to submit real invoices.

The "Purpose" Workflow

The integration requires a specific two-stage process to ensure your document data correctly translates to regulatory standards.

Step 1: MAPPING (Setup & Template Creation)

Set the Purpose to "MAPPING" to push your raw data to the Complyance platform. This stage is used for initial field discovery and visualization.

  • In Code: Submit your payload with "purpose": "MAPPING"
  • In Portal: Locate the uploaded payload, complete the field mapping, and save it as a successful Template.
  • Final Step: Register and bind your unique sourceName and sourceVersion to this template on the portal.

Step 2: INVOICING (Production Submission)

After your template is successfully bound to your source identifiers, change the Purpose to "INVOICING".

  • Action: The system now recognizes your sourceName/sourceVersion and applies the saved template logic to transform, validate, and officially submit the document to the tax authority.
  • Requirement: You must use the exact same Source identifiers registered during the Mapping phase.

Payload Structure (Country Label & Tooltip Mapping)

Use the following mapping structure as a payload reference for country-specific field labels and tooltips. For a complete and detailed field mapping reference, refer to the Field Mapping Payload Reference page.

Integration Engine & Field Mapping Workflow

Before submitting invoices through the Unify API, you must complete the field mapping process through the Integration Engine portal. This ensures your payload data correctly aligns with regulatory requirements for your target countries.

Complete Mapping Process

  1. Access the Integration Engine Portal

    • Navigate to your Dev Portal or Integration Engine dashboard
    • Create a new integration or select an existing one
  2. Upload Your Payload

    • Upload a sample JSON payload file representing your invoice data structure
    • The platform will analyze your payload and identify all available fields
  3. Map Your Fields

    • Map each field from your source payload to the corresponding Complyance standard field
    • Configure field transformations if needed (formatting, calculations, etc.)
    • Validate that all mandatory fields for your target country are mapped
  4. Test & Validate

    • Submit a test payload with "purpose": "MAPPING" through the Unify API
    • Verify the transformed data in the portal
    • Review any validation warnings or errors
  5. Save & Bind Your Template

    • Save your completed field mapping as a template
    • Register your integration with unique sourceName and sourceVersion identifiers
    • Bind this template to your integration

Using Mapped Templates with Unify API

Once your mapping is complete and bound to your integration, you can submit invoices through the Unify API:

  1. Initial Submissions — Use "purpose": "MAPPING" if testing new payload structures
  2. Production Submissions — Switch to "purpose": "INVOICING" to use the bound template
  3. Critical Requirement — Always use the exact same sourceName and sourceVersion that you registered in the Integration Engine

The Unify API will automatically apply your saved field mappings and validation rules, transforming your raw payload data into regulatory-compliant documents for submission to government authorities.

LogicalDocType

LogicalDocType is the recommended way to drive document behavior across different transaction types (B2B/B2C variants, export/self-billed/third-party, etc.). The same LogicalDocType values apply across all supported countries, ensuring consistency in your integration regardless of the target regulatory environment.

Common Document Types:

  • B2B Invoices: TAX_INVOICE, TAX_INVOICE_CREDIT_NOTE, TAX_INVOICE_DEBIT_NOTE
  • B2C Invoices (Simplified): SIMPLIFIED_TAX_INVOICE, SIMPLIFIED_TAX_INVOICE_CREDIT_NOTE
  • Special Types: EXPORT_INVOICE, SELF_BILLED_INVOICE, THIRD_PARTY_INVOICE, DEEMED_SUPPLY, MARGIN_SCHEME, CONTINUOUS_SUPPLY

Use the appropriate LogicalDocType value in the logicalDocumentType field of your request to ensure the correct document classification and validation rules are applied by the system.

Submit Invoices

Use action: "submit" to send invoices for processing. You can submit a single invoice or up to 10 invoices in one request (bulk).

Request Structure

{
  "action":  "submit",
  "purpose": "invoicing",
  "env":     "sandbox",

  "defaults": {
    "country":             "MY",
    "logicalDocumentType": "TAX_INVOICE",
    "source": {
      "name":    "your-system-name",
      "version": "1.0"
    },
    "destinations": [
      { "type": "TAX_AUTHORITY" }
    ]
  },

  "invoices": [
    {
      "payload": {
        "invoice_data": {
          "document_number": "INV-2026-0001",
          "invoice_date":    "2026-02-23"
        }
      }
    }
  ],

  "options": {
    "continueOnError":    true,
    "submitToGovernment": true
  }
}

Field Reference

FieldRequiredDescription
action✅ RequiredMust be "submit"
purpose✅ RequiredMust be "invoicing"
env✅ RequiredOne of: sandbox, simulation, production, prod
defaults.country✅ RequiredISO country code. Supported: SA, MY, BE, AE, SG, DE
defaults.logicalDocumentType✅ RequiredDocument type, validated per country (e.g. TAX_INVOICE)
defaults.source.name✅ RequiredName of your system or integration
defaults.source.version✅ RequiredVersion of your system
defaults.destinations⬜ OptionalArray of destination objects. Tax authority submission is mandatory by default. Use this field when the document needs to be routed to additional networks such as PEPPOL in parallel with the tax authority submission.
invoices✅ RequiredArray of invoice objects. Min 1, max 10.
invoices[].payload✅ RequiredInvoice data object. Must not be empty.
options.continueOnError⬜ OptionalIn bulk mode: true = process remaining invoices if one fails. false = abort on first error.
options.submitToGovernment⬜ OptionalDefaults to true when purpose is "invoicing".

Important Notes

payload goes directly inside each invoice object — do not wrap it in an extra object.

// ✅ Correct
"invoices": [
  { "payload": { "invoice_data": { ... } } }
]

// ❌ Wrong
"invoices": [
  { "invoice": { "payload": { "invoice_data": { ... } } } }
]

Do not include metaConfig — the fields defaults.metaConfig and invoices[].metaConfig are system-managed and will be rejected if present in your request.

List Documents (Malaysia)

Use action: "list" to retrieve the full document details for a previously submitted invoice. This action is currently supported for Malaysia (MY) only.

You need two identifiers to look up a document — both are returned in the submit response:

IdentifierWhere to find it
uuidReturned by the tax authority after successful submission
documentIdReturned by the API in the submit response (results[].documentId)

Request Structure

{
  "action": "list",
  "env":    "sandbox",

  "filters": {
    "country":    "MY",
    "uuid":       "4Q2H2R3YSSYZTX5TRWZF2M2K10",
    "documentId": "01DXXXXXXXXXXXXXXXXXXXXXXX"
  },

  "page":  1,
  "limit": 20,
  "sort":  "createdAt:desc"
}

The document details are returned inside data.results[0].documentDetails in the response.

Validation Rules

General

RuleDetail
envMust be one of: sandbox, simulation, production/prod
Supported countriesSA, MY, BE, AE, SG, DE
API key / env mismatchReturns AUTH_INVALID_API_KEY

Submit Action

RuleDetail
Invoice countMin 1, max 10 invoices per request
logicalDocumentTypeMust be a valid type for the specified country
invoices[].payloadMust be a non-empty object
submitToGovernmentCannot be false when purpose is "invoicing"

List Action

RuleDetail
filters.countryMust be "MY" (only Malaysia is supported)
filters.uuidRequired
filters.documentIdRequired
filters.tinNumberOptional — resolved automatically, do not send

Response Format

All API responses share a consistent envelope structure, whether the request succeeded or failed.

Submit — Success Response

{
  "status":    "success",
  "code":      "OK",
  "message":   "Processed",
  "requestId": "01J...",
  "timestamp": "2026-02-26T10:00:00.000Z",
  "data": {
    "summary": {
      "total":   2,
      "success": 2,
      "failed":  0
    },
    "results": [
      {
        "index":      0,
        "externalId": "invoice-1",
        "status":     "success",
        "country":    "SA",
        "inputLogicalDocumentType": "TAX_INVOICE",
        "resolvedDocumentType":     "tax_invoice",
        "derivedFlags": {
          "isExport": false,
          "isSelfBilled": false,
          "isThirdParty": false,
          "isNominalSupply": false,
          "isSummary": false,
          "isB2B": true,
          "isPrepayment": false,
          "isAdjusted": false,
          "isReceipt": false,
          "isB2G": false,
          "isPartial": false,
          "isPartialConstruction": false,
          "isPartialFinalConst": false,
          "isFinalConstruction": false
        },
        "payloadId":  "01KJCVMXZ2V23SC1HP5GHY8484",
        "documentId": "01D...",
        "validation": {
          "success": true,
          "errors": []
        },
        "submission": {
          "success": true,
          "errors": [],
          "governmentResponse": {
            "statusCode": 200,
            "body": {
              "clearanceStatus": "CLEARED",
              "invoiceHash": "..."
            }
          },
          "submittedAt": "2026-02-26T10:00:00.000Z"
        },
        "errors":     []
      }
    ]
  },
  "errors": []
}

Save the documentId. This is your reference for looking up document details later using the list action. Persist it in your system alongside your invoice record.

submission.governmentResponse (Important)

  • submission.governmentResponse contains the actual country adapter/government response payload.
  • The shape varies by country and adapter implementation/version.
  • Parse this object as country-specific data; do not enforce one global schema for all countries.
  • Large internal keys like originalDocument / updatedDocument may be omitted to keep response size manageable.

Example (Malaysia style):

{
  "submissionUid": "5XE7HPZYDZAVJB8XDZEEC8HK10",
  "acceptedDocuments": [
    {
      "uuid": "GVHDKMWYEYKMDMVHDZEEC8HK10",
      "invoiceCodeNumber": "INV-2026-0001"
    }
  ],
  "rejectedDocuments": []
}

List — Success Response

{
  "status": "success",
  "data": {
    "summary": {
      "total":    1,
      "returned": 1,
      "page":     1,
      "limit":    20
    },
    "results": [
      {
        "index":          0,
        "documentId":     "01DXXXXXXXXXXXXXXXXXXXXXXX",
        "uuid":           "4Q2H2R3YSSYZTX5TRWZF2M2K10",
        "country":        "MY",
        "environment":    "sandbox",
        "documentDetails": {}
      }
    ]
  }
}

Error Response

{
  "status":    "error",
  "code":      "VALIDATION_ERROR",
  "message":   "Request validation failed",
  "requestId": "01J...",
  "timestamp": "2026-02-26T10:00:00.000Z",
  "data":      null,
  "errors": [
    {
      "code":    "REQ_INVALID_INPUT",
      "message": "documentId is required for list action",
      "path":    ["filters", "documentId"]
    }
  ]
}

The errors array tells you exactly which field failed and why. Use the path field to pinpoint the issue in your request body.

Quick Start Checklist

  1. Get your API key — Start with a sandbox key so you can test safely without submitting real invoices.
  2. Send a test submit request — Use the single-invoice example with "env": "sandbox". Verify you get a "status": "success" response.
  3. Save the documentId — Store the documentId from the submit response in your system — you'll need it to retrieve document details.
  4. Test the list action (Malaysia) — Use the uuid and documentId to call the list endpoint and verify document details are returned.
  5. Switch to production — Replace your sandbox API key with your production key and update "env" to "production". You're live!

Examples & Code Samples

See Examples for detailed cURL examples and code samples for single submit, bulk submit, and list operations.