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 |
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