> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://catena.ferndocs.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://catena.ferndocs.com/_mcp/server.

# 🧪 List Driver Insurance Signals

GET https://api.catenatelematics.com/v2/intelligence/insurance/driver-signals

Retrieve underwriting signals per driver for your accessible fleets over a requested time window. Each row carries safety event counts (speeding, harsh cornering, harsh braking) attributed to the driver and the number of hours-of-service violations recorded against them. All signals are measured over the same window. Distance is not reported at this grain: the odometer is recorded per vehicle, so use the vehicle signals endpoint for distance. The window cannot exceed 90 days.

Reference: https://catena.ferndocs.com/api-reference/intelligence/insurance-signals/list-driver-insurance-signals

## Authentication

- `Authorization` header (bearer token, required) — Bearer authentication of the form `Bearer <token>`, where token is your auth token.

## Request

### Query parameters

- `fleet_ids` (list of string, optional, nullable) — Limit results to specific fleets using Catena's fleet IDs. *For your own fleet identifiers, use `fleet_refs` instead* To specify multiple values, repeat the parameter for each value (e.g., `?fleet_ids=id1&fleet_ids=id2`).
- `fleet_refs` (list of string, optional, nullable) — Limit results to specific fleets using your organization's fleet reference identifiers. To specify multiple values, repeat the parameter for each value (e.g., `?fleet_refs=ref1&fleet_refs=ref2`).
- `connection_id` (string, optional, nullable) — Limit results to a specific provider connection. This is the UUID assigned by Catena when your fleet connects to a TSP.
- `driver_ids` (list of string, optional, nullable) — Limit results to specific drivers. **Maximum:** 100 IDs To specify multiple values, repeat the parameter for each value (e.g., `?driver_ids=id1&driver_ids=id2`).
- `from_datetime` (datetime, optional) — Return only records that occurred on or after this date and time. **Format:** ISO 8601 (UTC) **Applies filter:** `occurred_at >= from_datetime` **Default value:** `now() - 1 day` **Restriction:** `to_datetime - from_datetime` cannot exceed 90 days
- `to_datetime` (datetime, optional) — Return only records that occurred before this date and time. **Format:** ISO 8601 (UTC) **Applies filter:** `occurred_at < to_datetime` **Default value:** `now()` **Restriction:** `to_datetime - from_datetime` cannot exceed 90 days
- `cursor` (string, optional, nullable) — Cursor for the next page
- `size` (integer, optional, default: 300) — Page size

## Response

### 200

Successful Response

- `items` (list of DriverInsuranceSignalsRead, required)
- `total` (integer, required)
- `current_page` (string, optional, nullable) — Cursor to refetch the current page
- `current_page_backwards` (string, optional, nullable) — Cursor to refetch the current page starting from the last item
- `previous_page` (string, optional, nullable) — Cursor for the previous page
- `next_page` (string, optional, nullable) — Cursor for the next page

## Errors

### 400 Bad Request Error

Bad Request

- `code` (integer, optional, default: 400)
- `message` (string, optional, default: Bad Request)
- `detail` (string, optional, nullable)

### 401 Unauthorized Error

Unauthorized

- `code` (integer, optional, default: 401)
- `message` (string, optional, default: Unauthorized)
- `detail` (string, optional, nullable)

### 403 Forbidden Error

Forbidden

- `code` (integer, optional, default: 403)
- `message` (string, optional, default: Forbidden)
- `detail` (string, optional, nullable)

### 404 Not Found Error

Not Found

- `code` (integer, optional, default: 404)
- `message` (string, optional, default: Not Found)
- `detail` (string, optional, nullable)

### 405 Method Not Allowed Error

Method Not Allowed

- `code` (integer, optional, default: 405)
- `message` (string, optional, default: Method Not Allowed)
- `detail` (string, optional, nullable)

### 409 Conflict Error

Conflict

- `code` (integer, optional, default: 409)
- `message` (string, optional, default: Conflict)
- `detail` (string, optional, nullable)

### 422 Unprocessable Entity Error

Unprocessable Entity

- `code` (integer, optional, default: 422)
- `message` (string, optional, default: Invalid Request Body)
- `detail` (list of ValidationErrorDetail, optional, nullable)

### 429 Too Many Requests Error

Too Many Requests

- `code` (integer, optional, default: 429)
- `message` (string, optional, default: Too Many Requests)
- `detail` (RetryAfterDetail, optional, nullable)

### 500 Internal Server Error

Internal Server Error

- `message` (string, optional, default: Internal Server Error)

### 501 Not Implemented Error

Not Implemented

- `code` (integer, optional, default: 501)
- `message` (string, optional, default: Not Implemented)
- `detail` (string, optional, nullable)

## Types

### DriverInsuranceSignalsRead

Underwriting signals for a single driver over the requested time window.

