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

# Rates API — Per-Tenant Billing Rate Plan Management

> Manage per-tenant billing rates in LaraCopilot. Rates define the per-minute cost and billing increment applied to each call detail record.

Rates define the per-minute charge applied to calls that match a given dialled `prefix`. Each rate is scoped to a single tenant and associates a destination label with a `cost_per_minute` and a `billing_increment` (the granularity in seconds at which the call is metered). The platform evaluates CDRs against the tenant's rate table at call completion to calculate the `cost` value stored on the CDR. All endpoints require an active admin session. The list endpoint supports an optional `search` parameter that matches against `prefix`, `destination`, and `status`.

***

## GET /api/rates

Returns all rates ordered by creation date descending, with the parent `tenant` relation included.

**Query parameters**

<ParamField query="search" type="string">
  Optional. Filters rates whose `prefix`, `destination`, or `status` contains the given string (case-insensitive).
</ParamField>

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

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

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

    <ResponseField name="data[].tenant_id" type="integer">
      ID of the tenant this rate belongs to.
    </ResponseField>

    <ResponseField name="data[].prefix" type="string">
      The dialled-number prefix this rate applies to, e.g. `"1212"` or `"44"`.
    </ResponseField>

    <ResponseField name="data[].destination" type="string">
      Human-readable destination label, e.g. `"US New York"` or `"UK Landline"`.
    </ResponseField>

    <ResponseField name="data[].cost_per_minute" type="string">
      Per-minute charge as a decimal with up to four decimal places, e.g. `"0.0120"`.
    </ResponseField>

    <ResponseField name="data[].billing_increment" type="integer">
      Billing granularity in seconds. Call duration is rounded up to the nearest increment before calculating cost.
    </ResponseField>

    <ResponseField name="data[].status" type="string">
      Lifecycle status, e.g. `active` or `inactive`.
    </ResponseField>

    <ResponseField name="data[].tenant" type="object">
      The parent tenant object.
    </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/rates \
    -H "Accept: application/json" \
    -b cookies.txt
  ```

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

  ```json 200 Response theme={null}
  {
    "message": "Rates fetched successfully.",
    "data": [
      {
        "id": 1,
        "tenant_id": 1,
        "prefix": "1212",
        "destination": "US New York",
        "cost_per_minute": "0.0120",
        "billing_increment": 60,
        "status": "active",
        "tenant": { "id": 1, "name": "Acme Corp" },
        "created_at": "2025-01-20T08:00:00.000000Z",
        "updated_at": "2025-01-20T08:00:00.000000Z"
      }
    ]
  }
  ```
</CodeGroup>

***

## POST /api/rates

Creates a new rate and returns `201 Created` with the record.

<ParamField body="tenant_id" type="integer" required>
  ID of the tenant to assign this rate to. Must reference an existing tenant.
</ParamField>

<ParamField body="prefix" type="string" required>
  The dialled-number prefix that triggers this rate, e.g. `"44"`. Maximum 50 characters.
</ParamField>

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

<ParamField body="cost_per_minute" type="number" required>
  Per-minute charge as a decimal number. Must be `0` or greater.
</ParamField>

<ParamField body="billing_increment" type="integer" required>
  Billing granularity in seconds. Minimum value: `1`. Common values are `6`, `30`, or `60`.
</ParamField>

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

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

<ResponseField name="data" type="object">
  The newly created rate record.
</ResponseField>

<CodeGroup>
  ```bash Request theme={null}
  curl -X POST https://your-instance.laracopilot.com/api/rates \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -b cookies.txt \
    -d '{
      "tenant_id": 1,
      "prefix": "44",
      "destination": "UK Landline",
      "cost_per_minute": 0.0250,
      "billing_increment": 60,
      "status": "active"
    }'
  ```

  ```json 201 Response theme={null}
  {
    "message": "Rate created successfully.",
    "data": {
      "id": 2,
      "tenant_id": 1,
      "prefix": "44",
      "destination": "UK Landline",
      "cost_per_minute": "0.0250",
      "billing_increment": 60,
      "status": "active",
      "created_at": "2025-04-22T11:00:00.000000Z",
      "updated_at": "2025-04-22T11:00:00.000000Z"
    }
  }
  ```
</CodeGroup>

***

## GET /api/rates/{rate}

Fetches a single rate by its ID. Includes the parent `tenant` relation.

**Path parameters**

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

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

<ResponseField name="data" type="object">
  The rate record with the `tenant` relation included.
</ResponseField>

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

  ```json 200 Response theme={null}
  {
    "message": "Rate loaded successfully.",
    "data": {
      "id": 2,
      "tenant_id": 1,
      "prefix": "44",
      "destination": "UK Landline",
      "cost_per_minute": "0.0250",
      "billing_increment": 60,
      "status": "active",
      "tenant": { "id": 1, "name": "Acme Corp" },
      "created_at": "2025-04-22T11:00:00.000000Z",
      "updated_at": "2025-04-22T11:00:00.000000Z"
    }
  }
  ```
</CodeGroup>

***

## PUT /api/rates/{rate}

Replaces all fields on an existing rate. `PATCH /api/rates/{rate}` is also accepted and uses the same handler.

**Path parameters**

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

<ParamField body="tenant_id" type="integer" required>
  Must reference an existing tenant.
</ParamField>

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

<ParamField body="destination" type="string" required>
  Maximum 255 characters.
</ParamField>

<ParamField body="cost_per_minute" type="number" required>
  Must be `0` or greater.
</ParamField>

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

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

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

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

<CodeGroup>
  ```bash Request theme={null}
  curl -X PUT https://your-instance.laracopilot.com/api/rates/2 \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -b cookies.txt \
    -d '{
      "tenant_id": 1,
      "prefix": "44",
      "destination": "UK Landline",
      "cost_per_minute": 0.0300,
      "billing_increment": 30,
      "status": "active"
    }'
  ```

  ```json 200 Response theme={null}
  {
    "message": "Rate updated successfully.",
    "data": {
      "id": 2,
      "tenant_id": 1,
      "prefix": "44",
      "destination": "UK Landline",
      "cost_per_minute": "0.0300",
      "billing_increment": 30,
      "status": "active",
      "created_at": "2025-04-22T11:00:00.000000Z",
      "updated_at": "2025-04-22T12:00:00.000000Z"
    }
  }
  ```
</CodeGroup>

***

## DELETE /api/rates/{rate}

Permanently deletes the specified rate.

**Path parameters**

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

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

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

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