REST API Labs
Check EU VAT numbers from your backend, over plain HTTP
One route: POST /api/v1/vat/verify. Send up to 20 VAT numbers; each row comes back valid, invalid or unavailable from the EU VIES register. This is the only REST route today — everything else is MCP.
Labs. The route is tested in our suite; it has not yet run against the real register on this website, and nobody has been charged through it.
1 · A person creates the key
Sign in, open Account → Connection, create a connection and copy its secret (
jxc_live_…, shown once). The same page revokes it.2 · Your backend calls
Send it as
Authorization: Bearer. No browser, no MCP client. The person approves; the backend or agent runs.3 · You pay per answer
2 credits (EUR 0.02) for each row VIES answered. A row VIES did not answer (down, busy, timed out) costs 0 and is listed for a retry.
curl
curl -s -X POST https://jithox.com/api/v1/vat/verify \
-H "authorization: Bearer $JITHOX_CONNECTION_SECRET" \
-H 'content-type: application/json' \
-H 'x-jithox-idempotency-key: invoice-2026-0917-C-001' \
-d '{"rows":[{"reference":"C-001","vatId":"BE0403170701"}]}'C# (.NET 8, HttpClient)
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
// Het verbindingsgeheim (jxc_live_…) dat een mens aanmaakte op https://jithox.com/mcp/account#connection
var secret = Environment.GetEnvironmentVariable("JITHOX_CONNECTION_SECRET")
?? throw new InvalidOperationException("Set JITHOX_CONNECTION_SECRET");
using var http = new HttpClient { BaseAddress = new Uri("https://jithox.com"), Timeout = TimeSpan.FromSeconds(60) };
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", secret);
using var request = new HttpRequestMessage(HttpMethod.Post, "/api/v1/vat/verify")
{
Content = JsonContent.Create(new { rows = new[] { new { reference = "C-001", vatId = "BE0403170701" } } }),
};
// Optioneel: dezelfde sleutel met dezelfde rijen wordt één keer afgerekend.
request.Headers.Add("x-jithox-idempotency-key", "invoice-2026-0917-C-001");
using var response = await http.SendAsync(request);
using var doc = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
var root = doc.RootElement;
switch ((int)response.StatusCode)
{
case 200:
foreach (var row in root.GetProperty("result").GetProperty("rows").EnumerateArray())
{
var verdict = row.GetProperty("verdict").GetString(); // valid | invalid | unavailable | not_checked
Console.WriteLine($"{row.GetProperty("input").GetString()}: {verdict} — {row.GetProperty("detail").GetString()}");
// "unavailable" is een VIES-storing, geen oordeel over het nummer: later opnieuw sturen, het kostte niets.
}
var billing = root.GetProperty("billing");
Console.WriteLine($"credits: {billing.GetProperty("credits").GetInt32()} (ledger ref, geen receipt: " +
$"{(billing.TryGetProperty("receiptRunId", out var r) ? r.GetString() : "-")})");
break;
case 401: // geen of ongeldig geheim — een mens maakt er een op authorization.createAt
Console.WriteLine(root.GetProperty("authorization").GetProperty("createAt").GetString());
break;
case 402: // te weinig credits — een mens vult aan op error.topUpUrl
Console.WriteLine(root.GetProperty("error").GetProperty("topUpUrl").GetString());
break;
case 403: // grens per aanroep op deze verbinding — minder rijen sturen of de grens verhogen
case 429: // rate limit — wacht Retry-After seconden
case 503: // verbindingsopslag antwoordt niet — wacht Retry-After seconden
default:
Console.WriteLine($"{(int)response.StatusCode} {root}");
break;
}Credits are prepaid on the account (1 credit = 1 euro cent). Without enough, the call answers 402 with the top-up link and VIES is not asked. Every status code and field: openapi.json.
Building an AI agent instead?
Use MCP: https://jithox.com/api/mcp. The tool check_vat_list runs the same check at the same price; check_vat_list_format checks only the format, free, without a key. Connect your AI
What it is not
- Not a Peppol Access Point. It sends no invoices.
- No tax advice: it reports what VIES says.
- No signed receipt; the answer carries a ledger reference only.