- `driver` (DriverEmbeddedRead, required) — Identifying details for the driver that this row describes.
- `fleet_refs` (list of string, required) — Your assigned reference IDs for the fleets this driver is visible through. Almost always one. Empty when no reference has been assigned to any of them. The signals below describe the driver and do not vary by fleet.
- `fleet_ids` (list of string, required) — Catena fleet identifiers for the same fleets. Several identifiers can share a single `fleet_refs` entry, so this list is usually the longer of the two and the two are not positionally paired. Prefer `fleet_refs` for grouping and reporting.
- `speeding_event_count` (integer, required) — Number of speeding events attributed to this driver in the window.
- `harsh_turn_count` (integer, required) — Number of harsh cornering events attributed to this driver in the window.
- `harsh_brake_count` (integer, required) — Number of harsh braking events attributed to this driver in the window.
- `total_safety_event_count` (integer, required) — Total number of safety events of any kind attributed to this driver in the window, including types not broken out above (e.g. collisions, hard acceleration).
- `hos_violation_count` (integer, required) — Number of hours-of-service violations recorded against this driver in the window, counting every violation category. `0` means no violation was recorded, which for a driver whose provider does not report HOS is indistinguishable from full compliance.

### ValidationErrorDetail

- `path` (string, required)
- `input` (string, required)
- `message` (string, required)
- `error_type` (string, required)

### RetryAfterDetail

- `retry_after_seconds` (integer, required)
- `message` (string, required)

### DriverEmbeddedRead

Lightweight driver snapshot embedded in other API responses. Deliberately excludes personal contact details (`user_email`, `phone_number`) available on the underlying user record.

- `id` (string, required) — Unique identifier of the record at Catena Telematics.
- `first_name` (string, optional, nullable) — Driver's given name.
- `last_name` (string, optional, nullable) — Driver's family/surname.
- `username` (string, optional, nullable) — Unique username/login for the driver (source or Catena).
- `user_designation` (string, optional, nullable) — Role/title or TSP designation (e.g., 'DRIVER', 'DISPATCHER', 'ADMIN').
- `employee_number` (string, optional, nullable) — Employer/HR or payroll identifier for the driver (if applicable).
- `is_driver` (boolean, optional, nullable) — Indicates whether the user is a driver (vs. back-office/admin).
- `is_active` (boolean, optional, nullable) — Indicates whether the driver is currently active.
- `status` (string, optional, nullable) — User/account status label (e.g., 'ACTIVE', 'INACTIVE', 'SUSPENDED').
- `license_country` (string, optional, nullable) — Issuing country for the driver's license (ISO-3166-1 alpha-3, e.g., 'USA', 'CAN').
- `license_region` (string, optional, nullable) — Issuing region/subdivision for the license (state/province code, e.g., 'CA', 'ON').
- `license_number` (string, optional, nullable) — Driver's license number as recorded by the source.
- `license_expiration` (date, optional, nullable) — License expiration date (YYYY-MM-DD, local to issuing authority).
- `source_id` (string, optional, nullable) — Unique identifier of the record in the TSP.

## Examples

**Response**

```json
{
  "items": [
    {
      "driver": {
        "id": "string",
        "first_name": "string",
        "last_name": "string",
        "username": "string",
        "user_designation": "string",
        "employee_number": "string",
        "is_driver": true,
        "is_active": true,
        "status": "string",
        "license_country": "string",
        "license_region": "string",
        "license_number": "string",
        "license_expiration": "2023-01-15",
        "source_id": "string"
      },
      "fleet_refs": [
        "string"
      ],
      "fleet_ids": [
        "string"
      ],
      "speeding_event_count": 1,
      "harsh_turn_count": 1,
      "harsh_brake_count": 1,
      "total_safety_event_count": 1,
      "hos_violation_count": 1
    }
  ],
  "total": 1,
  "current_page": "string",
  "current_page_backwards": "string",
  "previous_page": "string",
  "next_page": "string"
}
```

**SDK Code**

```python
import requests

url = "https://api.catenatelematics.com/v2/intelligence/insurance/driver-signals"

headers = {"Authorization": "Bearer <token>"}

response = requests.get(url, headers=headers)

print(response.json())
```

```javascript
const url = 'https://api.catenatelematics.com/v2/intelligence/insurance/driver-signals';
const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.catenatelematics.com/v2/intelligence/insurance/driver-signals"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("Authorization", "Bearer <token>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.catenatelematics.com/v2/intelligence/insurance/driver-signals")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://api.catenatelematics.com/v2/intelligence/insurance/driver-signals")
  .header("Authorization", "Bearer <token>")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.catenatelematics.com/v2/intelligence/insurance/driver-signals', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.catenatelematics.com/v2/intelligence/insurance/driver-signals");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = ["Authorization": "Bearer <token>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.catenatelematics.com/v2/intelligence/insurance/driver-signals")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```