LimeTip VATManage API keys

VAT API quickstart

From your first connection to a reliable integration.

Connect to the VAT API

Company keys use Bearer authentication. Keep your key on your server, never in browser code.

1. Create a company key

A company administrator can create a key in API access. Store the secret in your server environment as LIMETIP_API_KEY. Keys share your company’s credit allowance. Review it in Plan & credits.

Free includes 250 credits total. Pro and Business provide monthly credits shared by the company. For the one-time Free allowance, usage.interval is lifetime and usage.reset is null.

2. Check your connection for free

These commands use Bash with curl. The account request does not consume credits.

curl --fail-with-body 'https://vat.limetip.com/api/v1/account' \
  --header "Authorization: Bearer $LIMETIP_API_KEY"

A ready account includes your company’s shared balance, renewal date and country coverage. not_connected confirms authentication worked, but spending access is inactive. Ask your administrator to review the subscription in Plan & credits.

Example account response
{
  "status": "ready",
  "org_id": "org_example",
  "plan": "Example plan",
  "usage": {
    "used": 1,
    "reserved": 0,
    "limit": 100,
    "remaining": 99,
    "reset": "2026-10-01T00:00:00Z"
  },
  "capabilities": {
    "format": {
      "supported": true,
      "credits": 1,
      "countries": [
        "SE"
      ]
    },
    "registry": {
      "supported": true,
      "credits": 1,
      "countries": [
        "SE"
      ]
    },
    "lookup": {
      "supported": true,
      "credits": 1,
      "countries": [
        "SE"
      ]
    }
  }
}

3. Choose one operation

Each completed operation costs 1 credit, including an invalid number or a registration that was not found. Request errors, registry outages and completed-result replays are free.

VAT API operations
OperationUse it for
POST /checks, formatSyntax only. Does not verify checksums, registration or company identity.
POST /checks, registryRegistration plus company name and address when available.
POST /lookupsCompany lookup by VAT number. Includes the same registration and company details as a registry check.

You do not need to call registry validation and lookup for the same task. The first response already includes available company details. Check capabilities in your account for supported countries. The examples use an illustrative number, not a verified business.

The following request uses 1 credit if completed. LimeTip creates an operation ID and returns it with the result.

curl --fail-with-body --max-time 60 --request POST 'https://vat.limetip.com/api/v1/checks' \
  --header "Authorization: Bearer $LIMETIP_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{"mode":"registry","vat_number":"SE123456789001"}'
Use company lookup instead

Do not follow a registry check with this call unless you want another paid operation.

curl --fail-with-body --max-time 60 --request POST 'https://vat.limetip.com/api/v1/lookups' \
  --header "Authorization: Bearer $LIMETIP_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{"vat_number":"SE123456789001"}'

4. Read the result

Example check response
{
  "operation_id": "123e4567-e89b-42d3-a456-426614174000",
  "result": {
    "mode": "registry",
    "vat_number": "SE123456789001",
    "country_code": "SE",
    "format_valid": true,
    "checksum_checked": false,
    "registration_status": "valid",
    "company_name": null,
    "address": null,
    "provider": "VIES",
    "checked_at": "2026-09-19T12:00:00Z"
  },
  "charged_credits": 1,
  "replayed": false,
  "account": {
    "status": "ready",
    "org_id": "org_example",
    "plan": "Example plan",
    "usage": {
      "used": 1,
      "reserved": 0,
      "limit": 100,
      "remaining": 99,
      "reset": "2026-10-01T00:00:00Z"
    },
    "capabilities": {
      "format": {
        "supported": true,
        "credits": 1,
        "countries": [
          "SE"
        ]
      },
      "registry": {
        "supported": true,
        "credits": 1,
        "countries": [
          "SE"
        ]
      },
      "lookup": {
        "supported": true,
        "credits": 1,
        "countries": [
          "SE"
        ]
      }
    }
  }
}

