> For the complete documentation index, see [llms.txt](https://nexeum.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://nexeum.gitbook.io/docs/dutylogs/public-api.md).

# Public API

## Fetch Unit

<mark style="color:green;">`GET`</mark> `https://api.dutylogs.com/v1/public/units`

An endpoint to gather the details of a unit, with the option to include some metric data.

**Headers**

| Name          | Value                     |
| ------------- | ------------------------- |
| Content-Type  | `application/json`        |
| Authorization | `Bearer <public_api_key>` |

**Query Parameters**

| Name                 | Type    | Description                                                                    | Example               |
| -------------------- | ------- | ------------------------------------------------------------------------------ | --------------------- |
| `unit_id`            | integer | Unique Identifier for the Unit                                                 | `1234`                |
| `discord_id`         | string  | If you use `discord_id` instead of `unit_id`, you must specify the `entity_id` | `"123456789123456789` |
| `entity_id`          | string  | Entity Identifier, only used if you're using `discord_id` instead of `unit_id` | `"lspd"`              |
| `metrics [optional]` | boolean | Optionally include total active and afk time from past 14 days                 | `true`/`false`        |
| `actions [optional]` | boolean | Optionally include the actions received by the unit from the past 28 days      | `true`/`false`        |

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
  "id": 1232,
  "username": "Michael Scott",
  "callsign": "1234",
  "entity": "bcso",
  "entity_name": "Blaine County Sheriff's Office",
  "rank": "command_staff",
  "rank_name": "Command Staff",
  "equips_loadout": 0,
  "bodycam_status": null,
  "is_on_duty": 1,
  "last_on_duty": "2026-04-23T06:48:23.038Z",
  "last_on_duty_relative": "2 hours ago",
  "first_joined": "2025-11-14T03:34:56.204Z",
  "recent_actions": [],
  "is_suspended": false
}
```

{% endtab %}

{% tab title="200 \[Suspended]" %}

```json
{
  "id": 1232,
  "username": "Michael Scott",
  "callsign": "1234",
  "entity": "bcso",
  "entity_name": "Blaine County Sheriff's Office",
  "rank": "command_staff",
  "rank_name": "Command Staff",
  "equips_loadout": 0,
  "bodycam_status": null,
  "is_on_duty": 1,
  "last_on_duty": "2026-04-23T06:48:23.038Z",
  "last_on_duty_relative": "2 hours ago",
  "first_joined": "2025-11-14T03:34:56.204Z",
  "is_suspended": true,
  "suspended_till": "2026-04-27T12:08:30.000Z",
  "suspended_reason": "14",
  "suspended_till_relative": "in 3 days"
}
```

{% endtab %}

{% tab title="200 \[Metrics]" %}

```json
{
  "id": 1232,
  "username": "Michael Scott",
  "callsign": "1234",
  "entity": "bcso",
  "entity_name": "Blaine County Sheriff's Office",
  "rank": "command_staff",
  "rank_name": "Command Staff",
  "equips_loadout": 0,
  "bodycam_status": null,
  "is_on_duty": 1,
  "last_on_duty": "2026-04-23T06:48:23.038Z",
  "last_on_duty_relative": "2 hours ago",
  "first_joined": "2025-11-14T03:34:56.204Z",
  "total_active_time": "808",
  "total_afk_time": "30",
  "session_count": "10",
  "is_suspended": false
}
```

{% endtab %}

{% tab title="200 \[Actions]" %}

```json
{
  "id": 1232,
  "username": "Michael Scott",
  "callsign": "1234",
  "entity": "bcso",
  "entity_name": "Blaine County Sheriff's Office",
  "rank": "command_staff",
  "rank_name": "Command Staff",
  "equips_loadout": 0,
  "bodycam_status": null,
  "is_on_duty": 1,
  "last_on_duty": "2026-04-23T06:48:23.038Z",
  "last_on_duty_relative": "2 hours ago",
  "first_joined": "2025-11-14T03:34:56.204Z",
  "total_active_time": "808",
  "total_afk_time": "30",
  "session_count": "10",
  "recent_actions": [
      {
        "type": "suspend",
        "reason": "Reckless Endangerment with Service Equipment",
        "admin_id": 1235,
        "timestamp": "2026-04-08T06:58:21.253Z",
        "timestamp_relative": "16 days ago"
      },
      {
        "type": "send_off",
        "reason": "Reckless Driving",
        "admin_id": 1236,
        "timestamp": "2026-04-01T01:54:52.466Z",
        "timestamp_relative": "23 days ago"
      }
  ],
  "is_suspended": false
}
```

{% endtab %}

{% tab title="400" %}

```json
{
  "error": "missing_parameters",
  "explanation": "You must provide either unit_id or both discord_id and entity_id as query parameters."
}
```

{% endtab %}

{% tab title="404" %}

```json
{
  "error": "unit_not_found"
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" icon="rectangle-api" %}
Rate Limit: `5/minute`
{% endhint %}

## Fetch Unit Analytics

<mark style="color:green;">`GET`</mark> `https://api.dutylogs.com/v1/public/units/analytics`

An endpoint to gather the details of a unit, with the option to include some metric data.

**Headers**

| Name          | Value                     |
| ------------- | ------------------------- |
| Content-Type  | `application/json`        |
| Authorization | `Bearer <public_api_key>` |

**Query Parameters**

| Name         | Type    | Description                                                               | Example               |
| ------------ | ------- | ------------------------------------------------------------------------- | --------------------- |
| `unit_id`    | integer | Unique Identifier for the Unit                                            | `1234`                |
| `discord_id` | string  | If you provide `discord_ids`, you must provide an `entity_id`             | `"123456789123456789` |
| `entity_id`  | string  | An entity (department) identifier, required if you provide a `discord_id` | `"lspd"`              |
| `range`      | string  | The range: `days`, `weeks`                                                | `"weeks"`             |
| `period`     | integer | The period of days or weeks                                               | `4`                   |

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
  "id": 1234,
  "session_count": "2",
  "total_active_time": "203",
  "total_afk_time": "6",
  "last_on_duty": "2026-04-23T06:12:28.256Z",
  "last_on_duty_relative": "2 hours ago"
}
```

{% endtab %}

{% tab title="400" %}

```json
{
  "error": "missing_parameters",
  "explanation": "You must provide either unit_id or both discord_id and entity_id as query parameters."
}

