# Multi-Tenancy

Understand how FairePlace isolates data between organizations and scopes API access.

## How it works

Every API request is scoped to a single organization (tenant) via the API key. Data is completely isolated — you can only access resources belonging to your organization.

```
API Key → Tenant ID → All queries scoped to this tenant
```

The tenant ID is linked to your API key and cannot be modified by the client. Every database query is automatically filtered by tenant. Isolation is automatic — there is no need to specify a tenant or organization in your requests.

## API Key properties

Each API key has the following properties:

| Property | Description |
|----------|-------------|
| `name` | Human-readable label for the key (e.g., "Production", "Staging") |
| `prefix` | All keys start with `fp_*` (e.g., `fp_live_a1b2c3...`) |
| `expiration` | Optional expiration date — keys can be set to expire or remain valid until revoked |
| `tenant_id` | The organization this key is scoped to — determines which data is accessible |

API keys are managed from the FairePlace dashboard under **Paramètres > Développeur > Clés API**.

## Data isolation

Each tenant has a completely separate dataset:

| Resource | Isolation |
|----------|-----------|
| Places, Estates, Rooms | Per-tenant |
| Leases, Charges | Per-tenant |
| Lessees, Owners, Contacts | Per-tenant |
| Documents, PDFs | Per-tenant |
| Signatures, Proofs | Per-tenant |
| Credits, Payments | Per-tenant |
| Media files | Per-tenant |

There is no way to query across tenants. A `GET /leases` call from Tenant A will never return leases belonging to Tenant B.

## Isolation guarantees

- **Filtering:** Every database query includes `WHERE tenant_id = $1` — there is no way to bypass this at the API level
- **Cross-tenant access returns 404:** If you reference a resource belonging to another tenant, you receive a `404 Not Found` (not `403 Forbidden`) to prevent information leakage
- **No multi-org access per user:** A single API key is scoped to exactly one organization. There is no way to access multiple tenants with the same key

## Permissions

Permissions are scoped by resource and action:

| Permission | Description |
|------------|-------------|
| `properties:read` | View places, estates, rooms, equipment |
| `properties:write` | Create and update properties |
| `leases:read` | View leases, charges, documents |
| `leases:write` | Create and update leases |
| `lessees:read` | View tenants and contacts |
| `lessees:write` | Create and update tenants |
| `signatures:read` | View signature status and proofs |
| `signatures:write` | Initiate and manage signatures |
| `credits:read` | View credit balance and history |
| `credits:write` | Purchase credits |
| `media:read` | View uploaded files |
| `media:write` | Upload files |

### Permission errors

If you attempt an action without the required permission:

```json
{
  "error": {
    "code": 403,
    "type": "FORBIDDEN",
    "message": "Insufficient permissions",
    "details": {
      "required": "leases:write",
      "granted": ["leases:read", "properties:read"]
    }
  }
}
```

## Users within a tenant

A tenant can have multiple users, each with different permission sets. User management is handled through the FairePlace dashboard — there is no API endpoint for user management.

## Resource ownership

When you create a resource, it is automatically assigned to your tenant. The `tenant_id` is never exposed in API responses — it's implicit from authentication.

```bash
# This lease is automatically scoped to your tenant
curl -X POST https://api.faireplace.com/api/leases \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"estate_id": "...", "lease_type_id": "...", "rent_amount": 950}'
```

## Cross-resource references

All resource references (e.g., `estate_id` in a lease) must belong to the same tenant. Referencing a resource from another tenant returns a `404`:

```json
{
  "error": {
    "code": 404,
    "type": "NOT_FOUND",
    "message": "Estate not found",
    "details": {
      "estate_id": "estate-from-another-tenant"
    }
  }
}
```

## Edge cases

- **Referencing an ID from another tenant:** The API returns `404 Not Found`. The response is identical to a genuinely non-existent resource — there is no way to distinguish between the two, by design.
- **No cross-tenant data sharing:** There is no mechanism to share resources, leases, or any data between organizations. Each tenant is a fully isolated environment.

---

## Related

- **[Authentication](/quickstart/authentication)** — API keys and permissions
- **[Error Handling](/core/errors)** — Error codes
- **[Pagination](/core/pagination)** — List endpoint patterns
