# Edara API v3: Countries

Read the [guide](../guide.md) first: authentication, paging, errors, rate limits and the shared `PagedResult`, `BatchResult` and `*Reference` shapes.

- `GET /v3/countries`: Lists countries.
- `GET /v3/countries/{id}`: Gets a country by id.
- `POST /v3/countries`: Creates a country.
- `PUT /v3/countries/{id}`: Updates a country.
- `DELETE /v3/countries/{id}`: Deletes a country.

## Endpoints

### `GET /v3/countries`: Lists countries.

Operation `GetCountries` · permission `read:country`

**Query string**: `GetCountriesQuery`

| field | type | default | validation | description |
|---|---|---|---|---|
| `offset` | `int?` | 0 | >= 0 | Number of items to skip before returning results. Defaults to 0. |
| `limit` | `int?` | 100 | 1..1000 (out of range → 400) | Maximum number of items to return. Defaults to 100, maximum 1000. |
| `name` | `string` |  |  | Optional exact country name filter. |

**Responses**: OK `PagedResult<CountryResponse>`: Paged list of countries.

**Notes**

- `name` is a partial match, not an exact one: it finds every country whose name contains the text you send. A `name` that is only whitespace is ignored.
- There are no other filters and no hidden default filters.
- Results are ordered by `name`.
- `totalCount` is the number of countries that match the filter, not the number on the page.
- When nothing matches you get `200` with an empty `items` list and `totalCount` 0.
- `name` is returned exactly as stored. Unlike the cities and districts lists, tab characters are not removed.
- `page` in the response is `offset` divided by `limit`, plus 1.

---

### `GET /v3/countries/{id}`: Gets a country by id.

Operation `GetCountryById` · permission `read:country`

**Parameters**

| name | in | type | default | description |
|---|---|---|---|---|
| `id` | route | `int` |  | The country id. |

**Responses**: OK `CountryResponse`: The country.

**Notes**

- An `id` that does not exist returns `404`.

---

### `POST /v3/countries`: Creates a country.

Operation `CreateCountry` · permission `create:country`

**Body**: `CountryUpsertRequest`

| field | type | default | validation | description |
|---|---|---|---|---|
| `name` | `string` |  | NotEmpty() .NotNull() .MaximumLength(100) | The country name. |

**Responses**: Created `CountryResponse`: The created country.

**Business errors** (HTTP 409, match on `errorCode`):

- `DupplicatedName`: Another country already uses the same name.

**Notes**

- Only `name` is read from the body, and it is trimmed before it is saved.
- Country names are unique across the organization. A duplicate `name` returns `409` with `errorCode` `DupplicatedName`.

---

### `PUT /v3/countries/{id}`: Updates a country.

Operation `UpdateCountry` · permission `update:country`

**Parameters**

| name | in | type | default | description |
|---|---|---|---|---|
| `id` | route | `int` |  | The country id. |

**Body**: `CountryUpsertRequest`

| field | type | default | validation | description |
|---|---|---|---|---|
| `name` | `string` |  | NotEmpty() .NotNull() .MaximumLength(100) | The country name. |

**Responses**: OK `CountryResponse`: The updated country.

**Business errors** (HTTP 409, match on `errorCode`):

- `DupplicatedName`: Another country already uses the same name.

**Notes**

- An `id` that does not exist returns `404` and nothing is changed.
- `name` is the only field you can change.
- Renaming a country to a `name` that another country already uses returns `409` with `errorCode` `DupplicatedName`.

---

### `DELETE /v3/countries/{id}`: Deletes a country.

Operation `DeleteCountry` · permission `delete:country`

**Parameters**

| name | in | type | default | description |
|---|---|---|---|---|
| `id` | route | `int` |  | The country id. |

**Responses**: NoContent: (not declared; read from the method body)

**Business errors** (HTTP 409, match on `errorCode`):

- `ItemCannotDeleteItInUse`: The country is still referenced by related records and cannot be deleted.

**Notes**

- The delete is permanent.
- An `id` that does not exist returns `404`. Success returns `204`.
- A country that is still in use returns `409` with `errorCode` `ItemCannotDeleteItInUse`. A country is in use when a city, customer, customer address, sales document, quote, warehouse or account refers to it.
- A country that has any city cannot be deleted.

## Types

### `CountryResponse`

Response describing a country.

| field | type | description |
|---|---|---|
| `id` | `int` | The country identifier. |
| `name` | `string` | The country name. |
