# IBAN & EU VAT Validator: VIES, Peppol, Invoice Fraud Check (`lerider/payee-check`) Actor

Validate IBANs and EU VAT numbers (live VIES) and catch bank-change invoice fraud before you pay a supplier. Adds Peppol lookup, invoice VAT maths and SEPA date. ALLOW / REVIEW / BLOCK verdict with reasons, for AP automation and AI payment agents.

- **URL**: https://apify.com/lerider/payee-check.md
- **Developed by:** [Lerider Technologies](https://apify.com/lerider) (community)
- **Categories:** Business, Developer tools, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 payee checks

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## IBAN & EU VAT Validator: VIES, Peppol, Invoice Fraud Check

Validate IBANs and EU VAT numbers (live VIES) and catch bank-change invoice fraud before you pay a supplier.
Built for accounts-payable automation and AI payment agents. Each check returns one verdict, `ALLOW`, `REVIEW` or
`BLOCK`, together with the reasons for it.

Typical uses: IBAN validation, EU VAT number validation (VIES), Peppol participant lookup, supplier verification
before onboarding, and spotting business email compromise (BEC) where a known supplier suddenly sends a new IBAN.

| Event | Price | What it does |
|---|---|---|
| `payee-check` | $0.001 | Offline IBAN check: checksum, Dutch bank code, a known payee asking for a new IBAN, invoice IBAN mismatch, pressure and bank-change language |
| `supplier-preflight` | $0.03 | Everything `payee-check` does, plus a **live EU VAT id check (VIES)**, a **Peppol Directory lookup**, **invoice VAT arithmetic** with reverse-charge checks, and the **SEPA settlement date** |
| `attested-check` | $0.02 | Optional add-on (`"attest": true`) for either check: a **timestamped evidence record** of the input, verdict and rule version, so you can later prove the check was done before you paid |

The input picks the event. A request with `iban` or `payments` runs `payee-check`. A request with `payee` or
`preflights` runs `supplier-preflight`. Don't mix the two in one run. Add `"attest": true` to either one to get
an [attested verdict](#attested-verdicts-proof-that-you-checked-before-you-paid).

### Supplier pre-flight: "before I pay or onboard this supplier, is anything wrong?"

#### Input

Only `payee.iban` is required. Every other field you add switches on more checks.

```json
{
  "payee": {"name": "Jansen Bouw B.V.", "iban": "NL91ABNA0417164300",
            "vat_id": "NL123456789B01", "peppol_id": "0106:12345678"},
  "invoice": {"text": "Factuur 2026-118 Jansen Bouw B.V., btw-id NL123456789B01. Totaal EUR 121,00. IBAN NL91 ABNA 0417 1643 00.",
              "lines": [{"net": 100.0, "vat_rate": 21}],
              "total_net": 100.0, "total_vat": 21.0, "total_gross": 121.0,
              "buyer_vat_id": "BE0123456789", "issue_date": "2026-10-20"},
  "known_payees": [{"name": "Jansen Bouw BV", "iban": "NL02RABO0123456789"}],
  "pay_on": "2026-12-25"
}
```

- Amounts can be JSON numbers or decimal strings, with at most 2 decimals. Negative amounts are allowed for credit
  notes. `vat_rate` is a percentage. Lines may also carry their own `vat` amount, which is then checked too.
- `peppol_id` is `ICD:identifier`, for example `0106:12345678` (Dutch KvK), `0208:0123456789` (Belgian enterprise
  number) or `9944:NL123456789B01`. The `iso6523-actorid-upis::` prefix is optional. Identifiers are compared case-insensitively.
- `pay_on` is the date you will order the payment. It defaults to today (UTC).
- Batch: `{"preflights": [ {...}, {...} ], "known_payees": [...], "pay_on": "..."}`, up to 200 per run. The
  top-level `known_payees` and `pay_on` apply to every item that doesn't set its own.

#### Output

The structure below is exact; the values depend on your input. Keys of checks you did not switch on (for
example `peppol` without a `peppol_id`) may be missing. `checks.iban_change` summarises the K1/K2 known-payee
result; `checks.payee_check` is the full Payee Check rule list (I\*, K\* and T\* rules), so walk that array to see
every IBAN, known-payee and invoice-text rule in one place.

```json
{
  "verdict": "BLOCK",
  "score": 0.2,
  "checks": {
    "iban": {"ok": true, "iban": "NL91ABNA0417164300", "country": "NL", "bank": "ABN AMRO", "bic": "ABNANL2A"},
    "iban_change": {"flag": true, "detail": "Jansen Bouw B.V. was paid before on NL02RABO0123456789; this payment goes to NL91ABNA0417164300. Confirm by phone on a number you already had"},
    "vat": {"vat_id": "NL123456789B01", "country": "NL", "format_ok": true, "source": "VIES",
            "status": "valid", "valid": true, "name": "JANSEN BOUW B.V.", "name_match": 1.0,
            "checked_at": "2026-10-26T18:51:19Z", "cached": false, "in_invoice_text": true},
    "peppol": {"registered": true, "status": "listed", "source": "Peppol Directory", "participant_id": "0106:12345678",
               "country": "NL", "entity_name": "Jansen Bouw B.V.", "receives_invoices": true,
               "checked_at": "2026-10-26T18:51:19Z", "cached": false},
    "vat_math": {"ok": false, "rates_checked": "NL",
                 "computed": {"total_net": "100.00", "total_vat_line_rounding": "21.00",
                              "total_vat_total_rounding": "21.00", "total_gross": "121.00"},
                 "reverse_charge_expected": true, "reverse_charge_text_found": false, "vat_charged": true,
                 "issues": ["NL supplier to BE business buyer with VAT charged: usually 0 % with reverse charge (services) or as an intra-Community supply (goods); some supplies are exceptions",
                            "NL to BE B2B: no 'btw verlegd' / reverse-charge or intra-Community supply wording found in the invoice text"]},
    "settlement": {"pay_on": "2026-12-25", "pay_on_is_target_day": false, "target_closed_reason": "Christmas Day",
                   "sepa_ct_value_date": "2026-12-28", "sepa_ct_latest_credit_date": "2026-12-29",
                   "instant_available": true,
                   "instant_basis": "payee bank is in the euro area: must accept SCT Inst under Regulation (EU) 2024/886",
                   "pay_on_in_past": false},
    "payee_check": [{"rule": "I1 IBAN format and length", "ok": true, "severity": "block", "detail": "..."}]
  },
  "unavailable": [],
  "reasons": [
    "K2 known payee asks for a new IBAN: Jansen Bouw B.V. was paid before on NL02RABO0123456789; ...",
    "M3 cross-border B2B VAT: NL supplier to BE business buyer with VAT charged: ...",
    "M4 reverse-charge wording: NL to BE B2B: no 'btw verlegd' / reverse-charge or intra-Community supply wording found in the invoice text"
  ],
  "engine": "supplier-preflight 0.2.0",
  "disclaimer": "Indicative checks, not tax or legal advice."
}
```

#### How the verdict is decided

- **BLOCK**: at least one block-level check failed. These are: an IBAN with the wrong length or check digits; a
  known payee name asking for a new IBAN; an invoice that lists IBANs but not the one being paid; or a VAT id that
  VIES says is invalid. A VAT id that is malformed while VIES is down also counts.
- **REVIEW**: at least one other check failed, or **a register did not answer**. In that case `unavailable` lists
  `"VIES"` and/or `"Peppol Directory"`. A lookup that could not be done never produces `ALLOW`.
- **ALLOW**: every check that your input switched on passed.
- `score` runs from 0 to 1 and summarises the result: 1.0 means nothing failed. Each block-level failure subtracts
  0.5, each other failure 0.15 and each unavailable register 0.1. Act on `verdict`, not on `score`.

| Rule | Severity | Check |
|---|---|---|
| V1 | block | VAT id valid in VIES (also: VIES unavailable **and** the VAT id has an invalid format or Dutch checksum) |
| V2 | review | VAT id could not be checked: VIES unavailable, or the prefix is not an EU VIES country (e.g. GB, CH, NO) |
| V3 | review | the name VIES returns does not match `payee.name` (only when VIES returns a name; some countries, e.g. DE, never do) |
| V4 | review | the VAT id does not appear in `invoice.text` |
| P1 / P2 | review | the `peppol_id` you gave is not listed in the Peppol Directory, or the Directory did not answer |
| P3 / P4 | review | the Peppol entity's country or name differs from the VAT id's country or the payee name |
| M1 | review | VAT arithmetic: line VAT, sum of the lines, total VAT (rounding per line **or** per rate on the totals both pass), gross = net + VAT |
| M2 | review | a rate other than 21 / 9 / 0 % on an invoice from a Dutch supplier |
| M3 / M4 | review | B2B supply between two different EU countries: VAT charged anyway, or no reverse-charge / intra-Community wording in the text |
| D1 | review | `issue_date` is in the future |
| I\*, K\*, T\* | as in Payee Check | the IBAN, known-payee and invoice-text checks listed below |

The settlement block is information only and never changes the verdict. `sepa_ct_value_date` is the first TARGET
business day on or after `pay_on`. TARGET is closed on weekends, 1 January, Good Friday, Easter Monday, 1 May,
25 December and 26 December. `sepa_ct_latest_credit_date` is the next business day after that (the D+1 rule).
`instant_available` is `true` for payee banks in the euro area, where SEPA Instant reception is mandatory. It is
`null` elsewhere, because there it depends on the bank.

### Payee check ($0.001): offline, stateless

```json
{
  "iban": "NL91ABNA0417164300",
  "payee_name": "Jansen Bouw B.V.",
  "amount": "1234.56",
  "message_text": "Invoice 2026-118, amount EUR 1,234.56, to be paid to NL91 ABNA 0417 1643 00.",
  "known_payees": [{"iban": "NL91ABNA0417164300", "name": "Jansen Bouw BV"}]
}
```

Only `iban` is required. Here `amount` must be a decimal string (unlike the pre-flight invoice amounts, which also
accept JSON numbers). For a batch, send `{"payments": [ {...}, ... ], "known_payees": [...]}` with up to 1000
payments; a payment that sets its own `known_payees` uses that list instead of the top-level one.

```json
{
  "verdict": "ALLOW",
  "iban": "NL91ABNA0417164300",
  "country": "NL",
  "bank": {"name": "ABN AMRO", "bic": "ABNANL2A"},
  "reasons": [],
  "checks": [{"rule": "I2 IBAN check digits (mod 97)", "ok": true, "severity": "block", "detail": "check digits valid"}],
  "note": "Offline heuristic check, not a bank Verification of Payee. BLOCK/REVIEW means: a human confirms with the payee on a known phone number before paying."
}
```

Rules: I1/I2 IBAN length and mod-97 (block). I3/I4 a non-SEPA country, or a Dutch bank code that is not on the
official Dutch list (review). K1 a known IBAN under a different name (review). K2 a known payee name with a new IBAN (block). K3 a
new payee (review). K4 a payee name that mixes Latin with Cyrillic or Greek look-alike letters (review). T1 the IBAN
being paid is not among the IBANs in the message (block). T2 to T6 (review): several IBANs in the message, pressure
language, bank-change language (Dutch, English, German, French, Spanish, Italian), or the amount or payee name missing
from the message. Names and message text are compared as a reader sees them: full-width characters, invisible
zero-width characters and Cyrillic/Greek look-alike letters can't be used to dodge a rule.

### Attested verdicts: proof that you checked before you paid

When a payment goes wrong, the question is often "did you check before you paid?". A bank, an auditor, an
insurer or a financial dispute body (for example the ombudsman for financial services in your EU country) may
ask for that proof. A log line in your own system is weak evidence, because you could have written it afterwards.
With `"attest": true`, each checked item gets an evidence record that cannot be back-dated or changed afterwards
without it showing, not by you and not by us. Two independent witnesses date it: a Time-Stamp Authority signs it
at once, and a Bitcoin anchor follows within hours that does not depend on trusting anyone:

```json
{"iban": "NL91ABNA0417164300", "payee_name": "Jansen Bouw B.V.", "attest": true}
```

Each result item then has an `attestation` object:

| Field | What it is |
|---|---|
| `status` | `ok` (timestamped, charged as `attested-check`) or `unavailable` (the timestamp service did not answer: you still get the verdict, and the attestation is **not charged**) |
| `document` | Canonical JSON (sorted keys, no spaces, UTF-8) of what was checked: the input, the full result (verdict, reasons, every rule), `engine` (rule version), `data_as_of`, the Actor build and run id, the check time and a random salt |
| `sha256` | SHA-256 of `document` |
| `merkle` | All items of one run share one timestamp. `path` leads from your item's `sha256` to the `root` that was timestamped (`R`: sha256(hash + x), `L`: sha256(x + hash)). For a single item, `root` = `sha256` |
| `rfc3161` | An RFC 3161 timestamp token from **FreeTSA** (freetsa.org, a free public Time-Stamp Authority) over `merkle.root`: `gen_time`, `serial`, and the full signed response as `tsr_b64` |
| `opentimestamps` | An **OpenTimestamps** proof (`ots_b64`, a standard `.ots` file for your item's `sha256`), submitted to four public calendars. It starts as `pending` and can be anchored in the Bitcoin blockchain a few hours later with `ots upgrade` |

The long text fields (`message_text`, `invoice.text`) and your `known_payees` list are recorded in `document` as
`{"sha256", "length"}` only. Keep the original e-mail or invoice: its SHA-256 proves which text was checked.

**Verify an attestation, free.** Run the Actor with `{"verify": [<attestation>, ...]}` (the attestation object or
the whole result item). It checks offline, without calling any service, that the document still matches its hash,
that the Merkle path reaches the timestamped root, and that the RFC 3161 token is signed by the FreeTSA key
(certificate chain pinned to the FreeTSA root, `timeStamping` key usage, nonce). It returns `valid` and the list of
`problems`. Verification is not charged. You can also check it with standard tools and without us:

```bash
echo '<rfc3161.tsr_b64>' | base64 -d > t.tsr
curl -sO https://freetsa.org/files/cacert.pem
openssl ts -verify -in t.tsr -digest <merkle.root> -CAfile cacert.pem       # "Verification: OK"
echo '<opentimestamps.ots_b64>' | base64 -d > p.ots
ots upgrade p.ots && ots verify -d <sha256> p.ots                           # after a few hours: Bitcoin block
```

What this proves: the exact `document` (and so this verdict, rule version and data dates for this input) existed
no later than `gen_time`, as signed by an independent TSA, and, once anchored, no later than the Bitcoin block
time. What it does not prove: it is **not an eIDAS qualified electronic time stamp** (FreeTSA is not a qualified
trust service), so courts weigh it like other electronic evidence rather than presuming its accuracy. It does not
prove that the payment was made, or what you did with the verdict.

### Calling it from an agent (MCP)

Add the Apify MCP server with this Actor to your MCP client, then call the Actor's tool with the JSON input above:

```json
{"mcpServers": {"apify": {"url": "https://mcp.apify.com?tools=lerider/payee-check",
                          "headers": {"Authorization": "Bearer <your Apify token>"}}}}
```

You can also call it from the Apify API (`run-sync-get-dataset-items`) or from the Apify client libraries. Results
come back as dataset items, one per payment or pre-flight. Each item has an `index`, and bad items carry an `error`
instead of a verdict and are not charged, for example `{"index": 0, "error": "payee.iban is required"}`. Required
fields are checked by the Actor at run time; the input schema itself is deliberately permissive because one
Actor serves two input shapes. The payee check's `note` and the pre-flight's `disclaimer` carry the same kind of
text. `engine` is the version of the check logic and changes independently of the Actor build version.

### Pricing and charging

- `payee-check`: **$0.001** per checked payment (about $1 per 1,000). `supplier-preflight`: **$0.03** per pre-flight.
- `attested-check`: **$0.02** per item, on top of the check, only with `"attest": true` and only when the RFC 3161
  timestamp was obtained. If the timestamp service is down, the verdict is returned with
  `"attestation": {"status": "unavailable"}` and only the check itself is charged. `verify` runs are free.
- A malformed item, such as a missing IBAN, a bad date, an amount with more than 2 decimals or a wrong field type,
  returns an `error` and is **not charged**. A batch is charged per item checked, not per run.
- A pre-flight whose register lookup was `unavailable` still returns a verdict and is charged. Its verdict is never
  `ALLOW`, and `unavailable` names the source, so you can re-run it later.

### What it does NOT do

- It does not pay anything or move money. It is a read-only check.
- It is **not your bank's Verification of Payee (VoP)**. It runs earlier, on the invoice text and your own payment
  history, which your bank's VoP never sees. VoP only warns, and a warning can be clicked through: the Dutch
  financial ombudsman Kifid holds that whoever pays despite a name-mismatch warning carries the loss
  ([Kifid 2026-0901](https://www.kifid.nl/media/cslixrxj/uitspraak-2026-0901-bindend.pdf): €1,420 paid to a
  tampered address-book payee after the bank showed "name does not match", claim rejected). An agent paying on
  its own cannot weigh a warning; it needs the verdict before it pays.
- It gives **no tax or legal advice**. The VAT checks are arithmetic and pattern checks that flag what a person
  should look at. Reverse-charge rules have exceptions (for example some property, event and passenger-transport
  services), and only you or your adviser can apply them.
- It checks VAT **rates** only for Dutch suppliers. Other countries' rates are reported as `"rates_checked": null`,
  never guessed.

### Data sources

- **VIES** (European Commission VAT Information Exchange System, public REST service). It is retried with backoff,
  and answers are cached in memory for at most 24 h, keyed on the VAT id.

- **Peppol Directory** (OpenPeppol, public search API). The Directory lists participants that chose to publish their
  details, so "not listed" does not prove a company is not on the Peppol network.

- **TARGET calendar** (European Central Bank), **Dutch VAT rates** (Belastingdienst), Dutch bank codes
  (Betaalvereniging Nederland BIC list) and the **euro-area country list** (European Union). These are built in.
  An automated check compares them with the official sources every month and flags any difference for an update.
  Every result carries `data_as_of`, the date each built-in table was last verified, e.g.
  `{"bic_list_nl": "2026-10-27", "vat_rates_nl": "2026-10-26", "euro_area": "2026-10-26"}`.

- **FreeTSA** (freetsa.org), RFC 3161 Time-Stamp Authority, used for `attest` only. Its usage policy allows
  commercial use, at most one request per second per IP, best effort without an SLA. One request per run, whatever
  the batch size.

- **OpenTimestamps** public calendars (opentimestamps.org, eternitywall.com, catallaxy.com), used for `attest` only.

### Privacy

Nothing is stored. Each run keeps lookup answers in memory only for its own lifetime, so a batch doesn't ask VIES
twice for the same VAT id. Nothing is written to disk or logged. For sole traders, the trader name that VIES returns
can be personal data. It is passed through to your result only and kept nowhere else. Apify keeps your run's
dataset for your own account, under Apify's own retention rules. Send only what the checks need.

With `attest`, only one 32-byte SHA-256 per run (the Merkle root) goes to FreeTSA, and a hash of it with a random
nonce goes to each OpenTimestamps calendar. Every record contains a random salt, so the hash cannot be used to guess
an IBAN or a name. The evidence record itself is returned only to you, in your dataset.

### Limits

- VIES and member-state registers go down at times. When that happens the verdict is `REVIEW` with
  `"unavailable": ["VIES"]`. Re-run it later.
- Dutch bank-code recognition covers the main Dutch retail and business banks only.
- A batch of pre-flights makes live lookups, so it takes longer than a `payee-check` batch: allow about 1 s per new
  VAT or Peppol id, and more when VIES retries.
- `attest` depends on FreeTSA, a free service without an SLA. When it does not answer within about 25 s (one
  retry), the item is returned unattested and the attestation is not charged.
- These are heuristic checks, not a guarantee. On `REVIEW` or `BLOCK`, a person should confirm with the payee on a
  phone number they already had, not one taken from the invoice in question.

***

Published by Lerider Technologies.

# Changelog

This Actor's version history is a separate document: https://apify.com/lerider/payee-check/changelog.md

# Actor input Schema

## `iban` (type: `string`):

Payee-check mode. Leave empty for 'payments' or for supplier pre-flight.

## `payee_name` (type: `string`):

Name on the invoice.

## `amount` (type: `string`):

Decimal string, e.g. 1234.56.

## `message_text` (type: `string`):

Text the payment request came with. Used for the IBAN-in-message, amount and pressure-language checks. Not stored by the Actor beyond your run's dataset.

## `known_payees` (type: `array`):

Payees you paid before: \[{"iban": "...", "name": "..."}]. Enables the new-IBAN-for-known-payee check.

## `payments` (type: `array`):

Batch mode: a list of {iban, payee_name, amount, message_text}. 'known_payees' above applies to all. Max 1000.

## `payee` (type: `object`):

Supplier pre-flight mode: {"iban": "..." (required), "name": "...", "vat_id": "NL...B01", "peppol_id": "0106:12345678"}.

## `invoice` (type: `object`):

Optional: {"text", "lines": \[{"net": 100.0, "vat_rate": 21}], "total_net", "total_vat", "total_gross", "buyer_vat_id", "issue_date": "YYYY-MM-DD"}.

## `pay_on` (type: `string`):

YYYY-MM-DD the payment will be ordered. Default: today (UTC). Used for the SEPA settlement date.

## `preflights` (type: `array`):

Batch mode: a list of {payee, invoice, pay_on}. 'known_payees' and 'pay_on' above apply to all. Max 200.

## `attest` (type: `boolean`):

Adds an evidence record to every checked item: the input, verdict, rule version and data_as_of in canonical JSON, its SHA-256, an RFC 3161 timestamp token (FreeTSA) and an OpenTimestamps proof (Bitcoin). Only the hash is sent to the timestamp services. Charged per item only when the timestamp was obtained. Works in both modes.

## `verify` (type: `array`):

Verify mode: a list of 'attestation' objects (or whole result items) from earlier runs. Checks offline that the record is unchanged and the timestamp token is valid. Not charged. Use on its own, not with a check.

## Actor input object example

```json
{
  "iban": "NL91ABNA0417164300",
  "payee_name": "Jansen Bouw B.V.",
  "attest": false
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `overview` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "iban": "NL91ABNA0417164300",
    "payee_name": "Jansen Bouw B.V."
};

// Run the Actor and wait for it to finish
const run = await client.actor("lerider/payee-check").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "iban": "NL91ABNA0417164300",
    "payee_name": "Jansen Bouw B.V.",
}

# Run the Actor and wait for it to finish
run = client.actor("lerider/payee-check").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "iban": "NL91ABNA0417164300",
  "payee_name": "Jansen Bouw B.V."
}' |
apify call lerider/payee-check --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lerider/payee-check"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/veb5bYICGBZiqb0Pp/builds/fiIQX0jAIj3qG8YN7/openapi.json
