On this page

Customer API documentation

The Customer API allows merchants to upload customer data in real-time or in bulk. Customer data flows automatically and securely into Lovat, enabling businesses to manage their customer database efficiently and maintain accurate customer records for invoicing and compliance purposes.

Terms and abbreviations

  • API – Application Programming Interface. A set of calls provided by the system for integration with external software products.
  • Customer – An individual or business entity who purchases goods or services from the merchant.
  • Token – A secret string used by the system to identify the merchant and authenticate API requests.
  • Peppol – Pan-European Public Procurement On-Line, a network for electronic procurement.

 

Customer data parameters

Parameter Type/Example Description Validation
name String/“Acme Corp” Customer business name Required. Maximum 255 characters. Not empty
email String/“contact@acme.com” Customer email address Optional. Must contain ‘@’ if provided
country String/“USA” Customer country code Optional. ISO 3166-1 alpha-3 format (3 characters)
tax_number String/“123456789” Customer tax/VAT number Optional. Minimum 3 characters if provided
peppol_id String/“0192:123456789” Peppol identifier Optional. Maximum 25 characters
contact_person String/“John Doe” Primary contact person Optional. Maximum 75 characters
language String/“EN” Preferred language Optional. ISO 639-1 format (2 characters)
city String/“New York” Customer city Optional. Maximum 30 characters
state String/“NY” State/province Optional. Maximum 30 characters
address_line_1 String/“123 Main Street” Primary address line Optional. Maximum 75 characters
address_line_2 String/“Suite 100” Secondary address line Optional. Maximum 40 characters
postal_code String/“10001” Postal/ZIP code Optional. Maximum 12 characters
sending_method String/“Peppol” Document sending method Optional. Default: “Peppol”. Values: “Peppol”, “Email”

API methods

1. Bulk customer upload

  • Description: Upload one or multiple customers to the platform in a single request.
  • Method: POST
  • URL: https://invoice.vatcompliance.co/api/1/app/l_invoice/customers/{access_token}
  • Parameters:
    Path parameters: access_token (required)
    Body parameters: Array of customer objects (JSON format)

Example requests

Bulk customer upload


curl -X POST \
"https://invoice.vatcompliance.co/api/1/app/l_invoice/customers/your-access-token" \
  -H "Content-Type: application/json" \
  -d '[
    {
      "name": "Acme Corporation",
      "email": "contact@acme.com",
      "country": "USA",
      "tax_number": "123456789",
      "peppol_id": "0192:123456789",
      "contact_person": "John Smith",
      "language": "EN",
      "city": "New York",
      "state": "NY",
      "address_line_1": "123 Business Ave",
      "postal_code": "10001",
      "sending_method": "Peppol"
    },
    {
      "name": "Tech Solutions Ltd",
      "email": "info@techsolutions.com",
      "country": "GBR",
      "tax_number": "GB123456789",
      "contact_person": "Jane Doe",
      "language": "EN",
      "city": "London",
      "address_line_1": "456 Tech Street",
      "postal_code": "SW1A 1AA",
      "sending_method": "Email"
    }
  ]'



import requests
import json

Url = "https://invoice.vatcompliance.co/api/1/app/l_invoice/customers/your-access-token"
headers = {"Content-Type": "application/json"}

customers = [
    {
        "name": "Acme Corporation",
        "email": "contact@acme.com",
        "country": "USA",
        "tax_number": "123456789",
        "peppol_id": "0192:123456789",
        "contact_person": "John Smith",
        "language": "EN",
        "city": "New York",
        "state": "NY",
        "address_line_1": "123 Business Ave",
        "postal_code": "10001",
        "sending_method": "Peppol"
    }
]

response = requests.post(url, headers=headers, data=json.dumps(customers))
print(response.json())

require 'net/http'
require 'uri'
require 'json'

url = URI("https://invoice.vatcompliance.co/api/1/app/l_invoice/customers/your-access-token")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

headers = { "Content-Type" => "application/json" }

customers = [
  {
    "name" => "Acme Corporation",
    "email" => "contact@acme.com",
    "country" => "USA",
    "tax_number" => "123456789",
    "peppol_id" => "0192:123456789",
    "contact_person" => "John Smith",
    "language" => "EN",
    "city" => "New York",
    "state" => "NY",
    "address_line_1" => "123 Business Ave",
    "postal_code" => "10001",
    "sending_method" => "Peppol"
  }
]

request = Net::HTTP::Post.new(url, headers)
request.body = customers.to_json

response = http.request(request)
puts response.body

