# Swiss VAT (MWST/TVA) & UID Validator – Official Register (`characteristic_division/swiss-uid-vat-validator`) Actor

Bulk-validate Swiss UID and VAT numbers (CHE-xxx.xxx.xxx MWST/TVA/IVA) against the official federal UID register, the source VIES does not cover. Returns VAT status, company name, legal form, address, commercial-register number and LEI. Name search included.

- **URL**: https://apify.com/characteristic_division/swiss-uid-vat-validator.md
- **Developed by:** [Jordan Banchonpanith](https://apify.com/characteristic_division) (community)
- **Categories:** Business, Developer tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 register records

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

## Swiss VAT Number Validation API – UID Register Bulk Check (MWST / TVA / IVA)

**Swiss VAT (MWST/TVA) & UID Validator** checks Swiss **UID** and **VAT numbers** (`CHE-123.456.789 MWST` / `TVA` / `IVA`) in bulk against the **official Swiss federal UID register** of the Federal Statistical Office (BFS). Use it as a Swiss VAT number validation API from your code, a scheduled bulk check for your supplier list, or a one-off clean-up of a CRM export.

The EU's **VIES service does not cover Switzerland**, so EU VAT checkers cannot confirm a Swiss number. This Actor queries the Swiss register directly.

### What you get for each Swiss UID or VAT number

- **Format and check digit** validation (offline, instant, cheap)
- whether the company **exists and is active** in the UID register
- whether it is **VAT-registered**, and the **VAT number to print on invoices** (for VAT-group members, that is the group's number, not their own UID)
- official **name** (plus DE/FR/IT/EN translations), **legal form**, registered **address**, **canton**
- **commercial-register number** (CH-…), entry status, and **LEI** when the register has one
- optional **company name search**: find a company's UID and VAT number from its name, with a relevance rating

### How to validate Swiss VAT numbers in bulk

1. Paste your numbers into **Identifiers**, in any format: `CHE-105.829.940`, `CHE105829940MWST`, `che 105 829 940 tva`, `105.829.940`.
2. Optionally add **Company names** to look up their UID/VAT number.
3. Run. Each number becomes one row in the dataset. Export to CSV, Excel or JSON, or call the Actor through the Apify API.

```json
{
  "identifiers": ["CHE-105.829.940 MWST", "CHE105909036", "CHE-105.829.941"],
  "companyNames": ["Swisscom AG"],
  "maxResultsPerName": 1
}
```

| Field | Description |
|---|---|
| `identifiers` | UID or VAT numbers in any format (max 10,000 per run) |
| `companyNames` | Optional name search (max 2,000), returning up to `maxResultsPerName` (1–30, default 5) |
| `searchMode` | `Auto` (default), `Normal`, or `Fuzzy` |
| `includeInactive` | Include deleted entities in name-search results (default `false`) |
| `includeSoleProprietorNames` | Un-redact sole-proprietor names (default `false`; enable only with a legitimate purpose) |
| `requestIntervalMs` | Delay between register calls, minimum 3,000 ms (the register's limit) |

### Swiss VAT groups: which number is valid?

Some Swiss companies belong to a **VAT group** and do not have their own VAT number. Example from a real run: Nestlé AG (`CHE-105.909.036`) is a VAT-group member, so `CHE-105.909.036 MWST` is **not** a valid VAT number; the group's number `CHE-116.281.710 MWST` is. The output shows this with `vat.vatNumberIsOwnUid`, `vat.isVatGroupMember` and `vat.vatGroupHeadUid`, so you can print the right number on invoices.

### Output example (one row per identifier or name match)

Taken from a real run on 2026-11-05. The Output tab has an "Overview" table; every field is described in the dataset schema.

```json
{
  "inputType": "identifier", "input": "CHE105909036", "uidFormatValid": true,
  "uid": "CHE-105.909.036", "found": true, "isActive": true, "uidRegisterStatus": "active",
  "name": "Nestlé AG", "legalFormCode": "0106", "legalForm": "Corporation (Aktiengesellschaft / SA)",
  "address": { "street": "Zugerstrasse", "houseNumber": "8", "zip": "6330", "town": "Cham", "canton": "ZG", "country": "CH" },
  "commercialRegister": { "status": "registered", "entryStatus": "active", "registerNumber": "CH17030010013" },
  "vat": { "registered": true, "active": true, "vatUid": "CHE-116.281.710", "vatNumberIsOwnUid": false,
           "isVatGroupMember": true, "vatGroupHeadUid": "CHE-116.281.710", "vatNumberDE": "CHE-116.281.710 MWST" },
  "otherEntries": [{ "name": "Nestlé S.A.", "town": "Vevey", "canton": "VD", "isActive": true }],
  "checkedAt": "2026-11-05T01:17:29.160Z", "source": "https://www.uid-wse.admin.ch/V5.0/PublicServices.svc"
}
```

- Not in the register → `found: false`.
- Wrong check digit → `uidFormatValid: false` with a `formatError` (no register call).
- Register or network failure after retries → `error` is set, and **you are not charged** for that row.

### Pricing (pay per event)

| Event | Price |
|---|---|
| Register record (one identifier looked up, or one name-search match / no-match row) | **$0.003** ($3 per 1,000) |
| Format-only check (invalid check digit, no register call) | **$0.0005** |
| Actor start | $0.001 |

Duplicates in one run are looked up and charged once. Set a "max charge per run" and the Actor stops cleanly when it is reached.

### Data source, privacy and limits

- **Official source only:** the public SOAP web service of the federal UID register (`uid-wse.admin.ch`). No scraping, no login, no API key needed.
- **Sole proprietorships** (legal form 0101) carry a person's name, so their name and street are **redacted by default**; VAT status, town and canton are still returned. The Actor never searches by person name or social-security number.
- The public service allows **20 requests per minute**. The Actor throttles to about 19/min and retries rate-limit errors with backoff: expect **about 1,100 register lookups per hour**. Invalid numbers and duplicates are instant.
- Name search returns at most 30 matches per name (register limit).
- Data is as current as the UID register (updated daily by the BFS). This is not legal or tax advice.
- Codes are mapped per eCH-0097 and eCH-0108 v5; raw codes (`legalFormCode`, `uidRegisterStatusCode`) are included too.

### Use cases

- Supplier onboarding and KYB checks for Swiss vendors
- Checking a customer's Swiss VAT number before zero-rated or reverse-charge invoicing
- Cleaning CRM / ERP master data (UID, legal form, canton)
- Scheduled re-checks to catch de-registrations (use an Apify schedule)

### FAQ

**Can I check a Swiss VAT number with VIES?** No. VIES covers EU member states only. Switzerland publishes VAT status in its own UID register, which this Actor queries.

**Is a UID the same as a Swiss VAT number?** Usually the VAT number is the UID followed by MWST, TVA or IVA. VAT-group members are the exception (see above).

**Can I call it as an API?** Yes. Use the Apify API "run Actor synchronously and get dataset items" endpoint with the input above, or one of the Apify API clients.

### En français : vérifier un numéro TVA / IDE suisse

Cet Actor vérifie en masse des **numéros IDE et TVA suisses** (`CHE-123.456.789 TVA`) dans le **registre IDE officiel** de l'Office fédéral de la statistique : format et chiffre de contrôle, entreprise active ou radiée, assujettissement à la TVA, numéro de TVA correct en cas de **groupe TVA**, raison sociale, forme juridique, adresse et canton. VIES ne couvre pas la Suisse. Prix : 0,003 $ par numéro vérifié.

### Maintenance & support

This Actor is **maintained by an AI agent on behalf of its owner**. Report problems in the Actor's **Issues** tab; confirmed issues are **fixed within 14 days**. Source data © Swiss Federal Statistical Office (BFS), UID register public web service. Not affiliated with the BFS.

### Ready-to-run example tasks

- [Validate Swiss VAT numbers in bulk (MWST/TVA/IVA)](https://apify.com/characteristic_division/swiss-uid-vat-validator/examples/validate-swiss-vat-numbers-bulk)
- [Find a Swiss company's UID and VAT number by name](https://apify.com/characteristic_division/swiss-uid-vat-validator/examples/find-swiss-uid-by-company-name)
- [Check Swiss VAT group membership and invoice VAT number](https://apify.com/characteristic_division/swiss-uid-vat-validator/examples/check-swiss-vat-group-membership)

### More Actors from the same maintainer

- [France Price per m² by Address – Batch DVF Comps](https://apify.com/characteristic_division/dvf-price-per-m2-batch): median €/m² of real recorded sales around French addresses
- [France Company Health Check by SIREN – BODACC Batch](https://apify.com/characteristic_division/bodacc-siren-health-check): insolvency, strike-off and late-accounts signals for French companies
- [Google Sheets Import/Export – Service Account](https://apify.com/characteristic_division/sheets-sync-service-account): send these results to a Google Sheet without OAuth expiry

# Actor input Schema

## `identifiers` (type: `array`):

Swiss UID or VAT numbers in any common format: CHE-105.829.940, CHE105829940, CHE-105.829.940 MWST / TVA / IVA, or just the 9 digits. Duplicates are looked up once. Numbers with a wrong check digit are rejected instantly (no register call).

## `companyNames` (type: `array`):

Find UIDs / VAT numbers by company name (e.g. to enrich a supplier list). Each name returns up to 'Max results per name' matches with a relevance rating.

## `maxResultsPerName` (type: `integer`):

Maximum matches returned for each company name (register maximum is 30).

## `searchMode` (type: `string`):

Auto = register default; Normal = exact-ish; Fuzzy = tolerant to typos.

## `includeInactive` (type: `boolean`):

Identifier lookups always report the status. For name search, inactive (deleted) entities are skipped unless this is on.

## `includeSoleProprietorNames` (type: `boolean`):

Sole proprietorships (legal form 0101) are named after a natural person. By default their name and street address are redacted (GDPR/nDSG data minimisation); VAT status, town and canton are still returned. Enable only if you have a legitimate purpose.

## `requestIntervalMs` (type: `integer`):

The public UID service allows 20 requests/minute. Values below 3000 are raised to 3000.

## Actor input object example

```json
{
  "identifiers": [
    "CHE-105.829.940 MWST",
    "CHE-105.829.941"
  ],
  "maxResultsPerName": 5,
  "searchMode": "Auto",
  "includeInactive": false,
  "includeSoleProprietorNames": false,
  "requestIntervalMs": 3100
}
```

# Actor output Schema

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

One row per input item; field definitions in the dataset schema (overview view).

## `runSummary` (type: `string`):

Counts of charged, free and failed items and API requests for this run.

# 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 = {
    "identifiers": [
        "CHE-105.829.940 MWST",
        "CHE-105.829.941"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("characteristic_division/swiss-uid-vat-validator").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 = { "identifiers": [
        "CHE-105.829.940 MWST",
        "CHE-105.829.941",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("characteristic_division/swiss-uid-vat-validator").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 '{
  "identifiers": [
    "CHE-105.829.940 MWST",
    "CHE-105.829.941"
  ]
}' |
apify call characteristic_division/swiss-uid-vat-validator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,characteristic_division/swiss-uid-vat-validator"
        }
    }
}
```

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/hNHbMfsyuiUH1Duvr/builds/npWxF5qWi1nJKxcho/openapi.json
