---
title: API REST – Taxes, régions fiscales et règles territoriales
description: "L'API donne accès à tout le paramétrage de l'écran **Calcul des taxes** : les taxes et leur mode de calcul, les frais et leurs montants par région, les régions fiscales, la région de chaque pays, les exceptions territoriales, la proposition…"
url: "https://www.kafinea.com/fr/documentation/api/api-rest-regions-fiscales/"
updated: "2026-10-28"
category: Intégrations / API
---

# API REST – Taxes, régions fiscales et règles territoriales

L'API donne accès à tout le paramétrage de l'écran **Calcul des taxes** : les taxes et leur mode de calcul, les frais et leurs montants par région, les régions fiscales, la région de chaque pays, les exceptions territoriales, la proposition automatique et le testeur d'adresse. Les contrôles sont ceux de l'écran : ce qu'il refuse, l'API le refuse avec le même motif.

Les trois opérations utilisent la session de l'[API REST](https://www.kafinea.com/fr/documentation/api/api-rest-introduction/) et sont réservées aux comptes **administrateurs**.

| Opération | Méthode | Résultat |
| --- | --- | --- |
| `tax_region_configuration` | GET | Paramétrage complet et contrôles de cohérence |
| `tax_region_preview` | GET | Région d'une adresse, et proposition pour un nouveau document, sans rien enregistrer |
| `tax_region_configure` | POST | Une modification, validée puis enregistrée en une seule fois |

Le paramètre `input` est un objet JSON. Les cases à cocher (`enabled`, `active`, `taxable`, `documentTest`, `intravatApproved`) attendent un vrai booléen JSON : la chaîne `"false"` est refusée.

---

## 1. Lire le paramétrage

`tax_region_configuration` ne prend aucun paramètre.

```bash
curl 'https://apps.kafinea.com/YourKafinea/webservice.php?operation=tax_region_configuration&sessionName=YOUR_SESSION_ID'
```

| Clé de `result.configuration` | Contenu |
| --- | --- |
| `regions` | Identifiant numérique et nom de chaque région fiscale |
| `taxes` | Chaque taxe des articles (`appliesTo: product`) et des frais (`shipping`), inactives comprises : `taxId`, nom, `active`, mode de calcul `method`, type, `compoundOn`, taux par défaut `defaultRate` et taux par région `ratesByRegionId` |
| `charges` | Chaque frais de l'onglet **Frais (& leurs taxes)** : `chargeId`, nom, `format`, type, montant par défaut `defaultValue`, montants par région `valuesByRegionId`, `taxable` et taxes appliquées `taxIds` |
| `countries` | Chaque pays : identifiant, code ISO, région de base, régions professionnelle et particulier, condition professionnelle |
| `rules` | Les exceptions territoriales, actives ou non, avec leur critère et leur priorité |
| `enabled`, `departure_country`, `operation_kind`, `organization_ids` | La proposition automatique et son périmètre |
| `diagnostics` | `configurationIssues` (pays en double, exceptions qui se chevauchent, région supprimée) et `missingRates` (taux absents pour une région utilisée) |

Les identifiants de cette réponse sont ceux à renvoyer dans les modifications. Ils diffèrent d'une instance à l'autre : lisez-les sur l'instance visée.

---

## 2. Tester une adresse ou un nouveau document

`tax_region_preview` reçoit l'adresse dans `input` : `country` (code ISO, nom français ou anglais), `postcode` et `state`.

```bash
curl -G 'https://apps.kafinea.com/YourKafinea/webservice.php' 
  --data-urlencode 'operation=tax_region_preview' 
  --data-urlencode 'sessionName=YOUR_SESSION_ID' 
  --data-urlencode 'input={"country":"France","postcode":"97300"}'
```

La réponse indique le pays reconnu, la région géographique (`geography`) et la règle ou le pays qui l'a choisie. Avec `documentTest: true`, ajoutez les faits du client et de l'opération (`partyNature`, `intravatApproved`, `vatNumber`, `organizationId`, `operation`, `goodsOrServices`, `departureCountry`, `partyRegionId`) : la réponse contient alors la région qu'un **nouveau** document recevrait (`document`). Aucun fait n'est deviné. `vatNumber` est le numéro de TVA du client, une chaîne JSON ; un autre type est refusé.

`organizationId` accepte l'identifiant de la société ou son nom exact (également via `organizationName`). Une société absente, inconnue ou dont le nom est porté par plusieurs sociétés est signalée dans `inputIssues`, avec les sociétés configurées.