<?php $url = "https://invoice.vatcompliance.co/api/1/app/l_invoice/customers/your-access-token"; $customers = [     [         "name" => "Acme Corporation",
        "email" => "contact@acme.com",
        "country" => "USA",
        "tax_number" => "123456789",
        "peppol_id" => "0192:123456789",
        "contact_person" => "John Smith",
        "language" => "EN",
        "city" => "New York",
        "state" => "NY",
        "address_line_1" => "123 Business Ave",
        "postal_code" => "10001",
        "sending_method" => "Peppol"
    ]
];

$options = [
    "http" => [
        "header"  => "Content-Type: application/json\r\n",
        "method"  => "POST",
        "content" => json_encode($customers),
    ]
];

$context  = stream_context_create($options);
$result = file_get_contents($url, false, $context);

if ($result === FALSE) {
    die("Error sending request");
}

echo $result;

const fetch = require("node-fetch");

const url = "https://invoice.vatcompliance.co/api/1/app/l_invoice/customers/your-access-token";
const customers = [
  {
    name: "Acme Corporation",
    email: "contact@acme.com",
    country: "USA",
    tax_number: "123456789",
    peppol_id: "0192:123456789",
    contact_person: "John Smith",
    language: "EN",
    city: "New York",
    state: "NY",
    address_line_1: "123 Business Ave",
    postal_code: "10001",
    sending_method: "Peppol"
  }
];

fetch(url, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify(customers),
})
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error("Error:", err));


using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

class Program {
    static async Task Main() {
        var url = "https://invoice.vatcompliance.co/api/1/app/l_invoice/customers/your-access-token";
        var client = new HttpClient();

        var customers = new[] {
            new {
                name = "Acme Corporation",
                email = "contact@acme.com",
                country = "USA",
                tax_number = "123456789",
                peppol_id = "0192:123456789",
                contact_person = "John Smith",
                language = "EN",
                city = "New York",
                state = "NY",
                address_line_1 = "123 Business Ave",
                postal_code = "10001",
                sending_method = "Peppol"
            }
        };

        var json = Newtonsoft.Json.JsonConvert.SerializeObject(customers);
        var content = new StringContent(json, Encoding.UTF8, "application/json");

        var response = await client.PostAsync(url, content);
        string responseBody = await response.Content.ReadAsStringAsync();

        Console.WriteLine(responseBody);
    }
}

import java.net.http.*;
import java.net.URI;
import java.nio.charset.StandardCharsets;

public class BulkCustomerUpload {
    public static void main(String[] args) throws Exception {
        String url = "https://invoice.vatcompliance.co/api/1/app/l_invoice/customers/your-access-token";

        String json = "[{\"name\":\"Acme Corporation\",\"email\":\"contact@acme.com\",\"country\":\"USA\",\"tax_number\":\"123456789\",\"peppol_id\":\"0192:123456789\",\"contact_person\":\"John Smith\",\"language\":\"EN\",\"city\":\"New York\",\"state\":\"NY\",\"address_line_1\":\"123 Business Ave\",\"postal_code\":\"10001\",\"sending_method\":\"Peppol\"}]";

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(url))
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(json, StandardCharsets.UTF_8))
            .build();

        HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println(response.body());
    }
}

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "net/http"
    "io/ioutil"
)

func main() {
    url := "https://invoice.vatcompliance.co/api/1/app/l_invoice/customers/your-access-token"

    customers := []map[string]interface{}{
        {
            "name":           "Acme Corporation",
            "email":          "contact@acme.com",
            "country":        "USA",
            "tax_number":     "123456789",
            "peppol_id":      "0192:123456789",
            "contact_person": "John Smith",
            "language":       "EN",
            "city":           "New York",
            "state":          "NY",
            "address_line_1": "123 Business Ave",
            "postal_code":    "10001",
            "sending_method": "Peppol",
        },
    }

    body, _ := json.Marshal(customers)
    resp, err := http.Post(url, "application/json", bytes.NewBuffer(body))
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    responseData, _ := ioutil.ReadAll(resp.Body)
    fmt.Println(string(responseData))
}

Example response

Customer upload response


{
  "status": "done",
  "results": [
    {
      "status": 200,
      "customer_id": 1111,
      "customer_name": "Acme Corporation"
    }
  ]
}

2. Update Customer

  • Description: Update an existing customer’s information.
  • Method: PUT
  • URL:https://merchant.vatcompliance.co/api/app/l_invoice/customers/{access_token}/{customer_id}
  • Parameters:
    – Path parameters:
    access_token (required)
    customer_id (required)
    – Body parameters: Customer object (JSON format)

 

Customer update


curl -X PUT "https://invoice.vatcompliance.co/api/1/app/l_invoice/customers/{customer_id}/{access_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Updated Corp Ltd",
    "email": "updated@corp.com",
    "city": "Berlin",
    "country": "DEU",
    "tax_number": "DE123456789"
  }'


