# API Overview

This tutorial introduces the Pigello API: base URLs, endpoint patterns, list reading (filters, ordering, pagination), list writing, and conventions such as PATCH over PUT and trailing slashes.

## Base URLs

Use the following base URLs depending on your environment:

| Environment | Base URL |
|  --- | --- |
| **Production** | `api.pigello.io` |
| **Development** | `dev.api.pigello.io` |


All API requests use HTTPS.

## Endpoints

Most entities follow the same endpoint pattern. The API supports:

- **Single instance retrieval** — Fetch one resource by ID.
- **Multi instance retrieval** — List resources with optional filters, ordering, and pagination.
- **Single instance create** — Create one resource.
- **Single instance update** — Update one resource by ID.
- **Single instance delete** — Delete one resource by ID.
- **Multi instance update** — Bulk update via the list endpoint.
- **Multi instance create** — Bulk create via the list endpoint.


### Endpoint structure

Paths are usually built from the sub-application, sub-functionality, and entity content type:

| Purpose | Path pattern | Example |
|  --- | --- | --- |
| List (multi instance) | `/<sub-application>/<sub-functionality>/<entity-content-type>/` | `/objects/structural/realestate/` |
| Single instance | `/<sub-application>/<sub-functionality>/<entity-content-type>/<uuid:pk>/` | `/objects/structural/realestate/<id>/` |
| List operations (bulk) | `/<sub-application>/<sub-functionality>/<entity-content-type>/list/` | `/objects/structural/realestate/list/` |


Use the API References to find the exact paths and content types for each entity.

## List reading

When reading multiple instances (list endpoints), you can filter, order, and paginate the results.

### Filters

Many filters are available per entity, depending on the field types.

**String-based fields** typically support:

| Operator | Description |
|  --- | --- |
| (none) | Exact match |
| `icontains` | Case-insensitive contains |
| `contains` | Contains |
| `startswith` | Starts with |
| `istartswith` | Case-insensitive starts with |
| `endswith` | Ends with |
| `iendswith` | Case-insensitive ends with |
| `in` | Value in a list of options |


**Number-based fields** (integers, floats, dates, date-times) typically support:

| Operator | Description |
|  --- | --- |
| (none) | Exact match |
| `gte` | Greater than or equal |
| `lte` | Less than or equal |
| `gt` | Greater than |
| `lt` | Less than |
| `in` | Value in a list of options |


**Negation:** For most filters, add the suffix `!` to the filter parameter to negate the condition.

**List values:** When a filter expects a list of values, pass them as a comma-separated string, for example `abc,cde` for the values `abc` and `cde`.

### Ordering

Specify sort order with the `_order_by` query parameter. The value is a comma-separated list of field names. Prefix a field with `-` for descending order.

**Example:** `_order_by=name,-created_at` orders by `name` ascending, then by `created_at` descending.

### Pagination

Pagination is controlled by:

| Parameter | Description |
|  --- | --- |
| `_page_size` | Number of results per page (max **500** on most endpoints). |
| `_page` | Page number (1-based). |


Most endpoints **require** pagination. The maximum `_page_size` is typically **500**. Some endpoints waive the pagination requirement when you filter by `id` or `id__in` (e.g. when fetching a known set of IDs).

## List writing

Many entities support **bulk create and update** by sending a `POST` request to the **list** endpoint (e.g. `.../<realestate>/list/`).

- **Create:** Omit the primary key (`id`) in the request body for each row. The API treats the row as a new instance.
- **Update:** Include the primary key (`id`) for each row. The API updates the existing instance.


Updates are applied in a **PATCH** style: you only need to send the attributes you want to change. **Sending attributes that are not intended to be changed is unnecessary and can affect validation**. See [PATCH over PUT](#patch-over-put) below.

## PATCH over PUT

The API uses **PATCH** instead of **PUT** for updates.

- Send only the attributes you intend to change. Do not send the full resource unless you mean to change every field.
- Validation may depend on which attributes are present in the payload. Omitting unchanged data helps avoid unintended validation behavior.


This applies to both single-instance updates and bulk (list) updates.

## Trailing slash

All endpoints use a **trailing slash**. Always include it in your requests.

**Example:** Use `/objects/structural/realestate/` rather than `/objects/structural/realestate`.

Including the trailing slash avoids unnecessary redirects (3xx responses), though the server may still accept requests without it.