Quand le contexte de l'opération ne permet pas de proposer une région, `document.advisories` contient `UNSUPPORTED_TAX_CONTEXT` et `document.advisory_details` en précise la cause :

| `cause` | Signification |
| --- | --- |
| `ORGANIZATION_NOT_CONFIGURED` | La société ne fait pas partie des sociétés retenues pour la sélection automatique |
| `OPERATION_KIND_NOT_SUPPORTED` | L'opération ne porte pas sur des biens |
| `DEPARTURE_COUNTRY_NOT_CONFIGURED` | Le pays de départ du paramétrage est absent ou non reconnu |
| `DEPARTURE_COUNTRY_UNKNOWN` | Le pays de départ fourni est absent ou non reconnu |
| `DEPARTURE_COUNTRY_MISMATCH` | Le pays de départ fourni diffère de celui du paramétrage |
| `MODULE_NOT_SUPPORTED` | Le document n'est pas un document de vente |
| `OPERATION_NOT_SALE` | L'opération n'est pas une vente |

Chaque entrée donne aussi la valeur reçue (`actual`), la valeur attendue (`expected`) et un `message` lisible, par exemple : « La société 0 ne fait pas partie des sociétés configurées pour la sélection automatique de la région : 530 (Ma société). »

Pour essayer une modification avant de l'enregistrer, ajoutez `configurationPreview` : le même objet que celui de `tax_region_configure`, complété par `configurationKind` (`settings`, `country` ou `rule`).

---

## 3. Modifier le paramétrage

`tax_region_configure` reçoit `kind` et l'objet `input` complet de la modification.

| `kind` | Effet | `input` |
| --- | --- | --- |
| `region` | Crée, renomme ou supprime une région | `{"action":"save","name":"…"}` pour créer ; ajoutez `region_id` pour renommer ; `{"action":"delete","region_id":12}` pour supprimer |
| `tax_grid` | Remplace le taux par défaut et les taux par région d'une taxe existante | `appliesTo`, `taxId`, `defaultRate`, `ratesByRegionId` complet, par exemple `{"3":0,"5":20}` |
| `tax` | Crée une taxe, ou redéfinit une taxe existante | `appliesTo`, `name`, `active`, `method` (`Simple`, `Compound` ou `Deducted`), `type` (`Fixed` ou `Variable`), `defaultRate`, `ratesByRegionId`, `compoundOn` ; `taxId` pour modifier |
| `tax_status` | Active ou désactive une taxe | `appliesTo`, `taxId`, `active` |
| `charge` | Crée un frais, ou redéfinit un frais existant avec ses montants par région | `name`, `format` (`Flat` ou `Percent`), `type`, `defaultValue`, `valuesByRegionId`, `taxable`, `taxIds` ; `chargeId` pour modifier |
| `charge_delete` | Supprime un frais | `chargeId` |
| `country` | Change la région d'un pays, ou de plusieurs pays à la fois | `country_id`, `mdstaxregionid`, `mdsprofessionaltaxregionid`, `mdsindividualtaxregionid`, `mdsprofessionaltaxcondition` (`nature_only`, `qualified_customer` ou `vat_number`) ; ou `isocodes` avec seulement les champs à changer (voir plus bas) |
| `rule` | Crée ou modifie une exception territoriale | `label`, `country`, `criterion_type` (`postcode_prefix`, `postcode_range`, `subdivision`), `criterion_value`, `criterion_end` pour une plage, `priority`, `active`, les trois régions et la condition ; `ruleid` pour modifier |
| `settings` | Active ou règle la proposition automatique | `enabled`, `departure_country`, `operation_kind` (`goods` pour activer), `organization_ids` |
| `french_baseline` | Exécute **Générer le paramétrage fiscal France** | `{}` |

```bash
curl -X POST 'https://apps.kafinea.com/YourKafinea/webservice.php' 
  -d 'operation=tax_region_configure' 
  -d 'sessionName=YOUR_SESSION_ID' 
  -d 'kind=rule' 
  --data-urlencode 'input={"label":"Canaries – Las Palmas","country":"ES","criterion_type":"postcode_prefix","criterion_value":"35","priority":50,"active":true,"mdstaxregionid":5,"mdsprofessionaltaxregionid":0,"mdsindividualtaxregionid":0,"mdsprofessionaltaxcondition":"nature_only"}'
```