HTTP 200 means the operation completed. Only registration_status: "valid" confirms registration. invalid means the registry did not confirm an active registration; not_checked means no registry answer was obtained. format_valid: true alone is not registration proof. Company name and address can be null even for a valid registration.

The response includes operation_id for history and support. The downloadable clients below create an ID once and reuse it automatically across temporary failures.

Add durable retry recovery

A raw HTTP client cannot recover a completed result when the entire response is lost unless it chose an ID before sending. Queue workers and other durable jobs can generate and save one UUID, then send it as Idempotency-Key. Reuse the same API key, ID and body on every retry. A saved result returns replayed: true and charged_credits: 0.

OPERATION_ID=$(uuidgen)
# Save this ID with your job. Reuse it unchanged on retries.
printf '%s\n' "$OPERATION_ID"
curl --fail-with-body --max-time 60 --request POST 'https://vat.limetip.com/api/v1/checks' \
+  --header "Authorization: Bearer $LIMETIP_API_KEY" \
  --header 'Content-Type: application/json' \
  --header "Idempotency-Key: $OPERATION_ID" \
+  --data '{"mode":"registry","vat_number":"SE123456789001"}'
401
Missing, invalid, expired or revoked key. Check the key’s lifecycle before retrying.
402
No credits available. Ask your administrator to upgrade your plan, or wait for renewal on a paid plan. Free credits do not refill.
403
Access inactive or permission missing. Check error.code and account status.
409
A supplied idempotency key belongs to different input or another credential. Recover the original request before creating a new paid operation.
422
Fix input or unsupported coverage. Validation errors include field locations in detail.
429
Too many concurrent company checks. Respect Retry-After and retry the original operation.
503
A service is temporarily unavailable. Downloadable clients retry with the same generated ID. Raw HTTP callers that need the same guarantee should use the optional idempotency header above.

Use error.code for program logic, not message text. Older validation responses may have only a detail array and HTTP errors a message. Keep the X-Request-ID response header when contacting support; never send your API secret.

Test your integration without spending credits

Use the integration kit with deterministic local fixtures. It includes valid, invalid, missing-company-details, no-credit and outage responses, plus a connection dropped after completion to test safe retries. The mock uses fictional data and never contacts a registry.

Run the mock with Node 22.18+ on your own device, and use a dummy key. Keep production and mock configuration separate. These are tested examples, not a hosted sandbox or an SDK.

Concurrency and timeouts

Up to 10 checks per company can run at once across all keys and web users. Additional requests receive 429 concurrency_limit and a Retry-After delay in seconds. Use a 60-second client timeout and bounded exponential backoff, keeping the same operation ID.

usage.used counts completed operations. usage.reserved counts credits temporarily held for checks in progress. usage.remaining excludes both. Failures release reservations; abandoned holds expire within 60 seconds. An accepted check belongs to the UTC month when it started, even if it finishes after renewal.

A completed result can be returned with an inactive account after access expires. Display the result; inactive access prevents new spending. A saved result remains recoverable with the same authenticated credential and operation ID.

Read history and attribute credit use

History & usage lets company members reopen results and export a ledger without spending credits. API reporting keys need the explicit vat:history permission. Read-account-only keys cannot access saved company details. Existing keys keep their original permissions.

Use GET /api/v1/history for saved checks, GET /api/v1/history/{check_id} for one result, GET /api/v1/usage for totals by day, actor and operation, and GET /api/v1/history/export for CSV. All are free. Filter with inclusive UTC completion dates since and until, an optional mode or exact actor_id. Follow next_cursor for history pages. Exports are capped at 10,000 checks; reduce the date range if the selection is larger.

Rotate keys without losing pending requests

  1. Create a replacement key and save it securely.
  2. Deploy it for new operations.
  3. Finish pending retries using the original key and operation IDs.
  4. Revoke the old key once no requests need it.

If a key is compromised, revoke it immediately and contact support about unresolved requests. A replacement credential cannot replay an old credential’s operation.