> ## Documentation Index
> Fetch the complete documentation index at: https://withkazi.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Tenants API — Full CRUD Reference for Tenant Accounts

> REST API endpoints for creating, reading, updating, and deleting tenants in LaraCopilot. Each tenant is a fully isolated customer account.

Tenants are the top-level organisational unit in LaraCopilot. Every extension, DID number, call queue, rate plan, and call detail record belongs to exactly one tenant. The tenant's `slug` and `domain` must be globally unique across the platform. All endpoints require an active admin session — include the session cookie obtained from `POST /api/admin/login` with every request.

The list endpoint supports an optional `search` query parameter that filters across `name`, `slug`, and `domain`. List responses include computed counts for `extensions_count`, `dids_count`, and `queues_count`. The show endpoint additionally eager-loads the full `extensions`, `dids`, `queues`, and `rates` relations.

***

## GET /api/tenants

Returns all tenants ordered by creation date descending, with relation counts attached.

**Query parameters**

<ParamField query="search" type="string">
  Optional. Filters tenants whose `name`, `slug`, or `domain` contains the given string (case-insensitive).
</ParamField>

<ResponseField name="message" type="string">
  Value is `"Tenants fetched successfully."`.
</ResponseField>

<ResponseField name="data" type="array">
  Array of tenant objects.

  <Expandable title="tenant object fields">
    <ResponseField name="data[].id" type="integer">
      Auto-incremented primary key.
    </ResponseField>

    <ResponseField name="data[].name" type="string">
      Human-readable tenant name.
    </ResponseField>

    <ResponseField name="data[].slug" type="string">
      URL-safe unique identifier for the tenant.
    </ResponseField>

    <ResponseField name="data[].domain" type="string">
      Fully-qualified domain name associated with this tenant.
    </ResponseField>

    <ResponseField name="data[].status" type="string">
      Current lifecycle status of the tenant, e.g. `active` or `suspended`.
    </ResponseField>

    <ResponseField name="data[].timezone" type="string">
      IANA timezone string, e.g. `America/New_York`.
    </ResponseField>

    <ResponseField name="data[].max_extensions" type="integer">
      Maximum number of extensions this tenant may provision.
    </ResponseField>

    <ResponseField name="data[].settings" type="object|null">
      Arbitrary key-value configuration bag for tenant-level settings.
    </ResponseField>

    <ResponseField name="data[].extensions_count" type="integer">
      Number of extensions currently assigned to this tenant.
    </ResponseField>

    <ResponseField name="data[].dids_count" type="integer">
      Number of DID numbers currently assigned to this tenant.
    </ResponseField>

    <ResponseField name="data[].queues_count" type="integer">
      Number of call queues currently assigned to this tenant.
    </ResponseField>

    <ResponseField name="data[].created_at" type="string">
      ISO 8601 creation timestamp.
    </ResponseField>

    <ResponseField name="data[].updated_at" type="string">
      ISO 8601 last-updated timestamp.
    </ResponseField>
  </Expandable>
</ResponseField>

<CodeGroup>
  ```bash Request theme={null}
  curl https://your-instance.laracopilot.com/api/tenants \
    -H "Accept: application/json" \
    -b cookies.txt
  ```

  ```bash Request (with search) theme={null}
  curl "https://your-instance.laracopilot.com/api/tenants?search=acme" \
    -H "Accept: application/json" \
    -b cookies.txt
  ```

  ```json 200 Response theme={null}
  {
    "message": "Tenants fetched successfully.",
    "data": [
      {
        "id": 1,
        "name": "Acme Corp",
        "slug": "acme-corp",
        "domain": "acme.laracopilot.com",
        "status": "active",
        "timezone": "America/New_York",
        "max_extensions": 50,
        "settings": { "record_calls": true },
        "extensions_count": 12,
        "dids_count": 4,
        "queues_count": 2,
        "created_at": "2025-01-15T09:00:00.000000Z",
        "updated_at": "2025-03-20T14:30:00.000000Z"
      }
    ]
  }
  ```
</CodeGroup>

***

## POST /api/tenants

Creates a new tenant. Returns `201 Created` with the new tenant record on success.

<ParamField body="name" type="string" required>
  Human-readable name for the tenant. Maximum 255 characters.
</ParamField>

<ParamField body="slug" type="string" required>
  URL-safe unique identifier. Must be unique across all tenants. Maximum 255 characters.
</ParamField>

<ParamField body="domain" type="string" required>
  Fully-qualified domain name for the tenant. Must be unique across all tenants. Maximum 255 characters.
</ParamField>

<ParamField body="status" type="string" required>
  Lifecycle status, e.g. `active`, `suspended`. Maximum 50 characters.
</ParamField>

<ParamField body="timezone" type="string" required>
  IANA timezone identifier, e.g. `America/Chicago`. Maximum 100 characters.
</ParamField>

<ParamField body="max_extensions" type="integer" required>
  Maximum number of extensions the tenant can provision. Minimum value: `1`.
</ParamField>

<ParamField body="settings" type="object">
  Optional. Arbitrary JSON object for tenant-level configuration. Stored as-is.
</ParamField>

<ResponseField name="message" type="string">
  Value is `"Tenant created successfully."`.
</ResponseField>

<ResponseField name="data" type="object">
  The newly created tenant record. Contains the same fields as described in the list response above, without relation counts.
</ResponseField>