Dans cet exemple, `5` est l'identifiant de la région « Hors UE » lu sur l'instance. Une région vaut `0` quand elle n'est pas renseignée. La réponse `{"saved":true,"result":{…}}` donne l'identifiant créé ou modifié (`region_id`, `ruleid`, `taxId`, `chargeId`). Relisez ensuite le paramétrage avec `tax_region_configuration`, puis testez quelques adresses.

Les garanties sont celles de l'écran :

- une modification est enregistrée en entier ou pas du tout ; la création d'une taxe et `french_baseline` sont entièrement contrôlées avant d'écrire ;
- une région encore utilisée par un pays, une exception, une grille de taux, un article ou un document enregistré est conservée ;
- deux exceptions actives de même priorité qui peuvent viser la même adresse sont refusées ;
- la proposition automatique ne s'active qu'avec un paramétrage sans incohérence ;
- un taux nul est un taux configuré, et une taxe fixe garde une grille vide ;
- `french_baseline` ne complète que ce qui manque et ne remplace jamais une région, un taux ou un pays déjà paramétré. Sa réponse liste ce qui a été créé ; rejouée, elle ne crée rien.

Un refus commence par un code stable, par exemple `LBL_TAX_REGION_INVALID_RULE`, suivi de l'explication affichée par l'écran et, pour un objet incomplet, du champ manquant. Testez le code dans vos programmes et affichez l'explication.

