API Reference

Branches and Group VAT

Wafeq's e-invoicing API supports reporting documents from a Group VAT member or multiple branches.

In the context of Value Added Tax (VAT), a Branch and a Group VAT Member represent two different organizational structures and methods of VAT treatment.

A Branch is an extension of a parent company operating in a different location or jurisdiction. It is not a separate legal entity but rather a part of the parent company. The Branch typically shares the same VAT registration number as the parent company if they are operating within the same country. In some cases, especially in different jurisdictions, the branch may need to obtain its own VAT registration.
While Group VAT members are separate legal entities (such as companies) that are closely related (e.g., parent companies and subsidiaries) and are treated as a single VAT entity for VAT purposes.

When reporting VAT, both Branches and Group VAT Members need to be created as devices, and the
X-ZATCA-Branch value needs to be added when reporting invoices or documents.

📘

How to tell if a VAT Number is a Group VAT

If the 11th digit of the entity's VAT number is 1 then it is a Group VAT number.

Reporting documents from a branch

To issue an e-invoice through a branch, you must first register a device for that branch.
When making the register request, you must set the X-ZATCA-Branch to the branch name.

Here is an example of a register device request for a branch called Abdallah Trading LLC Jeddah:

curl --request POST \
     --url https://api.wafeq.com/v1/zatca/devices/register/ \
     --header 'Authorization: Api-Key replace_with_your_api_key' \
     --header 'X-ZATCA-Branch: Abdallah Trading LLC Jeddah' \
     --header 'X-ZATCA-Environment: production' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "common_name": "abdallah-jeddah",
  "otp": "123456"
}
'
import sdk from '@api/wafeq-zatca';

sdk.auth('Api-Key replace_with_your_api_key');
sdk.devices_register_create({
  common_name: 'abdallah-jeddah',
  otp: '123456'
}, {
  'X-ZATCA-Branch': 'Abdallah Trading LLC Jeddah',
  'X-ZATCA-Environment': 'production'
})
  .then(({ data }) => console.log(data))
  .catch(err => console.error(err));
import requests

url = "https://api.wafeq.com/v1/zatca/devices/register/"

payload = {
    "common_name": "abdallah-jeddah",
    "otp": "123456"
}
headers = {
    "accept": "application/json",
    "X-ZATCA-Branch": "Abdallah Trading LLC Jeddah",
    "X-ZATCA-Environment": "production",
    "content-type": "application/json",
    "Authorization": "Api-Key replace_with_your_api_key"
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
<?php

$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://api.wafeq.com/v1/zatca/devices/register/",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => json_encode([
    'common_name' => 'abdallah-jeddah',
    'otp' => '123456'
  ]),
  CURLOPT_HTTPHEADER => [
    "Authorization: Api-Key replace_with_your_api_key",
    "X-ZATCA-Branch: Abdallah Trading LLC Jeddah",
    "X-ZATCA-Environment: production",
    "accept: application/json",
    "content-type: application/json"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}

You can then report documents from a specific branch by setting the X-ZATCA-Branch header to the branch name registered in the previous step.

To display the branch name on the invoice, set the document.supplier.namein the body to the branch name registered above to display it on the PDF.

Here is an example of a credit note reported from Abdallah Trading LLC Jeddah branch:

curl --request POST \
     --url https://api.wafeq.com/v1/zatca/credit-notes/report/ \
     --header 'Authorization: Api-Key replace_with_your_api_key' \
     --header 'X-ZATCA-Branch: Abdallah Trading LLC Jeddah' \
     --header 'X-ZATCA-Environment: production' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  //Remaining Body
  ...
  "document": {
    "supplier": {
      "name": "Abdallah Trading LLC Jeddah"
    }
  }
}
'
import wafeqZatca from '@api/wafeq-zatca';

wafeqZatca.auth('Api-Key replace_with_your_api_key');
wafeqZatca.credit_notes_report_create({
  
  //Remaining Body
  ...  
  document: {
    supplier: {
      name: 'Abdallah Trading LLC Jeddah'
    }
  }
}, {
  'X-ZATCA-Branch': 'Abdallah Trading LLC Jeddah',
  'X-ZATCA-Environment': 'production'
})
  .then(({ data }) => console.log(data))
  .catch(err => console.error(err));

import requests

url = "https://api.wafeq.com/v1/zatca/credit-notes/report/"