require 'net/http'
require 'uri'
require 'json'

url = URI("https://invoice.vatcompliance.co/api/1/app/l_invoice/customers/{customer_id}/{access_token}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Put.new(url, { "Content-Type" => "application/json" })
request.body = {
  name: "Updated Corp Ltd",
  email: "updated@corp.com",
  city: "Berlin",
  country: "DEU",
  tax_number: "DE123456789"
}.to_json

response = http.request(request)
puts response.read_body


import requests
import json

url = "https://invoice.vatcompliance.co/api/1/app/l_invoice/customers/{customer_id}/{access_token}"
headers = {"Content-Type": "application/json"}

payload = {
    "name": "Updated Corp Ltd",
    "email": "updated@corp.com",
    "city": "Berlin",
    "country": "DEU",
    "tax_number": "DE123456789"
}

response = requests.put(url, headers=headers, data=json.dumps(payload))
print(response.json())


<?php $url = "https://invoice.vatcompliance.co/api/1/app/l_invoice/customers/{customer_id}/{access_token}"; $data = [     "name" => "Updated Corp Ltd",
    "email" => "updated@corp.com",
    "city" => "Berlin",
    "country" => "DEU",
    "tax_number" => "DE123456789"
];

$options = [
    "http" => [
        "header"  => "Content-Type: application/json\r\n",
        "method"  => "PUT",
        "content" => json_encode($data),
    ],
];

$context  = stream_context_create($options);
$result = file_get_contents($url, false, $context);

if ($result === FALSE) {
    die("Error occurred");
}

echo $result;

const fetch = require("node-fetch");

const url = "https://invoice.vatcompliance.co/api/1/app/l_invoice/customers/{customer_id}/{access_token}";

const payload = {
  name: "Updated Corp Ltd",
  email: "updated@corp.com",
  city: "Berlin",
  country: "DEU",
  tax_number: "DE123456789"
};

fetch(url, {
  method: "PUT",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify(payload)
})
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error(err));
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

class Program {
    static async Task Main(string[] args) {
        var client = new HttpClient();
        var url = "https://invoice.vatcompliance.co/api/1/app/l_invoice/customers/{customer_id}/{access_token}";

        var payload = new {
            name = "Updated Corp Ltd",
            email = "updated@corp.com",
            city = "Berlin",
            country = "DEU",
            tax_number = "DE123456789"
        };

        var content = new StringContent(System.Text.Json.JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
        var response = await client.PutAsync(url, content);
        var result = await response.Content.ReadAsStringAsync();

        Console.WriteLine(result);
    }
}


import java.net.http.*;
import java.net.URI;
import java.nio.charset.StandardCharsets;

public class UpdateCustomer {
    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newHttpClient();
        String url = "https://invoice.vatcompliance.co/api/1/app/l_invoice/customers/{customer_id}/{access_token}";

        String json = """
        {
          "name": "Updated Corp Ltd",
          "email": "updated@corp.com",
          "city": "Berlin",
          "country": "DEU",
          "tax_number": "DE123456789"
        }
        """;

        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Content-Type", "application/json")
                .PUT(HttpRequest.BodyPublishers.ofString(json, StandardCharsets.UTF_8))
                .build();

        HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println(response.body());
    }
}

package main

import (
    "bytes"
    "fmt"
    "net/http"
    "io/ioutil"
)

func main() {
    url := "https://invoice.vatcompliance.co/api/1/app/l_invoice/customers/{customer_id}/{access_token}"

    payload := []byte(`{
        "name": "Updated Corp Ltd",
        "email": "updated@corp.com",
        "city": "Berlin",
        "country": "DEU",
        "tax_number": "DE123456789"
    }`)

    req, _ := http.NewRequest("PUT", url, bytes.NewBuffer(payload))
    req.Header.Set("Content-Type", "application/json")

    client := &http.Client{}
    res, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer res.Body.Close()

    body, _ := ioutil.ReadAll(res.Body)
    fmt.Println(string(body))
}

Customer update response


{
  "status": 200,
  "message": "Customer 'Acme Consulting' (ID: 3302) updated successfully",
  "customer": {
    "id": 3302,
    "name": "Acme Consulting Ltd",
    "email": "john.smith@acme-consulting.eu",
    "country": "DEU",
    "city": "Munich",
    "tax_number": "DE123456789"
  }
}

Rate limits and restrictions

  • Bulk Upload Limit: Maximum 100 customers per request
  • Request Frequency: No specific rate limit, but reasonable usage is expected
  • Token Validation: Access tokens are validated on each request
  • Data Validation: All customer data is validated before processing