> 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 %}
