Invoice API documentation
The Invoice Feed API allows merchants to upload invoice data in real-time or in bulk. Invoice data flows automatically and securely into Lovat, enabling businesses to generate, manage, and track invoices efficiently while maintaining compliance with tax regulations and accounting standards.
Terms and abbreviations
- API – Application Programming Interface. A set of calls provided by the system for integration with external software products.
- Merchant – The owner of an online store or business using the Lovat platform.
- Customer – An individual or business entity who purchases goods or services from the merchant.
- Invoice – A commercial document issued by a seller to a buyer, indicating the products, quantities, and agreed prices for products or services.
- Token – A secret string used by the system to identify the merchant and authenticate API requests.
- Line Item – Individual product or service entry in an invoice with quantity, unit price, and total.
Invoice data parameters
Parameter | Type/Example | Description | Validation |
invoice_number | String/”INV-2024-001″ | Unique invoice identifier | Optional. Maximum 255 characters |
customer_id | Integer/123 | Existing customer ID in system | Optional. Must exist in customer database |
customer_name | String/”Acme Corporation” | Customer business name | Required. Maximum 255 characters. Not empty |
customer_email | String/”contact@acme.com” | Customer email address | Optional. Must contain ‘@’ if provided |
customer_country | String/”USA” | Customer country code | Optional. ISO 3166-1 alpha-3 format (3 characters) |
customer_tax_number | String/”123456789″ | Customer tax/VAT number | Optional. Maximum 25 characters |
customer_address | String/”123 Business St” | Customer address | Optional. Maximum 255 characters |
invoice_date | String/”2024-01-15″ | Invoice creation date | Required. YYYY-MM-DD format |
due_date | String/”2024-02-15″ | Payment due date | Optional. YYYY-MM-DD format |
currency | String/”EUR” | Invoice currency | Optional. Default: “EUR”. Maximum 3 characters |
status | String/”draft” | Invoice status | Required. Values: “draft”, “pending”, “sent”, “paid” |
line_items | Array | List of invoice items | Required. At least one item required |
subtotal | Float/1000.00 | Sum before taxes and discounts | Required. Decimal with 2 places |
total_tax | Float/220.00 | Total tax amount | Required. Decimal with 2 places |
total | Float/1220.00 | Final invoice amount | Required. Decimal with 2 places |
total_discount_amount | Float/50.00 | Total discount amount | Required. Decimal with 2 places |
supplier_tax_number | String/”987654321″ | Supplier tax number | Optional. Maximum 25 characters |
supplier_country | String/”USA” | Supplier country code | Optional. ISO 3166-1 alpha-3 format |
Line item parameters
Parameter | Type/Example | Description | Validation |
description | String/”Web Development” | Item description | Required. Maximum 255 characters |
quantity | Float/2.0 | Item quantity | Required. Positive number |
unit_price | Float/500.00 | Price per unit | Required. Positive number |
is_taxable | Boolean/true | Whether item is taxable | Default: true |
API methods
1. Bulk invoice upload
- Description: Upload one or multiple invoices to the platform in a single request.
- Method: POST
- URL: https://invoice.vatcompliance.co/api/1/app/l_invoice/invoices/{access_token}
- Parameters:
Path parameters: access_token (required)
Body parameters: Array of invoice objects (JSON format)
Example requests
Bulk invoice upload
curl -X POST \\
"https://invoice.vatcompliance.co/api/1/app/l_invoice/invoices/your-access-token" \\
-H "Content-Type: application/json" \\
-d '[
{
"invoice_number": "INV-2024-001",
"customer_name": "Acme Corporation",
"customer_email": "contact@acme.com",
"customer_country": "USA",
"customer_tax_number": "123456789",
"customer_address": "123 Business Ave, New York, NY 10001",
"invoice_date": "2024-01-15",
"due_date": "2024-02-15",
"currency": "USD",
"status": "draft",
"line_items": [
{
"description": "Web Development Services",
"quantity": 40,
"unit_price": 75.00,
"tax": true
},
{
"description": "Domain Registration",
"quantity": 1,
"unit_price": 15.00,
"tax": false
}
],
"subtotal": 3015.00,
"total_tax": 663.30,
"total": 3678.30,
"total_discount_amount": 0.00,
"supplier_tax_number": "987654321",
"supplier_country": "USA"
},
{
"invoice_number": "INV-2024-002",
"customer_name": "Tech Solutions Ltd",
"customer_email": "info@techsolutions.com",
"customer_country": "GBR",
"customer_tax_number": "GB123456789",
"customer_address": "456 Tech Street, London, SW1A 1AA",
"invoice_date": "2024-01-16",
"due_date": "2024-02-16",
"currency": "EUR",
"status": "draft",
"line_items": [
{
"description": "Software License",
"quantity": 1,
"unit_price": 299.00,
"tax": true
}
],
"subtotal": 299.00,
"total_tax": 65.78,
"total": 364.78,
"total_discount_amount": 0.00,
"supplier_tax_number": "987654321",
"supplier_country": "USA"
}
]'
import requests
import json
url = "https://invoice.vatcompliance.co/api/1/app/l_invoice/invoices/your-access-token"
headers = {"Content-Type": "application/json"}
invoices = [
{
"invoice_number": "INV-2024-001",
"customer_name": "Acme Corporation",
"customer_email": "contact@acme.com",
"customer_country": "USA",
"customer_tax_number": "123456789",
"customer_address": "123 Business Ave, New York, NY 10001",
"invoice_date": "2024-01-15",
"due_date": "2024-02-15",
"currency": "USD",
"status": "draft",
"line_items": [
{
"description": "Web Development Services",
"quantity": 40,
"unit_price": 75.00,
"tax": True
},
{
"description": "Domain Registration",
"quantity": 1,
"unit_price": 15.00,
"tax": False
}
],
"subtotal": 3015.00,
"total_tax": 663.30,
"total": 3678.30,
"total_discount_amount": 0.00,
"supplier_tax_number": "987654321",
"supplier_country": "USA"
}
]
response = requests.post(url, headers=headers, data=json.dumps(invoices))
print(response.json())
require 'net/http'
require 'uri'
require 'json'
url = URI("https://invoice.vatcompliance.co/api/1/app/l_invoice/invoices/your-access-token")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
headers = { "Content-Type" => "application/json" }
invoices = [
{
"invoice_number" => "INV-2024-001",
"customer_name" => "Acme Corporation",
"customer_email" => "contact@acme.com",
"customer_country" => "USA",
"customer_tax_number" => "123456789",
"customer_address" => "123 Business Ave, New York, NY 10001",
"invoice_date" => "2024-01-15",
"due_date" => "2024-02-15",
"currency" => "USD",
"status" => "draft",
"line_items" => [
{
"description" => "Web Development Services",
"quantity" => 40,
"unit_price" => 75.00,
"tax" => true
},
{
"description" => "Domain Registration",
"quantity" => 1,
"unit_price" => 15.00,
"tax" => false
}
],
"subtotal" => 3015.00,
"total_tax" => 663.30,
"total" => 3678.30,
"total_discount_amount" => 0.00,
"supplier_tax_number" => "987654321",
"supplier_country" => "USA"
}
]
request = Net::HTTP::Post.new(url, headers)
request.body = invoices.to_json
response = http.request(request)
puts response.body
<?php
$url = "https://invoice.vatcompliance.co/api/1/app/l_invoice/invoices/your-access-token";
$invoices = [
[
"invoice_number" => "INV-2024-001",
"customer_name" => "Acme Corporation",
"customer_email" => "contact@acme.com",
"customer_country" => "USA",
"customer_tax_number" => "123456789",
"customer_address" => "123 Business Ave, New York, NY 10001",
"invoice_date" => "2024-01-15",
"due_date" => "2024-02-15",
"currency" => "USD",
"status" => "draft",
"line_items" => [
[
"description" => "Web Development Services",
"quantity" => 40,
"unit_price" => 75.00,
"tax" => true
],
[
"description" => "Domain Registration",
"quantity" => 1,
"unit_price" => 15.00,
"tax" => false
]
],
"subtotal" => 3015.00,
"total_tax" => 663.30,
"total" => 3678.30,
"total_discount_amount" => 0.00,
"supplier_tax_number" => "987654321",
"supplier_country" => "USA"
]
];
$options = [
"http" => [
"header" => "Content-Type: application/json\r\n",
"method" => "POST",
"content" => json_encode($invoices),
]
];
$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/invoices/your-access-token";
const invoices = [
{
invoice_number: "INV-2024-001",
customer_name: "Acme Corporation",
customer_email: "contact@acme.com",
customer_country: "USA",
customer_tax_number: "123456789",
customer_address: "123 Business Ave, New York, NY 10001",
invoice_date: "2024-01-15",
due_date: "2024-02-15",
currency: "USD",
status: "draft",
line_items: [
{
description: "Web Development Services",
quantity: 40,
unit_price: 75.00,
tax: true
},
{
description: "Domain Registration",
quantity: 1,
unit_price: 15.00,
tax: false
}
],
subtotal: 3015.00,
total_tax: 663.30,
total: 3678.30,
total_discount_amount: 0.00,
supplier_tax_number: "987654321",
supplier_country: "USA"
}
];
fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(invoices),
})
.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/invoices/your-access-token";
var client = new HttpClient();
var invoices = new[] {
new {
invoice_number = "INV-2024-001",
customer_name = "Acme Corporation",
customer_email = "contact@acme.com",
customer_country = "USA",
customer_tax_number = "123456789",
customer_address = "123 Business Ave, New York, NY 10001",
invoice_date = "2024-01-15",
due_date = "2024-02-15",
currency = "USD",
status = "draft",
line_items = new[] {
new {
description = "Web Development Services",
quantity = 40,
unit_price = 75.00,
tax = true
},
new {
description = "Domain Registration",
quantity = 1,
unit_price = 15.00,
tax = false
}
},
subtotal = 3015.00,
total_tax = 663.30,
total = 3678.30,
total_discount_amount = 0.00,
supplier_tax_number = "987654321",
supplier_country = "USA"
}
};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(invoices);
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 BulkInvoiceUpload {
public static void main(String[] args) throws Exception {
String url = "https://invoice.vatcompliance.co/api/1/app/l_invoice/invoices/your-access-token";
String json = "[{\\"invoice_number\\":\\"INV-2024-001\\",\\"customer_name\\":\\"Acme Corporation\\",\\"customer_email\\":\\"contact@acme.com\\",\\"customer_country\\":\\"USA\\",\\"customer_tax_number\\":\\"123456789\\",\\"customer_address\\":\\"123 Business Ave, New York, NY 10001\\",\\"invoice_date\\":\\"2024-01-15\\",\\"due_date\\":\\"2024-02-15\\",\\"currency\\":\\"USD\\",\\"status\\":\\"draft\\",\\"line_items\\":[{\\"description\\":\\"Web Development Services\\",\\"quantity\\":40,\\"unit_price\\":75.00,\\"tax\\":true},{\\"description\\":\\"Domain Registration\\",\\"quantity\\":1,\\"unit_price\\":15.00,\\"tax\\":false}],\\"subtotal\\":3015.00,\\"total_tax\\":663.30,\\"total\\":3678.30,\\"total_discount_amount\\":0.00,\\"supplier_tax_number\\":\\"987654321\\",\\"supplier_country\\":\\"USA\\"}]";
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/invoices/your-access-token"
invoices := []map[string]interface{}{
{
"invoice_number": "INV-2024-001",
"customer_name": "Acme Corporation",
"customer_email": "contact@acme.com",
"customer_country": "USA",
"customer_tax_number": "123456789",
"customer_address": "123 Business Ave, New York, NY 10001",
"invoice_date": "2024-01-15",
"due_date": "2024-02-15",
"currency": "USD",
"status": "draft",
"line_items": []map[string]interface{}{
{
"description": "Web Development Services",
"quantity": 40,
"unit_price": 75.00,
"tax": true,
},
{
"description": "Domain Registration",
"quantity": 1,
"unit_price": 15.00,
"tax": false,
},
},
"subtotal": 3015.00,
"total_tax": 663.30,
"total": 3678.30,
"total_discount_amount": 0.00,
"supplier_tax_number": "987654321",
"supplier_country": "USA",
},
}
body, _ := json.Marshal(invoices)
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
Invoice upload response
{
"status": "done",
"results": [
{
"index": 0,
"status": "success",
"invoice_id": 5290,
"invoice_number": "INV-2024-009",
"total": "3678.3"
}
]
}
2. Invoice update
- Description: Update an existing invoice by its unique identifier. Supports partial updates – only provided fields will be modified.
- Method: PUT
- URL: https://invoice.vatcompliance.co/api/1/app/l_invoice/invoices/{access_token}/{invoice_id}
- Parameters:
– Path parameters:
access_token (required) – Authentication token
invoice_id (required) – Unique invoice identifier
– Body parameters: Invoice update object (JSON format)
Example requests
Update invoice by ID
curl -X PUT \\
"https://invoice.vatcompliance.co/api/1/app/l_invoice/invoices/your-access-token/1234" \\
-H "Content-Type: application/json" \\
-d '{
"invoice_date": "2024-01-20",
"due_date": "2024-02-20",
"status": "sent",
"line_items": [
{
"description": "Updated Web Development Services",
"quantity": 45,
"unit_price": 80.00,
"tax": true
},
{
"description": "Additional Consulting",
"quantity": 5,
"unit_price": 100.00,
"tax": true
}
],
"subtotal": 4100.00,
"total_tax": 902.00,
"total": 5002.00,
"total_discount_amount": 0.00
}'
import requests
import json
url = "https://invoice.vatcompliance.co/api/1/app/l_invoice/invoices/your-access-token/1234"
headers = {"Content-Type": "application/json"}
update_data = {
"invoice_date": "2024-01-20",
"due_date": "2024-02-20",
"status": "sent",
"line_items": [
{
"description": "Updated Web Development Services",
"quantity": 45,
"unit_price": 80.00,
"tax": True
},
{
"description": "Additional Consulting",
"quantity": 5,
"unit_price": 100.00,
"tax": True
}
],
"subtotal": 4100.00,
"total_tax": 902.00,
"total": 5002.00,
"total_discount_amount": 0.00
}
response = requests.put(url, headers=headers, data=json.dumps(update_data))
print(response.json())
require 'net/http'
require 'uri'
require 'json'
url = URI("https://invoice.vatcompliance.co/api/1/app/l_invoice/invoices/your-access-token/1234")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
headers = { "Content-Type" => "application/json" }
update_data = {
"invoice_date" => "2024-01-20",
"due_date" => "2024-02-20",
"status" => "sent",
"line_items" => [
{
"description" => "Updated Web Development Services",
"quantity" => 45,
"unit_price" => 80.00,
"tax" => true
},
{
"description" => "Additional Consulting",
"quantity" => 5,
"unit_price" => 100.00,
"tax" => true
}
],
"subtotal" => 4100.00,
"total_tax" => 902.00,
"total" => 5002.00,
"total_discount_amount" => 0.00
}
request = Net::HTTP::Put.new(url, headers)
request.body = update_data.to_json
response = http.request(request)
puts response.body
<?php
$url = "https://invoice.vatcompliance.co/api/1/app/l_invoice/invoices/your-access-token/1234";
$update_data = [
"invoice_date" => "2024-01-20",
"due_date" => "2024-02-20",
"status" => "sent",
"line_items" => [
[
"description" => "Updated Web Development Services",
"quantity" => 45,
"unit_price" => 80.00,
"tax" => true
],
[
"description" => "Additional Consulting",
"quantity" => 5,
"unit_price" => 100.00,
"tax" => true
]
],
"subtotal" => 4100.00,
"total_tax" => 902.00,
"total" => 5002.00,
"total_discount_amount" => 0.00
];
$options = [
"http" => [
"header" => "Content-Type: application/json\r\n",
"method" => "PUT",
"content" => json_encode($update_data),
]
];
$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/invoices/your-access-token/1234";
const update_data = {
invoice_date: "2024-01-20",
due_date: "2024-02-20",
status: "sent",
line_items: [
{
description: "Updated Web Development Services",
quantity: 45,
unit_price: 80.00,
tax: true
},
{
description: "Additional Consulting",
quantity: 5,
unit_price: 100.00,
tax: true
}
],
subtotal: 4100.00,
total_tax: 902.00,
total: 5002.00,
total_discount_amount: 0.00
};
fetch(url, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(update_data),
})
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error("Error:", err));
.Net
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/invoices/your-access-token/1234";
var client = new HttpClient();
var update_data = new {
invoice_date = "2024-01-20",
due_date = "2024-02-20",
status = "sent",
line_items = new[] {
new {
description = "Updated Web Development Services",
quantity = 45,
unit_price = 80.00,
tax = true
},
new {
description = "Additional Consulting",
quantity = 5,
unit_price = 100.00,
tax = true
}
},
subtotal = 4100.00,
total_tax = 902.00,
total = 5002.00,
total_discount_amount = 0.00
};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(update_data);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PutAsync(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 UpdateInvoice {
public static void main(String[] args) throws Exception {
String url = "https://invoice.vatcompliance.co/api/1/app/l_invoice/invoices/your-access-token/1234";
String json = "{\\"invoice_date\\":\\"2024-01-20\\",\\"due_date\\":\\"2024-02-20\\",\\"status\\":\\"sent\\",\\"line_items\\":[{\\"description\\":\\"Updated Web Development Services\\",\\"quantity\\":45,\\"unit_price\\":80.00,\\"tax\\":true},{\\"description\\":\\"Additional Consulting\\",\\"quantity\\":5,\\"unit_price\\":100.00,\\"tax\\":true}],\\"subtotal\\":4100.00,\\"total_tax\\":902.00,\\"total\\":5002.00,\\"total_discount_amount\\":0.00}";
HttpClient client = HttpClient.newHttpClient();
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"
"encoding/json"
"fmt"
"net/http"
"io/ioutil"
)
func main() {
url := "https://invoice.vatcompliance.co/api/1/app/l_invoice/invoices/your-access-token/1234"
update_data := map[string]interface{}{
"invoice_date": "2024-01-20",
"due_date": "2024-02-20",
"status": "sent",
"line_items": []map[string]interface{}{
{
"description": "Updated Web Development Services",
"quantity": 45,
"unit_price": 80.00,
"tax": true,
},
{
"description": "Additional Consulting",
"quantity": 5,
"unit_price": 100.00,
"tax": true,
},
},
"subtotal": 4100.00,
"total_tax": 902.00,
"total": 5002.00,
"total_discount_amount": 0.00,
}
body, _ := json.Marshal(update_data)
req, _ := http.NewRequest("PUT", url, bytes.NewBuffer(body))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
responseData, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(responseData))
}
Example responses
Update invoice response
Success response
{
"status": 200,
"message": "Invoice 'INV-2024-001' (ID: 5289) updated successfully",
"invoice": {
"id": 5289,
"invoice_number": "INV-2024-001",
"customer_name": "Acme Corporation",
"total": "5002.0",
"currency": "USD",
"created_date": "2024-01-20",
"due_date": "2024-02-20"
}
}
Limitations and best practices
- Rate Limiting: Maximum 100 requests per minute per access token
- Partial Updates: Only provided fields will be updated, others remain unchanged
- Data Validation: All update data is validated before processing
- Line Items: If updating line items, must provide complete new list
- Date Format: All dates must be in YYYY-MM-DD format
- Decimal Precision: All monetary values support 2 decimal places