payload = {
  
  # Remaining Body 
  ...
    "document": {
        "supplier": {
            "name": "Abdallah Trading LLC Jeddah"
        },      
    }  
}
headers = {
    "accept": "application/json",
    "X-ZATCA-Branch": "Abdallah Trading LLC Jeddah",
    "X-ZATCA-Environment": "production",
    "content-type": "application/json",
    "Authorization": "Api-Key replace_with_your_api_key"
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)

<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.wafeq.com/v1/zatca/credit-notes/report/', [
  'body' => '{... "document":{"supplier":{"name":"Abdallah Trading LLC Jeddah"}}}',
  'headers' => [
    'Authorization' => 'Api-Key replace_with_your_api_key',
    'X-ZATCA-Branch' => 'Abdallah Trading LLC Jeddah',
    'X-ZATCA-Environment' => 'production',
    'accept' => 'application/json',
    'content-type' => 'application/json',
  ],
]);

echo $response->getBody();

Reporting documents from a Group VAT member

To issue an e-invoice through a Group VAT member, you must first register a device for that member.
When making the register request, you must set the X-ZATCA-Branch to the member's TIN (Tax Identification Number).

Here is an example of a registere device request for a Group VAT member called Abdallah Trading LLC Jeddah whose TIN is 3125678939:

curl --request POST \
     --url https://api.wafeq.com/v1/zatca/devices/register/ \
     --header 'Authorization: Api-Key replace_with_your_api_key' \
     --header 'X-ZATCA-Branch: 3125678939' \
     --header 'X-ZATCA-Environment: production' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "common_name": "abdallah-jeddah",
  "otp": "123456"
}
'
import sdk from '@api/wafeq-zatca';

sdk.auth('Api-Key replace_with_your_api_key');
sdk.devices_register_create({
  common_name: 'abdallah-jeddah',
  otp: '123456'
}, {
  'X-ZATCA-Branch': '3125678939',
  'X-ZATCA-Environment': 'production'
})
  .then(({ data }) => console.log(data))
  .catch(err => console.error(err));
import requests

url = "https://api.wafeq.com/v1/zatca/devices/register/"

payload = {
    "common_name": "abdallah-jeddah",
    "otp": "123456"
}
headers = {
    "accept": "application/json",
    "X-ZATCA-Branch": "3125678939",
    "X-ZATCA-Environment": "production",
    "content-type": "application/json",
    "Authorization": "Api-Key replace_with_your_api_key"
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
<?php

$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://api.wafeq.com/v1/zatca/devices/register/",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_HTTPHEADER => [
    "Authorization: Api-Key replace_with_your_api_key",
    "X-ZATCA-Branch: 3125678939",
    "X-ZATCA-Environment: production",
    "accept: application/json",
    "content-type: application/json"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}

You can then report documents from a specific Group VAT member by setting the X-ZATCA-Branch header to the TIN registered in the previous step.

Here is an example of a credit note reported from Abdallah Trading LLC Jeddah member whose TIN is 3125678939 :

curl --request POST \
     --url https://api.wafeq.com/v1/zatca/credit-notes/report/ \
     --header 'Authorization: Api-Key replace_with_your_api_key' \
     --header 'X-ZATCA-Branch: 3125678939' \
     --header 'X-ZATCA-Environment: production' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  // Body goes here
}
'
import sdk from '@api/wafeq-zatca';

sdk.auth('Api-Key replace_with_your_api_key');
sdk.credit_notes_report_create({

  // Body goes here

}, {
  'X-ZATCA-Branch': '3125678939',
  'X-ZATCA-Environment': 'production'
})
  .then(({ data }) => console.log(data))
  .catch(err => console.error(err));
import requests

url = "https://api.wafeq.com/v1/zatca/credit-notes/report/"

payload = {
   
  # Body goes here 
  
}
headers = {
    "accept": "application/json",
    "X-ZATCA-Branch": "3125678939",
    "X-ZATCA-Environment": "production",
    "content-type": "application/json",
    "Authorization": "Api-Key replace_with_your_api_key"
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.wafeq.com/v1/zatca/credit-notes/report/', [
  'body' => '{}', // Body goes here 
  'headers' => [
    'Authorization' => 'Api-Key replace_with_your_api_key',
    'X-ZATCA-Branch' => '3125678939',
    'X-ZATCA-Environment' => 'production',
    'accept' => 'application/json',
    'content-type' => 'application/json',
  ],
]);
}

echo $response->getBody();