# Migrating from 2.0

Everything you need to upgrade an integration from Foxentry API 2.0 to 2.1

This guide covers everything you need to upgrade an integration from Foxentry API `2.0` to `2.1`. It lists every breaking change, the additive (non-breaking) features, before/after examples, and a field-by-field reference.

Action required

Version `2.1` is now the default. Integrations that do not pin a version will receive `2.1` automatically. If you are not ready to migrate, pin `2.0` explicitly. The breaking changes are limited to two endpoints, `POST /phone/validate` and `POST /name/validate`, but two of them are silent (no error is returned), so review them carefully.

## At a glance

`Endpoints, envelope, auth, base URL` Unchanged

`/company/*` Unchanged

`/email/*` Unchanged

`/location/*` Unchanged

`/phone/validate` Breaking changes

`/name/validate` Breaking changes

If your integration does not call `/phone/validate` or `/name/validate`, upgrading to `2.1` requires no code changes, only confirming the version header.

## Selecting a version

The API version is selected with the `api-version` request header.

```bash
curl https://api.foxentry.com/phone/validate \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "api-version: 2.1" \
  -H "Content-Type: application/json" \
  -d '{ "request": { "query": { "numberFull": "+420607123456" } } }'
```

The header is **optional**, and its default changed in this release:

|  | Default `api-version` |
| --- | --- |
| Before this release | `2.0` |
| Now | `2.1` |

**Recommendations**

- **Pin the version explicitly on every request.** Relying on the default means a server-side default change can alter your integration's behaviour without a deploy on your side.
- **Not ready to migrate?** Send `api-version: 2.0`. Version `2.0` remains available to pinned clients.
- **Verify what you received.** Every response echoes the resolved version in the `Foxentry-Api-Version` response header. Assert on it in your tests.

## Breaking changes

### POST /phone/validate

#### Request query

The combined number field was renamed.

| 2.0 | 2.1 |
| --- | --- |
| `query.numberWithPrefix` | `query.numberFull` |

The alternative form (separate `prefix` + `number`) is unchanged.

#### Request options

| 2.0 | 2.1 | Notes |
| --- | --- | --- |
| `defaultPrefix` *(deprecated)* | **Removed** | Use `preferredPrefixes` |
| `formatNumber` *(boolean)* | `numberFormat` *(enum)* | Type and semantics changed |

| Value | Description | Example |
| --- | --- | --- |
| `raw` | Number as supplied, digits only | `607123456` |
| `national` | National format with grouping | `607 123 456` |
| `e123` | ITU-T E.123 international, with spaces | `+420 607 123 456` |
| `e164` | ITU-T E.164 international, no spaces | `+420607123456` |

**Before (2.0)**

```json
{
  "request": {
    "query": { "numberWithPrefix": "+420607123456" },
    "options": {
      "validationType": "basic",
      "defaultPrefix": "+420",
      "formatNumber": false
    }
  }
}
```

**After (2.1)**

```json
{
  "request": {
    "query": { "numberFull": "+420607123456" },
    "options": {
      "validationType": "basic",
      "preferredPrefixes": ["+420"],
      "numberFormat": "e164"
    }
  }
}
```

#### Response result.data

| 2.0 field | 2.0 value | 2.1 field | 2.1 value |
| --- | --- | --- | --- |
| `national` | `775111222` | `raw` | `775111222` |
| `nationalFormatted` | `775 111 222` | `national` | `775 111 222` |
| `international` | `+420775111222` | `e164` | `+420775111222` |
| `internationalFormatted` | `+420 775 111 222` | `e123` | `+420 775 111 222` |

Silent breaking change: `format.national` was reused

The key `national` exists in both versions but its meaning changed: in `2.0` it was the unformatted number (`775111222`); in `2.1` it is the grouped number (`775 111 222`). Code reading `format.national` will keep working without an error and silently return different data. Audit every reference to the `format` object.

`result.data.country.code` and `result.data.country.prefix` are now nullable (`string | null`). Handle `null` when the country cannot be resolved.

### POST /name/validate

#### Request options

| 2.0 | 2.1 | Notes |
| --- | --- | --- |
| `validationDepth` *(enum)* | **Removed** | Validation strictness is now handled internally |
| `smartMode` *(boolean)* | **Removed** | Superseded by `correctionMode` |
| none | `correctionMode` *(enum)* | **New**, default `full` |
| none | `dataLanguage` *(enum)* | **New**, default `cs` |

**Mapping the old behaviour**

| 2.0 | 2.1 equivalent |
| --- | --- |
| `smartMode: true` (corrections applied) | `correctionMode: full` |
| `smartMode: false` (corrections offered as suggestions) | `correctionMode: suggestion` |

#### Response details was relocated

| 2.0 | 2.1 |
| --- | --- |
| `result.details` | `result.data.details` |

Silent breaking change

No error is returned if you read the old path; the field is simply absent. Update all reads from `result.details` to `result.data.details`.

## New features (additive)

**`POST /name/validate` vocative (5th case) forms** in `result.data`:

| Field | Description | Example |
| --- | --- | --- |
| `vocativeName` | Vocative of the first name | `Petře` |
| `vocativeSurname` | Vocative of the surname | `Nováku` |
| `vocativeNameSurname` | Vocative of the full name | `Petře Nováku` |

**`POST /name/validate` `result.dataTypes`**  reports which queried components were judged valid vs. invalid:

```json
"dataTypes": {
  "valid":   ["name", "surname"],
  "invalid": []
}
```

## Migration checklist

**All integrations**

- Send the `api-version` header explicitly on every request.
- Assert on the `Foxentry-Api-Version` response header in your tests.
- Decide your cutover strategy: pin `2.0` until ready, or migrate to `2.1`.

**/phone/validate**

- Request: rename `numberWithPrefix` to `numberFull`.
- Request: remove `defaultPrefix`; move to `preferredPrefixes`.
- Request: replace `formatNumber` (boolean) with `numberFormat`.
- Response: remap the `data.format` object and re-check every use of `format.national`.

**/name/validate**

- Request: remove `validationDepth` and `smartMode`.
- Request: add `correctionMode` (and optionally `dataLanguage`).
- Response: move reads from `result.details` to `result.data.details`.
