eliDocs
API Reference

Authentication

How to authenticate requests to the Beliq API using API keys.

All /v1/* endpoints require an API key. If a key is missing, the API returns 401 AUTHENTICATION_REQUIRED.

Obtaining an API key

Obtaining an API key

  1. Sign in to the Beliq dashboard
  2. Navigate to Integration → API Keys
  3. Click Create API Key and give it a descriptive label
  4. Copy the key immediately — it is only displayed once

API keys are stored securely in hashed form. Beliq does not store or log your plaintext key.

Passing the API key

Passing the API key

Use one of two methods:

Authorization: Bearer YOUR_API_KEY
import { Beliq } from '@beliq/sdk';

// `auth: 'bearer'` sends Authorization: Bearer instead of the default X-API-Key.
const beliq = new Beliq({ apiKey: process.env.BELIQ_API_KEY!, auth: 'bearer' });
import os

from beliq import Beliq

# auth="bearer" sends Authorization: Bearer instead of the default X-API-Key.
beliq = Beliq(api_key=os.environ["BELIQ_API_KEY"], auth="bearer")

X-API-Key header

X-API-Key: YOUR_API_KEY
import { Beliq } from '@beliq/sdk';

// X-API-Key is what the client sends unless you ask for `auth: 'bearer'`.
const beliq = new Beliq({ apiKey: process.env.BELIQ_API_KEY! });
import os

from beliq import Beliq

# X-API-Key is what the client sends unless you ask for auth="bearer".
beliq = Beliq(api_key=os.environ["BELIQ_API_KEY"])

Both methods work the same way. Use whichever is easier in your client.

Example request

Example request

validate.sh
curl -X POST https://api.beliq.eu/v1/validate \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/xml" \
  --data-binary @invoice.xml
import { readFile } from 'node:fs/promises';
import { Beliq } from '@beliq/sdk';

const beliq = new Beliq({ apiKey: process.env.BELIQ_API_KEY! });

const result = await beliq.validate(await readFile('invoice.xml'));

console.log(result.valid, result.format, result.schematronVersion);
import os
from pathlib import Path

from beliq import Beliq

beliq = Beliq(api_key=os.environ["BELIQ_API_KEY"])

result = beliq.validate(Path("invoice.xml").read_bytes())

print(result.valid, result.format, result.schematron_version)
Verifying a key

Verifying a key

GET /v1/me returns the account, plan, and live allowance for the calling key. It is a lightweight credential check that does not count against your monthly quota, so it is the right call for “is this key valid?” probes. The official connectors and SDKs use it to validate stored credentials.

me.sh
curl https://api.beliq.eu/v1/me \
  -H "Authorization: Bearer YOUR_API_KEY"
import { Beliq } from '@beliq/sdk';

const beliq = new Beliq({ apiKey: process.env.BELIQ_API_KEY! });

// `me()` is the credential check: it does not draw on your monthly quota.
const account = await beliq.me();

console.log(account.livemode, account.plan.name, account.quota.remaining);
import os

from beliq import Beliq

beliq = Beliq(api_key=os.environ["BELIQ_API_KEY"])

# me() is the credential check: it does not draw on your monthly quota.
account = beliq.me()

print(account.livemode, account.plan.name, account.quota.remaining)
Response
{
  "success": true,
  "data": {
    "keyId": "3f9c2a1b-8e4d-4c7a-9b21-5e0f7d8a6c31",
    "keyPrefix": "blq_live",
    "livemode": true,
    "org": {
      "id": "7b2e9d14-6a03-4f58-8c9e-2d1b4a7f0e63",
      "name": "Acme AG",
      "rulesetChannel": "latest"
    },
    "plan": { "id": 3, "name": "Growth" },
    "rateLimitPerMinute": 200,
    "quota": { "limit": 10000, "used": 1234, "remaining": 8766, "resetsAt": "2026-07-20T09:00:00.000Z" }
  }
}

quota describes the allowance the calling key spends, and livemode says which one that is. On a live key it is your plan quota, and resetsAt is the end of the current window: one month anchored on your billing day, so it falls on the 1st only if your subscription renews on the 1st. On a test key it is the sandbox allowance instead, on the UTC calendar month. Read resetsAt rather than assuming a month boundary. See test mode for what a blq_test_ key reads back.

keyPrefix is the first eight characters of the key, so it reads blq_live or blq_test and carries no key material: only a hash of the key itself is stored. keyId and the org id are UUIDs.

plan.name is never null. An account on the free tier references no plan record, so plan.id is null while plan.name is the free tier’s name. A 401 or 403 here means the key is missing, malformed, or revoked (see the table below).

Error responses

Error responses

HTTP Status Error Code Meaning
401 AUTHENTICATION_REQUIRED No API key was provided, or the key format is invalid
403 INVALID_API_KEY The API key does not exist or has been revoked
429 QUOTA_EXCEEDED Your monthly usage quota is exhausted — upgrade your plan
429 RATE_LIMITED Too many requests in the current rate-limit window — back off and retry
Quotas and rate limits

Quotas and rate limits

Beliq applies request limits to keep the service reliable and fair for all customers.

Throttle Window Source of truth 429 error code
Monthly quota One month anchored on your billing day subscriptionPlans.monthlyQuota (per plan) QUOTA_EXCEEDED
Sandbox allowance (test keys) Calendar month (UTC) Flat, independent of plan QUOTA_EXCEEDED
Per-minute burst Rolling 1-minute window Plan-based rate limit RATE_LIMITED
Abuse throttle Temporary protection window Beliq runtime ACCOUNT_THROTTLED

The two monthly windows do not line up: only an account billed on the 1st sees its plan quota reset when the sandbox allowance does. GET /v1/me reports the boundary that applies to the calling key.

Quota and rate limits are tracked per account. All API keys belonging to the same account share the same quota and burst limit.

Burst and sustained throughput

The per-minute figure is a burst allowance, not a sustained rate. You may spend the whole minute’s allowance at once, and Beliq queues what it cannot start immediately rather than rejecting it. Your sustained throughput is governed by your monthly quota.

The two are deliberately far apart, so it is worth being concrete: a Business plan allows 300 requests per minute against a quota of 20,000 documents per month. Sending 300 every minute would exhaust the month’s quota in about 67 minutes. Size your integration against the quota, and treat the per-minute figure as headroom for batches and spikes.

A queued request answers more slowly, which is normal and not an error. If a burst is large enough that Beliq cannot serve it inside the request deadline, you get a 503 with Retry-After and the document’s quota unit is not consumed, so retrying is free.

Plan changes mid-window: an upgrade raises the cap on your current window immediately, so the allowance you just paid for is usable the moment the payment lands. A downgrade does not shrink it: the current window keeps the allowance it was billed at, and the smaller one applies from the next window.

QUOTA_EXCEEDED includes your current usage in the message (for example "Monthly quota exceeded (1000/1000)"). Check usage in the dashboard or upgrade your plan.

Response headers

Header Set on Meaning
x-ratelimit-limit All /v1/* responses Your plan’s request limit for the current minute
x-ratelimit-remaining All /v1/* responses Burst budget left in the current minute
x-ratelimit-reset All /v1/* responses Seconds until the burst window resets
Retry-After All /v1/* 429 responses Seconds to wait before retrying. For RATE_LIMITED this is the seconds left in the burst window; for ACCOUNT_THROTTLED the seconds left in the throttle window, which can be several minutes; for QUOTA_EXCEEDED the seconds until your quota window rolls over (the same instant /v1/me reports as resetsAt), or until the next UTC calendar month for a test-mode key

Always honor Retry-After when present. It indicates the earliest safe retry time.

Prometheus metrics (operators)

When enabled for your deployment, GET /metrics may include a counter beliq_api_http_429_total labeled by throttle subtype (rate_limit_hit, quota_exhausted, abuse_throttle_hit, unknown), and a histogram beliq_api_http_request_duration_seconds (method, route) for request latency — useful for alerting and SLO dashboards.

Beliq also sends common browser hardening headers (for example X-Content-Type-Options, X-Frame-Options) on API responses; they do not replace your own security review for embedded contexts.

Default per-minute limits by plan

These are the default per-minute burst allowances by plan, alongside the sustained rate each plan’s monthly quota works out to.

PlanBurst (requests/minute)Monthly quotaSustained average
Free1020under 1/hour
Starter1002,000~3/hour
Growth20010,000~14/hour
Business30020,000~28/hour
Scale50050,000~69/hour

See pricing for what each plan costs.

Test mode uses its own, lower burst allowance. Keys prefixed blq_test_ are limited to 30 requests per minute regardless of plan, with a separate monthly allowance. See test mode.

Key management

Key management

  • Revoke a key at any time from the dashboard. Revoked keys return INVALID_API_KEY immediately.
  • Rotate keys by creating a new key, updating your integration, then revoking the old key.
  • Multiple keys are supported — use separate keys for different environments or services.