Skip to content

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. 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. 2 · Your backend calls

    Send it as Authorization: Bearer. No browser, no MCP client. The person approves; the backend or agent runs.

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