# ToolForte NL (`toinedotcom/toolforte-nl`) Actor

Dutch IBAN, BSN, holiday, holiday allowance, severance and UPA test data tools in bulk, via the ToolForte API.

- **URL**: https://apify.com/toinedotcom/toolforte-nl.md
- **Developed by:** [ToolForte](https://apify.com/toinedotcom) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 processed items

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

## ToolForte NL

Run Dutch data tools in bulk. One item in, one dataset row out. You can download the dataset as JSON, CSV, Excel or HTML.

With a [ToolForte API key](https://toolforte.com/developers) the Actor calls `https://toolforte.com/api/v1/tools/<slug>`. **Without a key, Validate IBAN still runs**, locally, on the example in the input form. That demo does not call ToolForte and is not billed as a processed item.

### What does ToolForte NL do?

It runs seven ToolForte tools over a list of inputs: IBAN validation, test IBAN and test BSN generation, Dutch public holidays, holiday allowance (vakantiegeld), severance (transition payment) and UPA pension-declaration test data.

It does not scrape websites, and it does not call ToolForte's AI or render endpoints. BSN and IBAN generators return fictional test values.

### Why use ToolForte NL?

- Run the same tool on up to 1000 items and pick up a dataset.
- Schedule it, call it from the Apify API, or connect it to other Actors.
- See a real IBAN result from the example input before you create a key.
- Pay Apify per successful item. A bad row is not an `item-processed` charge. ToolForte credits, if you use a key, are billed by ToolForte separately.

### What data does it return?

| Field | Meaning |
|---|---|
| `ok` | The item was processed. For IBAN, an invalid number is still `ok: true`; read `result.valid`. |
| `demo` | `true` when no API key was set and nothing was sent to ToolForte. |
| `status` | `demo`, `ok`, `error`, `needs_api_key`, `invalid_api_key`, `unauthorized` or `payment_required`. |
| `input` | The object you sent. |
| `result` | The tool payload. Live calls unwrap ToolForte's `{ ok, data }` envelope, so this is `data`. |
| `error` | Why this item failed. |
| `message` | Set on demo rows so a local check is not mistaken for a live ToolForte response. |

### How to run it

1. Open the Actor and leave the API key empty.
2. Keep the prefilled operation **Validate IBAN** and the example item `{"iban": "NL91 ABNA 0417 1643 00"}`.
3. Start the run. It succeeds with one demo row. `result.valid` is true, `result.bankCode` is `ABNA`, and `result.institution.name` is `ABN AMRO`.
4. Create a key at https://toolforte.com/developers (it starts with `tf_`) and paste it into **ToolForte API key** when you want live data or any operation other than Validate IBAN.
5. For other tools, change **Operation** and replace **Items**. Examples are in the table below.

See the Input tab for the full form. A saved task or an API call that omits `operation` or `items` receives the same example, because both fields have a default.

### How much does it cost?

Pay per event, in USD, billed by Apify:

| Event | Price | When |
|---|---|---|
| `apify-actor-start` | 0.002 | Once per run, charged by the platform. Demo runs pay this too. |
| `item-processed` | 0.005 | Once per item ToolForte actually processed. |

Demo rows, validation errors, timeouts, a rejected key and a run that stops because credits are exhausted are not `item-processed` charges. The Actor charges an item only after that item is in the dataset.

There is no `apify-default-dataset-item` event. Pushing a row does not add a second per-item fee.

ToolForte credits are separate. A live call spends ToolForte credits on the key you provide. A 402 means that balance is empty; the run fails with ToolForte's message after saving the error row.

Memory defaults to 256 MB and can be raised to 1024 MB. The start event is one charge in that range.

### Input

| Field | Required | Default |
|---|---|---|
| `operation` | no | `validate_iban` |
| `items` | no | `[{"iban": "NL91 ABNA 0417 1643 00"}]` |
| `apiKey` | no | empty. A secret field. Leave it empty for demo mode. |

`items` holds at most 1000 objects. Each object is the JSON body of one ToolForte call.

#### Operations

| operation | endpoint | example item |
|---|---|---|
| `validate_iban` | `iban-validator` | `{"iban": "NL91 ABNA 0417 1643 00"}` |
| `generate_iban` | `test-iban-generator` | `{"country": "NL", "count": 3}` |
| `generate_bsn` | `test-bsn-generator` | `{"count": 3}` |
| `dutch_public_holidays` | `dutch-holidays` | `{"year": 2026}` |
| `dutch_holiday_allowance` | `dutch-holiday-allowance-calculator` | `{"monthlySalary": 3500, "monthsWorked": 12}` |
| `severance` | `dutch-severance-calculator` | `{"monthlySalary": 3500, "startDate": "2018-01-01", "endDate": "2026-12-31"}` |
| `upa` | `upa-file-generator` | `{"format": "summary", "options": {"schemeType": "FPR", "population": {"count": 50, "seed": 1}, "period": {"startYear": 2027, "startMonth": 1, "months": 3}}}` |

BSN validation is not offered because ToolForte has no REST endpoint for it.

### Output

A live IBAN check:

```json
{
  "input": { "iban": "NL91 ABNA 0417 1643 00" },
  "ok": true,
  "demo": false,
  "status": "ok",
  "result": {
    "valid": true,
    "iban": "NL91ABNA0417164300",
    "country": "NL",
    "countryName": "Netherlands",
    "checkDigits": "91",
    "bankCode": "ABNA",
    "accountNumber": "0417164300"
  }
}
```

The same input with no API key is `demo: true`, `status: "demo"`, and `result` comes from the local check. `message` says so.

A bad item (missing field, timeout, HTTP 400 or 404) is `ok: false` and the run continues with the next item. A key that does not start with `tf_`, a 401, or a 402 fails the run after that error is stored, so the log states the reason instead of printing a stack trace.

### Demo mode

Demo mode is on when `apiKey` is missing or blank and the operation is `validate_iban`.

The local check cleans spaces, checks the country length, checks the Dutch 4-letter bank code plus 10 digits, and runs the ISO 13616 mod-97 checksum. It names a Dutch bank only for a short list of well-known codes. It does not perform the national check digits the live API adds for some countries. An unknown Dutch bank code can still be a valid IBAN.

Any other operation without a key writes `status: "needs_api_key"` and does not call the network. The run still succeeds so the explanation is in the dataset.

### Tips

- Keep the example input small. One IBAN finishes in well under the Store test limit of 5 minutes.
- UPA files can be large. Prefer `"format": "summary"` unless you need the XML.
- Each live request waits at most 60 seconds. A timeout becomes an error row, not a stuck run.
- The key is sent only as `Authorization: Bearer tf_...` to ToolForte. It is not stored in the dataset and is not written to the log.

### FAQ

#### Does the example input work without a key?

Yes. Validate IBAN runs locally and the run succeeds.

#### What if my key is rejected?

The run fails with ToolForte's message and one `unauthorized` row. Create or copy the key again from https://toolforte.com/developers. Keys start with `tf_`.

#### Is this a scraper?

No. It does not browse the web and it does not collect private profiles. Generated BSN and IBAN values are test data. A real IBAN you submit is sent to ToolForte only when you set a key, over HTTPS, for a format check. That check does not ask the bank whether the account exists.

# Actor input Schema

## `operation` (type: `string`):

Which ToolForte tool to call for every item. Without an API key only Validate IBAN runs, and it runs locally.

## `items` (type: `array`):

One object per call (max 1000). See the README for an example per operation. The prefilled IBAN is a public example and is what demo mode checks when no API key is set.

## `apiKey` (type: `string`):

Optional. A ToolForte key (tf\_...) from https://toolforte.com/developers. Leave this empty to validate the example IBAN locally. The key is never written to the dataset or the log. No key is built into this Actor.

## Actor input object example

```json
{
  "operation": "validate_iban",
  "items": [
    {
      "iban": "NL91 ABNA 0417 1643 00"
    }
  ]
}
```

# Actor output Schema

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

All processed items in the default dataset.

# 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 = {
    "operation": "validate_iban",
    "items": [
        {
            "iban": "NL91 ABNA 0417 1643 00"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("toinedotcom/toolforte-nl").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 = {
    "operation": "validate_iban",
    "items": [{ "iban": "NL91 ABNA 0417 1643 00" }],
}

# Run the Actor and wait for it to finish
run = client.actor("toinedotcom/toolforte-nl").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 '{
  "operation": "validate_iban",
  "items": [
    {
      "iban": "NL91 ABNA 0417 1643 00"
    }
  ]
}' |
apify call toinedotcom/toolforte-nl --silent --output-dataset

```

## MCP server setup

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

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/RX8wLNxU8jpEpfNyY/builds/UCHVGA2bAEWdd0waV/openapi.json