<CodeGroup>
  ```bash Request theme={null}
  curl -X POST https://your-instance.laracopilot.com/api/tenants \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -b cookies.txt \
    -d '{
      "name": "Globex Telecom",
      "slug": "globex-telecom",
      "domain": "globex.laracopilot.com",
      "status": "active",
      "timezone": "America/Chicago",
      "max_extensions": 100,
      "settings": { "record_calls": false }
    }'
  ```

  ```json 201 Response theme={null}
  {
    "message": "Tenant created successfully.",
    "data": {
      "id": 2,
      "name": "Globex Telecom",
      "slug": "globex-telecom",
      "domain": "globex.laracopilot.com",
      "status": "active",
      "timezone": "America/Chicago",
      "max_extensions": 100,
      "settings": { "record_calls": false },
      "created_at": "2025-04-22T10:00:00.000000Z",
      "updated_at": "2025-04-22T10:00:00.000000Z"
    }
  }
  ```
</CodeGroup>

***

## GET /api/tenants/{tenant}

Fetches a single tenant by its ID. The response eager-loads the full `extensions`, `dids`, `queues`, and `rates` relations.

**Path parameters**

<ParamField path="tenant" type="integer" required>
  The numeric ID of the tenant to retrieve.
</ParamField>

<ResponseField name="message" type="string">
  Value is `"Tenant loaded successfully."`.
</ResponseField>

<ResponseField name="data" type="object">
  The tenant record with `extensions`, `dids`, `queues`, and `rates` arrays included.
</ResponseField>

<CodeGroup>
  ```bash Request theme={null}
  curl https://your-instance.laracopilot.com/api/tenants/2 \
    -H "Accept: application/json" \
    -b cookies.txt
  ```

  ```json 200 Response theme={null}
  {
    "message": "Tenant loaded successfully.",
    "data": {
      "id": 2,
      "name": "Globex Telecom",
      "slug": "globex-telecom",
      "domain": "globex.laracopilot.com",
      "status": "active",
      "timezone": "America/Chicago",
      "max_extensions": 100,
      "settings": { "record_calls": false },
      "extensions": [],
      "dids": [],
      "queues": [],
      "rates": [],
      "created_at": "2025-04-22T10:00:00.000000Z",
      "updated_at": "2025-04-22T10:00:00.000000Z"
    }
  }
  ```
</CodeGroup>

***

## PUT /api/tenants/{tenant}

Replaces all fields on an existing tenant. Accepts the same body as `POST /api/tenants`. `PATCH /api/tenants/{tenant}` is also accepted and uses the same handler.

**Path parameters**

<ParamField path="tenant" type="integer" required>
  The numeric ID of the tenant to update.
</ParamField>

<ParamField body="name" type="string" required>
  Human-readable name. Maximum 255 characters.
</ParamField>

<ParamField body="slug" type="string" required>
  Must be unique across all tenants, excluding the current record. Maximum 255 characters.
</ParamField>

<ParamField body="domain" type="string" required>
  Must be unique across all tenants, excluding the current record. Maximum 255 characters.
</ParamField>

<ParamField body="status" type="string" required>
  Lifecycle status. Maximum 50 characters.
</ParamField>

<ParamField body="timezone" type="string" required>
  IANA timezone identifier. Maximum 100 characters.
</ParamField>

<ParamField body="max_extensions" type="integer" required>
  Minimum value: `1`.
</ParamField>

<ParamField body="settings" type="object">
  Optional. Replaces the existing settings object entirely.
</ParamField>

<ResponseField name="message" type="string">
  Value is `"Tenant updated successfully."`.
</ResponseField>

<ResponseField name="data" type="object">
  The updated tenant record.
</ResponseField>

<CodeGroup>
  ```bash Request theme={null}
  curl -X PUT https://your-instance.laracopilot.com/api/tenants/2 \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -b cookies.txt \
    -d '{
      "name": "Globex Telecom",
      "slug": "globex-telecom",
      "domain": "globex.laracopilot.com",
      "status": "suspended",
      "timezone": "America/Chicago",
      "max_extensions": 100,
      "settings": { "record_calls": false }
    }'
  ```

  ```json 200 Response theme={null}
  {
    "message": "Tenant updated successfully.",
    "data": {
      "id": 2,
      "name": "Globex Telecom",
      "slug": "globex-telecom",
      "domain": "globex.laracopilot.com",
      "status": "suspended",
      "timezone": "America/Chicago",
      "max_extensions": 100,
      "settings": { "record_calls": false },
      "created_at": "2025-04-22T10:00:00.000000Z",
      "updated_at": "2025-04-22T11:00:00.000000Z"
    }
  }
  ```
</CodeGroup>

***

## DELETE /api/tenants/{tenant}

Permanently deletes the specified tenant. This action cannot be undone.

**Path parameters**

<ParamField path="tenant" type="integer" required>
  The numeric ID of the tenant to delete.
</ParamField>

<ResponseField name="message" type="string">
  Value is `"Tenant deleted successfully."`.
</ResponseField>

<CodeGroup>
  ```bash Request theme={null}
  curl -X DELETE https://your-instance.laracopilot.com/api/tenants/2 \
    -H "Accept: application/json" \
    -b cookies.txt
  ```

  ```json 200 Response theme={null}
  {
    "message": "Tenant deleted successfully."
  }
  ```
</CodeGroup>