Les régions sont aussi lisibles et modifiables par les [opérations CRUD](https://www.kafinea.com/fr/documentation/api/api-rest-operations-crud/) sur le module ci-dessous, avec les mêmes contrôles :

```text
elementType=MdsTaxRegion   champ : name
```

La condition `vat_number` accorde la région professionnelle à un client professionnel dont la fiche porte un numéro de TVA d’un autre pays que le pays de départ : seuls la présence d'un chiffre et le préfixe de deux lettres comptent, `EL` désigne la Grèce, un numéro sans préfixe est accepté. La case **Exonération intracommunautaire autorisée** cochée sur la fiche (`mdsintravatapproved`) remplit aussi la condition. Sinon, la région de base s'applique avec l'avis `VAT_NUMBER_MISSING`.

**Plusieurs pays à la fois.** Avec `isocodes` (de 1 à 300 codes ISO de la liste des pays) au lieu de `country_id`, seuls les champs envoyés sont écrits, sur chaque pays de la liste : chaque pays garde ses autres champs, si bien qu'un pays réglé à part n'est pas aligné sur ses voisins au-delà de ces champs. La région professionnelle s'envoie toujours avec sa condition. Tous les pays sont écrits, ou aucun ; la réponse les liste dans `result.isocodes` et l'historique garde une ligne par pays. Placé dans `configurationPreview`, le même objet se teste avec `tax_region_preview` avant d'être enregistré.

```bash
curl -X POST 'https://apps.kafinea.com/YourKafinea/webservice.php' 
  -d 'operation=tax_region_configure' 
  -d 'sessionName=YOUR_SESSION_ID' 
  -d 'kind=country' 
  --data-urlencode 'input={"isocodes":["BE","DE","IT"],"mdsprofessionaltaxregionid":6,"mdsprofessionaltaxcondition":"vat_number"}'
```

La région d'un pays se modifie de préférence avec `kind: "country"` : seule cette opération règle aussi les régions professionnelle et particulier. Les opérations génériques sur le module des pays appliquent les mêmes garanties :

```text
elementType=MdsTaxCountry   champs : countryname, isocode, mdstaxregionid, taxzone
```

- `update` et `revise` peuvent changer `mdstaxregionid` : la région choisie est contrôlée comme sur l'écran, et les régions professionnelle et particulier déjà réglées sont conservées ;
- le code ISO d'un pays ne change pas (`LBL_TAX_COUNTRY_ISO_IMMUTABLE`) ; la casse et les espaces sont tolérés ;
- `create` n'accepte qu'un code ISO existant et absent de la liste (`LBL_TAX_COUNTRY_ISO_UNKNOWN`, `LBL_TAX_COUNTRY_ISO_DUPLICATE`) ;
- `delete` est refusé (`LBL_TAX_COUNTRY_DELETE_REFUSED`) : videz plutôt la correspondance du pays.

Les taxes (`Tax`) et les taxes des articles (`ProductTaxes`) restent lisibles par `retrieve` et `query`, mais leurs opérations génériques d'écriture sont refusées (`LBL_TAX_GENERIC_WRITE_REFUSED`, `LBL_PRODUCT_TAXES_GENERIC_WRITE_REFUSED`) : une taxe se crée et se modifie avec `kind: "tax"`, `tax_grid` ou `tax_status`. La mise à jour d'un produit ou d'un service par l'API ne touche à ses catégories de taxe que si elle envoie des champs de taxe (`tax1`, `tax2`…) : les champs envoyés avec une valeur deviennent alors l'ensemble de ses catégories, et un champ envoyé vide retire la catégorie correspondante. Sans champ de taxe, les catégories restent telles quelles.

### Créer une taxe

Une taxe se crée avec `kind: "tax"` sans `taxId`. Ses règles sont celles du formulaire **Ajouter une taxe** :

- le nom est unique parmi les taxes de même portée, inactives comprises ;
- le mode de calcul se choisit à la création et ne change plus ; pour en changer, créez une autre taxe et désactivez l'ancienne ;
- une taxe composée (`Compound`) s'applique sur d'autres taxes simples actives, listées dans `compoundOn` ;
- une taxe déduite (`Deducted`) ne concerne que les articles et reste fixe ;
- seule une taxe variable (`Variable`) reçoit des taux par région.

```bash
curl -X POST 'https://apps.kafinea.com/YourKafinea/webservice.php' 
  -d 'operation=tax_region_configure' 
  -d 'sessionName=YOUR_SESSION_ID' 
  -d 'kind=tax' 
  --data-urlencode 'input={"appliesTo":"product","name":"Éco-participation","active":true,"method":"Simple","type":"Fixed","defaultRate":0.5,"ratesByRegionId":{},"compoundOn":[]}'
```

La création ajoute une colonne aux lignes des documents : une taxe ne se supprime pas, elle se désactive avec `kind: "tax_status"`. Tous les contrôles ont lieu avant cette création. Cochez ensuite la nouvelle taxe sur les produits et services concernés.

### Régler les frais par région

Un frais variable reçoit un montant par région dans `valuesByRegionId`, par exemple `{"3":15,"5":0}`. Le montant `Flat` est exprimé dans la devise de base ; un frais `Percent` reste compris entre 0 et 100. Un frais taxable liste les taxes de frais actives dans `taxIds`.

Comme dans l'écran, `kind: "charge_delete"` retire un frais des nouveaux documents ; les documents enregistrés gardent leurs montants. Donnez un autre nom à un nouveau frais. Rejouée, la suppression répond `alreadyDeleted: true`.

---

## 4. Avec le serveur MCP et l'Assistant

Le serveur MCP et l'Assistant Kafinea utilisent ces mêmes opérations, sous leurs contrôles de modification des données. Une modification du paramétrage ne recalcule pas les documents déjà enregistrés.

---

## 5. Région fiscale d'un document enregistré par l'API

Les opérations `create`, `update` et `revise` des devis, commandes, factures et avoirs lisent le champ `region_id` ainsi :

| `region_id` envoyé | Création | Modification avec `LineItems` | Modification sans `LineItems` |
| --- | --- | --- | --- |
| absent | région proposée, ou région par défaut du client, sinon aucune | inchangée | inchangée |
| `null` | comme absent | région retirée | refusée si elle diffère de la région enregistrée |
| `""` ou `0` | absence explicite de région | absence explicite | refusée si elle diffère de la région enregistrée |
| identifiant de région | cette région | cette région | refusée si elle diffère de la région enregistrée |
| autre valeur | refusée (`INVALID_ID_ATTRIBUTE`), rien n'est enregistré | refusée | refusée |

Le taux de chaque ligne dépend de la région : une région ne change qu'avec les lignes. Une modification sans `LineItems` qui change la région est refusée (`MANDATORY_FIELDS_MISSING`). Renvoyer la région déjà enregistrée, par exemple après un `retrieve`, reste accepté ; `null` et `0` y sont équivalents.

Chaque document garde sa propre région : la région d'un document n'est jamais reprise par le document enregistré juste après dans le même traitement.

---

## Références associées

- [La configuration des taxes](https://www.kafinea.com/fr/documentation/parametrage/la-configuration-des-taxes/)
- [La région fiscale des documents](https://www.kafinea.com/fr/documentation/parametrage/la-region-fiscale-des-documents/)
- [Introduction à l'API REST](https://www.kafinea.com/fr/documentation/api/api-rest-introduction/)