{
  "error": "invalid_range",
  "explanation": "The range must be either week or days."
}

{
  "error": "invalid_period",
  "explanation": "The period must be an integer value."
}
```

{% endtab %}

{% tab title="404" %}

```json
{
  "error": "unit_not_found"
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" icon="rectangle-api" %}
Rate Limit: `10/minute`
{% endhint %}

## Fetch Unit Actions History

<mark style="color:green;">`GET`</mark> `https://api.dutylogs.com/v1/public/units/actions`

An endpoint to gather the actions history of a unit for the past 28 days, with the option for all time.

**Headers**

| Name          | Value                     |
| ------------- | ------------------------- |
| Content-Type  | `application/json`        |
| Authorization | `Bearer <public_api_key>` |

**Query Parameters**

| Name         | Type    | Description                                                               | Example               |
| ------------ | ------- | ------------------------------------------------------------------------- | --------------------- |
| `unit_id`    | integer | Unique Identifier for the Unit                                            | `1234`                |
| `discord_id` | string  | If you provide `discord_ids`, you must provide an `entity_id`             | `"123456789123456789` |
| `entity_id`  | string  | An entity (department) identifier, required if you provide a `discord_id` | `"lspd"`              |
| `all_time`   | boolean | Optionally extends the search to all time                                 | `true`/`false`        |

**Response**

{% tabs %}
{% tab title="200" %}

```json
[
  {
    "type": "suspend",
    "reason": "Reckless Endangerment with Service Equipment",
    "admin_id": 1235,
    "timestamp": "2026-04-08T06:58:21.253Z",
    "timestamp_relative": "16 days ago"
  },
  {
    "type": "send_off",
    "reason": "Reckless Driving",
    "admin_id": 1236,
    "timestamp": "2026-04-01T01:54:52.466Z",
    "timestamp_relative": "23 days ago"
  }
]
```

{% endtab %}

{% tab title="200 \[No Actions]" %}

```
[]
```

{% endtab %}

{% tab title="400" %}

```json
{
  "error": "missing_parameters",
  "explanation": "You must provide either unit_id or both discord_id and entity_id as query parameters."
}
```

{% endtab %}

{% tab title="404" %}

```json
{
  "error": "unit_not_found"
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" icon="rectangle-api" %}
Rate Limit: `5/minute`
{% endhint %}

## Bulk Fetch Unit Analytics

<mark style="color:blue;">`POST`</mark> `https://api.dutylogs.com/v1/public/units/analytics`

An endpoint to bulk gather the analytics of a collection of units.

**Headers**

| Name          | Value                     |
| ------------- | ------------------------- |
| Content-Type  | `application/json`        |
| Authorization | `Bearer <public_api_key>` |

**Query Parameters**

| Name        | Type    | Description                                               | Example   |
| ----------- | ------- | --------------------------------------------------------- | --------- |
| `entity_id` | string  | Entity Identifier, required if you're using `discord_ids` | `"lspd"`  |
| `range`     | string  | The range: `days`, `weeks`                                | `"weeks"` |
| `period`    | integer | The period of days or weeks                               | `4`       |

**Body**

| Name          | Type  | Description                                                   | Example                                                              |
| ------------- | ----- | ------------------------------------------------------------- | -------------------------------------------------------------------- |
| `unit_ids`    | array | An array of unit identifiers                                  | `["1234", "1235", "1236", "1237"]`                                   |
| `discord_ids` | array | If you provide `discord_ids`, you must provide an `entity_id` | `["123456789123456789", "123456789123456781", "123456789123456782"]` |

**Response**

{% tabs %}
{% tab title="200" %}

```json
[
  {
    "discord_id": "123456789123456789",
    "member_id": 1234,
    "last_on_duty_date": "2026-04-01T22:09:19.044Z",
    "last_on_duty": "22 days ago",
    "session_count": "3",
    "total_active_time": "20",
    "total_afk_time": "5"
  },
  {
    "discord_id": "123456789123456781",
    "member_id": 1235,
    "last_on_duty_date": "2026-04-20T00:50:29.598Z",
    "last_on_duty": "4 days ago",
    "session_count": "5",
    "total_active_time": "553",
    "total_afk_time": "55"
  },
  {
    "discord_id": "123456789123456782",
    "error": "unit_not_found"
  }
]

```

{% endtab %}

{% tab title="400" %}

```json
{
  "error": "missing_parameters",
  "explanation": "You must provide either unit_ids or both discord_ids and entity_id as query parameters."
}

{
  "error": "invalid_range",
  "explanation": "The range must be either week or days."
}

{
  "error": "invalid_period",
  "explanation": "The period must be an integer value."
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" icon="rectangle-api" %}
Rate Limit: `30/hour`
{% endhint %}

## Fetch Player

<mark style="color:green;">`GET`</mark> `https://api.dutylogs.com/v1/public/players`

An endpoint to gather the details of a player, with the option to include some metric data.

**Headers**

| Name          | Value                     |
| ------------- | ------------------------- |
| Content-Type  | `application/json`        |
| Authorization | `Bearer <public_api_key>` |

**Query Parameters**

| Name                 | Type    | Description                                                                    | Example               |
| -------------------- | ------- | ------------------------------------------------------------------------------ | --------------------- |
| `discord_id`         | string  | If you use `discord_id` instead of `unit_id`, you must specify the `entity_id` | `"123456789123456789` |
| `metrics [optional]` | boolean | Optionally include total active and afk time from past 14 days                 | `true`/`false`        |

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
  "id": 4,
  "username": "Michael Scott",
  "first_connected": "2025-09-13T14:40:34.653Z",
  "units": [
    {
      "id": 1234,
      "callsign": "103",
      "entity": "bcso",
      "entity_name": "Blaine County Sheriff's Office",
      "rank": "patrol",
      "rank_name": "Patrol",
      "first_joined": "2025-12-29T03:41:58.730Z",
      "last_on_duty": "2026-03-21T20:03:04.455Z",
      "last_on_duty_relative": "a month ago",
      "is_on_duty": 0,
      "is_suspended": false,
    },
    {
      "id": 1235,
      "callsign": "122",
      "entity": "lspd",
      "entity_name": "Los Santos Police Department",
      "rank": "leadership",
      "rank_name": "Leadership",
      "first_joined": "2026-01-30T00:10:36.611Z",
      "last_on_duty": "2026-03-14T19:10:37.988Z",
      "last_on_duty_relative": "a month ago",
      "is_on_duty": 0,
      "is_suspended": true,
      "suspended_till": "2026-04-27T12:08:30.000Z",
      "suspended_reason": "14",
      "suspended_till_relative": "in 3 days"
    },
    {
      "id": 1236,
      "callsign": null,
      "entity": "sams",
      "entity_name": "San Andreas Medical Services",
      "rank": "patrol",
      "rank_name": "Patrol",
      "first_joined": "2026-03-19T02:21:32.873Z",
      "last_on_duty": "2026-04-01T22:07:30.406Z",
      "last_on_duty_relative": "23 days ago",
      "is_on_duty": 0,
      "is_suspended": false,
    }
  ]
}
```

{% endtab %}

{% tab title="200 \[Metrics]" %}

```json
{
  "id": 4,
  "username": "Michael Scott",
  "first_connected": "2025-09-13T14:40:34.653Z",
  "units": [
    {
      "id": 1234,
      "callsign": "103",
      "entity": "bcso",
      "entity_name": "Blaine County Sheriff's Office",
      "rank": "patrol",
      "rank_name": "Patrol",
      "first_joined": "2025-12-29T03:41:58.730Z",
      "last_on_duty": "2026-03-21T20:03:04.455Z",
      "last_on_duty_relative": "a month ago",
      "is_on_duty": 0,
      "total_active_time": "271",
      "total_afk_time": "113",
      "session_count": "19",
      "is_suspended": false,
    },
    {
      "id": 1235,
      "callsign": "122",
      "entity": "lspd",
      "entity_name": "Los Santos Police Department",
      "rank": "leadership",
      "rank_name": "Leadership",
      "first_joined": "2026-01-30T00:10:36.611Z",
      "last_on_duty": "2026-03-14T19:10:37.988Z",
      "last_on_duty_relative": "a month ago",
      "is_on_duty": 0,
      "total_active_time": "126",
      "total_afk_time": "23",
      "session_count": "10",
      "is_suspended": true,
      "suspended_till": "2026-04-27T12:08:30.000Z",
      "suspended_reason": "14",
      "suspended_till_relative": "in 3 days"
    },
    {
      "id": 1236,
      "callsign": null,
      "entity": "sams",
      "entity_name": "San Andreas Medical Services",
      "rank": "patrol",
      "rank_name": "Patrol",
      "first_joined": "2026-03-19T02:21:32.873Z",
      "last_on_duty": "2026-04-01T22:07:30.406Z",
      "last_on_duty_relative": "23 days ago",
      "is_on_duty": 0,
      "total_active_time": "464",
      "total_afk_time": "89",
      "session_count": "25",
      "is_suspended": false,
    }
  ]
}
```

{% endtab %}

{% tab title="400" %}

```json
{
  "error": "missing_parameters",
  "explanation": "You must provide discord_id as a query parameter."
}
```

{% endtab %}

{% tab title="404" %}

```json
{
  "error": "player_not_found"
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" icon="rectangle-api" %}
Rate Limit: `5/minute`
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://nexeum.gitbook.io/docs/dutylogs/public-api.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
