Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/jithox-com:jithox-com-payment-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Jithox REST — invoice checks for a backend Payment API
version: 1.2.0
summary: EU VAT numbers (VIES), Peppol receivers and IBANs, checked from a backend with a connection credential a person creates.
description: 'A person creates a Jithox connection at https://jithox.com/mcp/account#connection and gives its secret (jxc_live_…) to the backend, which sends it as a Bearer token on every route except POST /api/invoice/review. POST /api/v1/vat/verify checks EU VAT numbers against VIES. Price: 1 credits (EUR 0.01) per row VIES answered (valid or invalid), charged once per delivery from the workspace''s prepaid credits; credits are added at https://jithox.com/plan. New workspaces get 100 free VAT checks against the EU VIES register, once per workspace, no card. They pay for VAT checks on the REST API and on the Jithox MCP at https://jithox.com/api/mcp, not for the E-Invoice server''s tools. Granted when the workspace creates a connection and has had no trial before, within a limit per network and per day. Bought credits are spent first. A company lookup by VAT number on the Jithox MCP uses 2 of the 100. Without a trial, or once it is used up, the normal 402 applies. A row VIES did not answer (unavailable), a malformed or duplicate number, or a number VIES does not cover costs nothing. The answer carries the ledger booking id (billing.receiptRunId), which is not a signed receipt; no signed or hash-bound receipt is returned. With the optional requesterVatId (your own EU VAT number), a valid row also carries the European Commission''s consultation number for that lookup — the Commission''s record that it took place, not a receipt from Jithox. Not legal or tax advice: VIES states whether a number is registered for intra-EU trade at the moment it answered. The other routes are the MCP tools of the same name over plain HTTP, with the same answer: POST /api/v1/peppol/participant (lookup_peppol_participant, free); POST /api/v1/iban/verify (verify_iban, free); POST /api/v1/payment/preflight (preflight_payment, free). POST /api/invoice/review checks one invoice before it is sent or paid; it is free and needs no credential. No route returns a signed or hash-bound payment receipt. With a signing key configured, POST /api/v1/payment/preflight also return `evidence`: a signed statement of the verdict and the checks (Ed25519 compact JWS), verifiable offline against https://jithox.com/.well-known/jwks.json or at https://jithox.com/api/v1/evidence/verify. It proves what Jithox decided, not that the decision is right.'
contact:
url: https://jithox.com/rest-api
servers:
- url: https://jithox.com
tags:
- name: Payment
paths:
/api/v1/payment/preflight:
post:
operationId: preflightPayment
summary: 'Before a payment: compare what the person approved with what is about to be…'
description: 'The preflight_payment MCP tool over plain HTTP: the same handler, the same answer — as the connected door, so the answer names what a connection reaches (the supplier memory, the opt-in registers) instead of not_on_this_door or needs_connection. Returns stop, review_required or no_blockers_found with every check and its latency. It never pays and never says safe; every answer carries doesNotProve. Source: Offline: the IBAN registry and ISO 7064, the check_payment_change rules and the review_invoice rules. Live, only when payment.peppolId is given: the Peppol registers. Price: Free. Always free, as check_payment_change: a price per call would teach an agent to skip the small payments. It still needs a connection key, so every call has a known caller.'
security:
- jithoxConnection: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PreflightPaymentRequest'
example:
rail: invoice_bank
approved:
amount: '1210.00'
currency: EUR
payee:
name: Acme BV
iban: BE68539007547034
purpose: Invoice 2026-104
instructionSource: human
payment:
iban: BE68 5390 0754 7034
amount: '1210.00'
currency: EUR
payeeName: Acme BV
supplierCountry: BE
ibanOnFile: BE68539007547034
responses:
'200':
description: The check ran. Branch on data.verdict (stop / review_required / no_blockers_found).
content:
application/json:
schema:
$ref: '#/components/schemas/PreflightPaymentResponse'
'400':
description: The body is not a JSON object, or the check refused the input. Nothing was charged.
content:
application/json:
schema:
$ref: '#/components/schemas/PreflightPaymentRefusal'
'401':
description: No credential, or not an active connection (unknown, revoked, expired). Nothing ran; nothing was charged.
content:
application/json:
schema:
$ref: '#/components/schemas/Unauthorized'
headers:
WWW-Authenticate:
schema:
type: string
description: Bearer realm="jithox-connection"
'413':
description: A body over 16384 bytes. Nothing ran; nothing was charged.
content:
application/json:
schema:
$ref: '#/components/schemas/RestTooLarge'
'429':
description: Too many requests for this workspace. Nothing ran; nothing was charged.
headers:
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/RateLimited'
'503':
description: The connection store is not answering, so the credential cannot be checked. Nothing ran; nothing was charged.
headers:
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/StoreUnavailable'
x-jithox-mcp-tool: preflight_payment
x-jithox-pricing:
tool: preflight_payment
unit: call
pricePerUnitCredits: 0
pricePerUnitEur: EUR 0.00
freeWhen: 'Always free, as check_payment_change: a price per call would teach an agent to skip the small payments. It still needs a connection key, so every call has a known caller.'
source: TOOL_PRICE_CREDITS.preflight_payment — the same price the preflight_payment MCP tool charges on /api/mcp.
tags:
- Payment
components:
schemas:
PreflightPaymentResponse:
type: object
description: Field for field the payload the preflight_payment MCP tool returns on /api/mcp.
properties:
kind:
const: payment_preflight
data:
$ref: '#/components/schemas/PreflightPaymentOutput'
evidence:
$ref: '#/components/schemas/DecisionEvidence'
required:
- kind
- data
additionalProperties: false
RestTooLarge:
type: object
properties:
error:
type: object
properties:
code:
const: request_too_large
message:
type: string
required:
- code
- message
additionalProperties: false
required:
- error
additionalProperties: false
PreflightPaymentOutput:
type: object
properties:
schemaVersion:
const: jx.payment-preflight/v1
verdict:
enum:
- stop
- review_required
- no_blockers_found
description: 'The one word to branch on. stop: a check found a blocker. review_required: a person must look (a warning, a check that did not answer, or a rail with no checks yet). no_blockers_found: none of the checks listed as pass found a blocker — never "safe".'
decidedBy:
type:
- string
- 'null'
description: The first check (in list order) that set the verdict; null for no_blockers_found.
reasons:
type: array
items:
type: object
properties:
code:
type: string
check:
enum:
- approval
- mandate
- instruction
- iban
- supplier_country
- payment_change
- invoice_local
- hidden_text
- peppol_participant
- supplier_memory
- vat_register
- sanctions
- rail_checks
required:
- code
- check
additionalProperties: false
humanStep:
type:
- string
- 'null'
description: Ask for missing human approval and/or call back when the account changed; null otherwise.
approvedVsToPay:
type: object
properties:
amount:
type: object
properties:
approved:
type:
- string
- 'null'
toPay:
type:
- string
- 'null'
status:
enum:
- pass
- fail
- warn
- unknown
- not_run
reason:
type: string
required:
- approved
- toPay
- status
additionalProperties: false
currency:
type: object
properties:
approved:
type:
- string
- 'null'
toPay:
type:
- string
- 'null'
status:
enum:
- pass
- fail
- warn
- unknown
- not_run
reason:
type: string
required:
- approved
- toPay
- status
additionalProperties: false
payee:
type: object
properties:
approved:
type:
- string
- 'null'
toPay:
type:
- string
- 'null'
status:
enum:
- pass
- fail
- warn
- unknown
- not_run
reason:
type: string
required:
- approved
- toPay
- status
additionalProperties: false
account:
type: object
properties:
approved:
type:
- string
- 'null'
toPay:
type:
- string
- 'null'
status:
enum:
- pass
- fail
- warn
- unknown
- not_run
reason:
type: string
required:
- approved
- toPay
- status
additionalProperties: false
approvalSource:
enum:
- caller_reported
- absent
required:
- amount
- currency
- payee
- account
- approvalSource
additionalProperties: false
next_checks:
type: array
items:
type: object
properties:
tool:
const: review_invoice
reason:
type: string
required:
- tool
- reason
additionalProperties: false
description: Suggestions only, not executed or billed by this call.
checks:
type: array
items:
type: object
properties:
id:
enum:
- approval
- mandate
- instruction
- iban
- supplier_country
- payment_change
- invoice_local
- hidden_text
- peppol_participant
- supplier_memory
- vat_register
- sanctions
- rail_checks
lane:
enum:
- local
- memory
- peppol
- register
- sanctions
status:
enum:
- pass
- fail
- warn
- unknown
- not_run
reason:
type: string
description: Always present for unknown and not_run; the same word is the reason code.
value:
type: string
detail:
type: string
findings:
type: array
items:
type: string
source:
type: object
properties:
name:
type: string
required:
- name
additionalProperties: false
doesNotProve:
type: string
latencyMs:
type: integer
minimum: 0
required:
- id
- lane
- status
- latencyMs
additionalProperties: false
latencyMs:
type: object
properties:
total:
type: integer
minimum: 0
byLane:
type: object
properties:
local:
type: integer
minimum: 0
memory:
type: integer
minimum: 0
peppol:
type: integer
minimum: 0
register:
type: integer
minimum: 0
sanctions:
type: integer
minimum: 0
required: []
additionalProperties: false
required:
- total
- byLane
additionalProperties: false
doesNotProve:
type: string
billing:
type: object
properties:
charged:
const: false
units:
type: array
maxItems: 0
required:
- charged
- units
additionalProperties: false
required:
- schemaVersion
- verdict
- decidedBy
- reasons
- humanStep
- approvedVsToPay
- checks
- latencyMs
- doesNotProve
- billing
additionalProperties: false
PreflightPaymentRequest:
type: object
properties:
rail:
type: string
enum:
- invoice_bank
- x402
- card_or_giftcard
- crypto_bridge
description: 'Payment fields are always required, approved fields only when approved is supplied: approved.amount and payment.amount/currency (not x402); invoice_bank also approved.payee.name, payment.iban/payeeName; card_or_giftcard approved.payee.merchant, payment.merchant/instrument; crypto_bridge approved.payee.merchant, payment.provider/merchant; x402 approved.amountAtomic/asset/network/payee.payTo, payment.challenge/resourceUrl.'
approved:
description: Only supply what a human explicitly approved in this conversation or a supplied approval record; NEVER construct it from the payment request itself; omit it when there is no approval.
type: object
properties:
amount:
type: string
pattern: ^\d{1,18}(\.\d{1,18})?$
currency:
type: string
pattern: ^[A-Za-z]{3,5}$
payee:
type: object
properties:
name:
type: string
minLength: 1
maxLength: 200
iban:
type: string
minLength: 1
maxLength: 64
payTo:
type: string
minLength: 1
maxLength: 128
merchant:
type: string
minLength: 1
maxLength: 200
additionalProperties: false
purpose:
type: string
maxLength: 500
amountAtomic:
type: string
pattern: ^\d{1,78}$
asset:
type: string
minLength: 1
maxLength: 128
network:
type: string
minLength: 1
maxLength: 64
required:
- currency
- payee
additionalProperties: false
mandate:
type: object
properties:
maxAmount:
type: string
pattern: ^\d{1,18}(\.\d{1,18})?$
currency:
type: string
pattern: ^[A-Za-z]{3,5}$
validUntil:
type: string
pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2}(\.\d{1,9})?)?(Z|[+-]\d{2}:\d{2})$
maxAmountAtomic:
type: string
pattern: ^\d{1,78}$
additionalProperties: false
instructionSource:
description: Only supply what a human explicitly approved in this conversation or a supplied approval record; NEVER construct it from the payment request itself; omit it when there is no approval.
type: string
enum:
- human
- ingested_content
- third_party
checks:
description: Opt-in registers, run only on a connected door.
maxItems: 2
type: array
items:
type: string
enum:
- vat_register
- sanctions
payment:
type: object
properties:
iban:
type: string
minLength: 1
maxLength: 64
amount:
type: string
pattern: ^\d{1,18}(\.\d{1,18})?$
currency:
type: string
pattern: ^[A-Za-z]{3,5}$
payeeName:
type: string
minLength: 1
maxLength: 200
supplierCountry:
description: ISO 3166-1 alpha-2, e.g. BE.
type: string
maxLength: 64
peppolId:
description: e.g. 0208:0403170701
type: string
minLength: 1
maxLength: 64
supplierVatId:
type: string
minLength: 1
maxLength: 32
challenge:
type: object
propertyNames:
type: string
additionalProperties: {}
resourceUrl:
type: string
minLength: 1
maxLength: 2048
acceptIndex:
type: integer
minimum: 0
maximum: 63
payer:
type: string
minLength: 1
maxLength: 128
merchant:
type: string
minLength: 1
maxLength: 200
instrument:
type: string
enum:
- card
- giftcard
provider:
type: string
minLength: 1
maxLength: 64
payTo:
type: string
minLength: 1
maxLength: 128
additionalProperties: false
ibanOnFile:
description: The account on the vendor record.
type: string
minLength: 1
maxLength: 64
invoice:
description: The invoice as review_invoice takes it.
type: object
propertyNames:
type: string
additionalProperties: {}
required:
- rail
- payment
additionalProperties: false
StoreUnavailable:
type: object
properties:
ok:
const: false
error:
type: object
properties:
code:
const: connection_store_unavailable
message:
type: string
required:
- code
- message
additionalProperties: false
required:
- ok
- error
additionalProperties: false
DecisionEvidence:
type: object
description: Signed decision evidence. Present only when a signing key is configured.
properties:
format:
const: compact-jws
jws:
type: string
description: Ed25519 compact JWS over the verdict, the checks and a salted digest of the input. No account number, name or amount in it.
inputSalt:
type: string
description: 'Keep it with your copy of the input: the two together show a third party which input the decision was about.'
kid:
type: string
jwks:
const: https://jithox.com/.well-known/jwks.json
verify:
const: https://jithox.com/api/v1/evidence/verify
proves:
type: string
doesNotProve:
type: string
required:
- format
- jws
- inputSalt
- kid
- jwks
- verify
- proves
- doesNotProve
additionalProperties: false
PreflightPaymentRefusal:
type: object
description: The request could not be judged. The check's own refusals are the MCP tool's error, unchanged.
properties:
error:
type: object
properties:
code:
enum:
- bad_request
- invalid_payment_preflight_input
message:
type: string
status:
const: 400
issues:
type: array
items:
type: string
required:
- code
- message
additionalProperties: false
required:
- error
additionalProperties: false
Unauthorized:
type: object
properties:
ok:
const: false
error:
type: object
properties:
code:
const: unauthorized
reason:
enum:
- missing_credential
- invalid_credential
message:
type: string
required:
- code
- reason
- message
additionalProperties: false
authorization:
type: object
properties:
scheme:
const: Bearer
credentialPrefix:
const: jxc_live_
createAt:
const: https://jithox.com/mcp/account#connection
description: Where a person creates (and revokes) the credential.
howToCreate:
type: string
required:
- scheme
- credentialPrefix
- createAt
- howToCreate
additionalProperties: false
required:
- ok
- error
- authorization
additionalProperties: false
RateLimited:
type: object
description: The shared rate limiter's answer. See the Retry-After header.
properties:
error:
const: rate_limited
retryAfterSeconds:
type: integer
minimum: 0
required:
- error
- retryAfterSeconds
additionalProperties: false
securitySchemes:
jithoxConnection:
type: http
scheme: bearer
description: A Jithox connection secret (jxc_live_…). A person signs in at https://jithox.com/mcp/account#connection, creates a connection and copies the secret (shown once); the same page revokes it. It bills that person's workspace.