fleet/docs/Contributing/API-for-contributors.md
Victor Lyuboslavsky 2520fc2179
Reduce server load for fleetd upgrade (#15606)
📺 Loom:
https://www.loom.com/share/9e17848963574af3aa10d426b450bcd0?sid=f8078293-c7e1-4864-a8a3-4cec996971f5

#15476 
#15540 
#15542

After upgrading fleetd, customer-blanco saw a spike in traffic and a
spike in DB connections. These fixes attempt to reduce the traffic and
DB load when fleetd is upgraded.

On the server, added fleet/device/{token}/ping endpoint to be used by
agents to check their token.

On the agent:
- Removed call to fleet/orbit/device_token unless token needs to be
updated.
- Changed call to fleet/device/{token}/desktop with a less resource
intensive call to fleet/device/{token}/ping
- Removed call to fleet/orbit/ping

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

<!-- Note that API documentation changes are now addressed by the
product design team. -->

- [x] Changes file added for user-visible changes in `changes/` or
`orbit/changes/`.
See [Changes
files](https://fleetdm.com/docs/contributing/committing-changes#changes-files)
for more information.
- [x] Manual QA for all new/changed functionality
  - For Orbit and Fleet Desktop changes:
- [x] Manual QA must be performed in the three main OSs, macOS, Windows
and Linux.
- [x] Auto-update manual QA, from released version of component to new
version (see [tools/tuf/test](../tools/tuf/test/README.md)).
2023-12-13 14:31:48 -06:00

94 KiB
Raw Blame History

API for contributors

This document includes the internal Fleet API routes that are helpful when developing or contributing to Fleet.

These endpoints are used by the Fleet UI, Fleet Desktop, and fleetctl clients and will frequently change to reflect current functionality.

If you are interested in gathering information from Fleet in a production environment, please see the public Fleet REST API documentation.

Packs

Scheduling queries in Fleet is the best practice for collecting data from hosts. To learn how to schedule queries, check out the docs here.

The API routes to control packs are supported for backwards compatibility.

Create pack

POST /api/v1/fleet/packs

Parameters

Name Type In Description
name string body Required. The pack's name.
description string body The pack's description.
host_ids list body A list containing the targeted host IDs.
label_ids list body A list containing the targeted label's IDs.
team_ids list body Available in Fleet Premium A list containing the targeted teams' IDs.

Example

POST /api/v1/fleet/packs

Request query parameters
{
  "description": "Collects osquery data.",
  "host_ids": [],
  "label_ids": [6],
  "name": "query_pack_1"
}
Default response

Status: 200

{
  "pack": {
    "created_at": "0001-01-01T00:00:00Z",
    "updated_at": "0001-01-01T00:00:00Z",
    "id": 17,
    "name": "query_pack_1",
    "description": "Collects osquery data.",
    "query_count": 0,
    "total_hosts_count": 223,
    "host_ids": [],
    "label_ids": [
      6
    ],
    "team_ids": []
  }
}

Modify pack

PATCH /api/v1/fleet/packs/{id}

Parameters

Name Type In Description
id integer path Required. The pack's id.
name string body The pack's name.
description string body The pack's description.
host_ids list body A list containing the targeted host IDs.
label_ids list body A list containing the targeted label's IDs.
team_ids list body Available in Fleet Premium A list containing the targeted teams' IDs.

Example

PATCH /api/v1/fleet/packs/{id}

Request query parameters
{
  "description": "MacOS hosts are targeted",
  "host_ids": [],
  "label_ids": [7]
}
Default response

Status: 200

{
  "pack": {
    "created_at": "2021-01-25T22:32:45Z",
    "updated_at": "2021-01-25T22:32:45Z",
    "id": 17,
    "name": "Title2",
    "description": "MacOS hosts are targeted",
    "query_count": 0,
    "total_hosts_count": 110,
    "host_ids": [],
    "label_ids": [
      7
    ],
    "team_ids": []
  }
}

Get pack

GET /api/v1/fleet/packs/{id}

Parameters

Name Type In Description
id integer path Required. The pack's id.

Example

GET /api/v1/fleet/packs/17

Default response

Status: 200

{
  "pack": {
    "created_at": "2021-01-25T22:32:45Z",
    "updated_at": "2021-01-25T22:32:45Z",
    "id": 17,
    "name": "Title2",
    "description": "MacOS hosts are targeted",
    "disabled": false,
    "type": null,
    "query_count": 0,
    "total_hosts_count": 110,
    "host_ids": [],
    "label_ids": [
      7
    ],
    "team_ids": []
  }
}

List packs

GET /api/v1/fleet/packs

Parameters

Name Type In Description
order_key string query What to order results by. Can be any column in the packs table.
order_direction string query Requires order_key. The direction of the order given the order key. Options include asc and desc. Default is asc.

Example

GET /api/v1/fleet/packs

Default response

Status: 200

{
  "packs": [
    {
      "created_at": "2021-01-05T21:13:04Z",
      "updated_at": "2021-01-07T19:12:54Z",
      "id": 1,
      "name": "pack_number_one",
      "description": "This pack has a description",
      "disabled": true,
      "query_count": 1,
      "total_hosts_count": 53,
      "host_ids": [],
      "label_ids": [
        8
      ],
      "team_ids": []
    },
    {
      "created_at": "2021-01-19T17:08:31Z",
      "updated_at": "2021-01-19T17:08:31Z",
      "id": 2,
      "name": "query_pack_2",
      "query_count": 5,
      "total_hosts_count": 223,
      "host_ids": [],
      "label_ids": [
        6
      ],
      "team_ids": []
    }
  ]
}

Delete pack

Delete pack by name.

DELETE /api/v1/fleet/packs/{name}

Parameters

Name Type In Description
name string path Required. The pack's name.

Example

DELETE /api/v1/fleet/packs/pack_number_one

Default response

Status: 200

Delete pack by ID

DELETE /api/v1/fleet/packs/id/{id}

Parameters

Name Type In Description
id integer path Required. The pack's ID.

Example

DELETE /api/v1/fleet/packs/id/1

Default response

Status: 200

Get scheduled queries in a pack

GET /api/v1/fleet/packs/{id}/scheduled

Parameters

Name Type In Description
id integer path Required. The pack's ID.

Example

GET /api/v1/fleet/packs/1/scheduled

Default response

Status: 200

{
  "scheduled": [
    {
      "created_at": "0001-01-01T00:00:00Z",
      "updated_at": "0001-01-01T00:00:00Z",
      "id": 49,
      "pack_id": 15,
      "name": "new_query",
      "query_id": 289,
      "query_name": "new_query",
      "query": "SELECT * FROM osquery_info",
      "interval": 456,
      "snapshot": false,
      "removed": true,
      "platform": "windows",
      "version": "4.6.0",
      "shard": null,
      "denylist": null
    },
    {
      "created_at": "0001-01-01T00:00:00Z",
      "updated_at": "0001-01-01T00:00:00Z",
      "id": 50,
      "pack_id": 15,
      "name": "new_title_for_my_query",
      "query_id": 288,
      "query_name": "new_title_for_my_query",
      "query": "SELECT * FROM osquery_info",
      "interval": 677,
      "snapshot": true,
      "removed": false,
      "platform": "windows",
      "version": "4.6.0",
      "shard": null,
      "denylist": null
    },
    {
      "created_at": "0001-01-01T00:00:00Z",
      "updated_at": "0001-01-01T00:00:00Z",
      "id": 51,
      "pack_id": 15,
      "name": "osquery_info",
      "query_id": 22,
      "query_name": "osquery_info",
      "query": "SELECT i.*, p.resident_size, p.user_time, p.system_time, time.minutes AS counter FROM osquery_info i, processes p, time WHERE p.pid = i.pid;",
      "interval": 6667,
      "snapshot": true,
      "removed": false,
      "platform": "windows",
      "version": "4.6.0",
      "shard": null,
      "denylist": null
    }
  ]
}

Add scheduled query to a pack

POST /api/v1/fleet/schedule

Parameters

Name Type In Description
pack_id integer body Required. The pack's ID.
query_id integer body Required. The query's ID.
interval integer body Required. The amount of time, in seconds, the query waits before running.
snapshot boolean body Required. Whether the queries logs show everything in its current state.
removed boolean body Required. Whether "removed" actions should be logged.
platform string body The computer platform where this query will run (other platforms ignored). Empty value runs on all platforms.
shard integer body Restrict this query to a percentage (1-100) of target hosts.
version string body The minimum required osqueryd version installed on a host.

Example

POST /api/v1/fleet/schedule

Request body

{
  "interval": 120,
  "pack_id": 15,
  "query_id": 23,
  "removed": true,
  "shard": null,
  "snapshot": false,
  "version": "4.5.0",
  "platform": "windows"
}
Default response

Status: 200

{
  "scheduled": {
    "created_at": "0001-01-01T00:00:00Z",
    "updated_at": "0001-01-01T00:00:00Z",
    "id": 56,
    "pack_id": 17,
    "name": "osquery_events",
    "query_id": 23,
    "query_name": "osquery_events",
    "query": "SELECT name, publisher, type, subscriptions, events, active FROM osquery_events;",
    "interval": 120,
    "snapshot": false,
    "removed": true,
    "platform": "windows",
    "version": "4.5.0",
    "shard": 10
  }
}

Get scheduled query

GET /api/v1/fleet/schedule/{id}

Parameters

Name Type In Description
id integer path Required. The scheduled query's ID.

Example

GET /api/v1/fleet/schedule/56

Default response

Status: 200

{
  "scheduled": {
    "created_at": "0001-01-01T00:00:00Z",
    "updated_at": "0001-01-01T00:00:00Z",
    "id": 56,
    "pack_id": 17,
    "name": "osquery_events",
    "query_id": 23,
    "query_name": "osquery_events",
    "query": "SELECT name, publisher, type, subscriptions, events, active FROM osquery_events;",
    "interval": 120,
    "snapshot": false,
    "removed": true,
    "platform": "windows",
    "version": "4.5.0",
    "shard": 10,
    "denylist": null
  }
}

Modify scheduled query

PATCH /api/v1/fleet/schedule/{id}

Parameters

Name Type In Description
id integer path Required. The scheduled query's ID.
interval integer body The amount of time, in seconds, the query waits before running.
snapshot boolean body Whether the queries logs show everything in its current state.
removed boolean body Whether "removed" actions should be logged.
platform string body The computer platform where this query will run (other platforms ignored). Empty value runs on all platforms.
shard integer body Restrict this query to a percentage (1-100) of target hosts.
version string body The minimum required osqueryd version installed on a host.

Example

PATCH /api/v1/fleet/schedule/56

Request body

{
  "platform": ""
}
Default response

Status: 200

{
  "scheduled": {
    "created_at": "2021-01-28T19:40:04Z",
    "updated_at": "2021-01-28T19:40:04Z",
    "id": 56,
    "pack_id": 17,
    "name": "osquery_events",
    "query_id": 23,
    "query_name": "osquery_events",
    "query": "SELECT name, publisher, type, subscriptions, events, active FROM osquery_events;",
    "interval": 120,
    "snapshot": false,
    "removed": true,
    "platform": "",
    "version": "4.5.0",
    "shard": 10
  }
}

Delete scheduled query

DELETE /api/v1/fleet/schedule/{id}

Parameters

Name Type In Description
id integer path Required. The scheduled query's ID.

Example

DELETE /api/v1/fleet/schedule/56

Default response

Status: 200


Mobile device management (MDM)

Only Fleet MDM specific endpoints are located within the root /mdm/ path.

The MDM endpoints exist to support the related command-line interface sub-commands of fleetctl, such as fleetctl generate mdm-apple and fleetctl get mdm-apple, as well as the Fleet UI.

Generate Apple DEP Key Pair

Parameters

None.

Example

POST /api/v1/fleet/mdm/apple/dep/key_pair

Default response
{
  "public_key": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNzVENDQVptZ0F3SUJBZ0lCQVRBTkJna3Foa2lHOXcwQkFRc0ZBREFTTVJBd0RnWURWUVFERXdkR2JHVmwKZEVSTk1CNFhEVEl5TVRJeE16RTFNREl6TmxvWERUSXpNREV4TWpFMU1USXpObG93RWpFUU1BNEdBMVVFQXhNSApSbXhsWlhSRVRUQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQU1jbXIxOVNiQUhaCnVZNnJBa254dVBCV0tkSFlrSXpJY2JGMHErZ0ZKZVU3cUlwU0FQWFhmeUpFTXpyQXhpZStPSi9QSXhkTHZTZVoKdXA2Qzg5VHM1VEwrWjhKZmR3T2ZLQVFIUWpyQVpGZkxkdUh0SjNRZnk3di9rbmZ3VzNNSU9XZ00zcDQ3a0xzOAowZnJzNmVuTlpXZElsNUMyV1NpOXVGVVVQcFJTbm1Ha1AvK2QydmNCaWdIOHQ0K3RuV3NYdjhpekxqcHhhanV6CjN0Vlp3SFA0cjBQZTdIM0I0eDZINmlKZmxRZzI4Z3owbDZWa0c2NjVKT2NMLzlDSmNtOWpWRmpxb0RmZTVjUFAKMVFNbFpyb1FCaFhOUHN3bEhRWTkzekJFK3VSRUVNL1N1d0dZcGZLYjQwSDM0S1B1U3Y5SXZHTjIzTXdNM01FMwppNEFBWGJQOGZNTUNBd0VBQWFNU01CQXdEZ1lEVlIwUEFRSC9CQVFEQWdXZ01BMEdDU3FHU0liM0RRRUJDd1VBCkE0SUJBUUM5ZFcyRXBxemp1VWhhbk1CSXJpK09VWVhrekR2eVB6bGxTMXd0UVdQQ0s4cFJ5Rk5TM3RkakVXT2kKSTcyOVh2UmtpNjhNZStqRlpxSkxFWHpWUlkwb29aSWhhcG5lNUZoNzlCbkIrWGl6TFQ0TStDNHJ5RVQwOXg4SQpaWHJuY1BKME9ueUdVemlFK0szWEI2dVNLeWN1a3pZci9sRVBBMGlQRTZpM0dNYjljenJFL2NOQURrRXZwcjU2CjN1SFdMU3hwK1U5QmJyaTNDSXBoR1NvSWxnTVBEaUE1RkpiOXc0SnlMK0crZ3Q4c1BlcUZkZDYyRDRpV3U5a0wKMVZBUjRSU2xPcWt1cTVXREZVcUxsVGJFMS9oY1lqcVVUczRrSWhENmN6MkcxQlBnMUU2WVpRZWp6U0ZpeGR1MApYUy9UTTByUFBKNithUC82V1BNRWpJcGVRcmNvCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K",
  "private_key": "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBeHlhdlgxSnNBZG01anFzQ1NmRzQ4RllwMGRpUWpNaHhzWFNyNkFVbDVUdW9pbElBCjlkZC9Ja1F6T3NER0o3NDRuODhqRjB1OUo1bTZub0x6MU96bE12NW53bDkzQTU4b0JBZENPc0JrVjh0MjRlMG4KZEIvTHUvK1NkL0JiY3dnNWFBemVuanVRdXp6Uit1enA2YzFsWjBpWGtMWlpLTDI0VlJRK2xGS2VZYVEvLzUzYQo5d0dLQWZ5M2o2MmRheGUveUxNdU9uRnFPN1BlMVZuQWMvaXZROTdzZmNIakhvZnFJbCtWQ0RieURQU1hwV1FiCnJya2s1d3YvMElseWIyTlVXT3FnTjk3bHc4L1ZBeVZtdWhBR0ZjMCt6Q1VkQmozZk1FVDY1RVFRejlLN0FaaWwKOHB2alFmZmdvKzVLLzBpOFkzYmN6QXpjd1RlTGdBQmRzL3g4d3dJREFRQUJBb0lCQUZRMUFFeGU3bnB0MUc4RgowZ2J3SlpIQjdSYms2bUlNMHo0RXBqZUtEYmI2M2MzMjFKOGV5b3Z6cUhHOFYwMHd1b0tnTkNkQ2lDMjVhOVpnCmFyZHFuNU5MVFJZOEJYZkxrVUQ2ekw5STRHVGJERjZGUjN4cmdWcnh1cjNxTE5EYjltSVBwd1hqQzlTUDUvMmcKdFZ0OTFOV3lOUndrYmxpeXQ4R0p1TmhBZ3VXbnJLQmw5b3o1QkpCU3JLZTJPUE5ERm5mbUs1NFM1VzRKakZZMApFTUV3Z2ZiL2xQZjluWFZwRG9QeEl3QnJmRU5oU3oxcVI0bzJPbVFyRGNOQUNZU05razRjbXVIMHpxc3J5aFg4CkNhajhCcllOemxaeGNPTmpmK1NxUkdvVndjdzZKbzNKazBEREZHeEVaOHBEUThJTXgzRUQ1SE4rbW1SaGRMQmoKT0pRZVhVRUNnWUVBeWZDaFArSVNzMGNtcEM3WUFrK1UrVHNTTElnY3BTTHdReFF2RGFmRWFtMHJoWDJQdDk1ZgpJN1NCTlM3TmlNR0xCVk4rWHg0RHlsT3RYaGNzTm5YUU5qU3J3ZFNHTGxFbU5wWDJXR0x4Znp4REVVbFFSS3FEClY2RHBDaHdmY2tCTFRUNkVaRDlnV21DOGZIYUNPc0JDUHR1VStLQUpFa1FRaVk1VlRLSjYrMkVDZ1lFQS9IYnQKKzIvWFJzSW84VkE4QmhjMitDYyt4YUNrK3dvTVByZ0d4OWxrMTR2R0hDcCtDY2ZGZThqU2NHMDhzU3RKTnJCVgp0cHgvbm1yYklyMzUxVkxlMFNLQ2R2aHF5ajBXQWlWVDhDL0VjcUxGV0VwNG5mY1ZnVHIxRjBGMUptR0Y4WVNYCk41VEh4Tnc4VjZLUDVmWEM2dVVFMkNpZnR1bkxqSGFSNXZCakxxTUNnWUVBdlNjTE0zYUVRNjlTejVrZE5sVHEKMnVUczZnOTRuV256bVRGdnZaKzJ5R1dIelp0R0lsbEZ6b0VHUWhXYjZndzROdjMxTWcxQVNhVkZrQXV1bXppUgpsaVNSK1pZak5ZRkhoUHZFNnhlSzA3NVRwLzUvRkVLUGttWWp3eGVDa1JjT01jVnNaeVpDRDRYcko3NHR6L0JFClhQSjdRTU5PbS9CcmVSMThZck1TOVNFQ2dZQjhqZnhaV1ZNL1FKbE1mTVl3UnhIQ21qSVk5R21ReE9OSHFpa0cKUGhYSFZkazJtaXcyalEyOFJWYTFTdDl2bFNoNHg4Ung1SUg5MlVBbHdzNVlWWnRDV0tFL0tzNGMyc2haNUtxbAp6QnRDWjFXdmVvWkpnTlptUEgwZ3JSV3NDdDgzU2JBRkp1enNEYS9qbUhzZi9BRGZQSUFJV1BwN0ZwdHF3REM1ClhBM0N1d0tCZ0c0QVVmMUZralNYRFBlL2JoVjhtZG4rZCtzN2g2RjZkRWttNnEya1dyS1B4V2lFdlN3QlZEQWoKQjhIRlNtNW1pcHNTTXhQbFVEZDRPSXRSUzVUM1AwcStRZENZNkwzemhmSFBCUzdhTlZaRUJXdVNlY2lDRk0wSQo3MjFSK081TitMTlFwN1N6VWUxRll1WWdhandFSE9KMW82d1ArZWloMmQyVVQyQ09Ed1NrCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg=="
}

Note that the public_key and private_key are base64 encoded and should be decoded before writing them to files.

Request Certificate Signing Request (CSR)

POST /api/v1/fleet/mdm/apple/request_csr

Parameters

Name Type In Description
email_address string body Required. The email that will be associated with the Apple APNs certificate.
organization string body Required. The name of the organization associated with the Apple APNs certificate.

Example

POST /api/v1/fleet/mdm/apple/request_csr

Default response
{
  "apns_key": "aGV5LCBJJ20gc2VjcmV0Cg==",
  "scep_cert": "bHR5LCBJJ20gc2VjcmV0Cg=",
  "scep_key": "lKT5LCBJJ20gc2VjcmV0Cg="
}

Note that the response fields are base64 encoded and should be decoded before writing them to files. Once base64-decoded, they are PEM-encoded certificate and keys.

Batch-apply Apple MDM custom settings

POST /api/v1/fleet/mdm/apple/profiles/batch

Parameters

Name Type In Description
team_id number query Available in Fleet Premium The team ID to apply the custom settings to. Only one of team_name/team_id can be provided.
team_name string query Available in Fleet Premium The name of the team to apply the custom settings to. Only one of team_name/team_id can be provided.
dry_run bool query Validate the provided profiles and return any validation errors, but do not apply the changes.
profiles json body An array of strings, the base64-encoded .mobileconfig files to apply.

If no team (id or name) is provided, the profiles are applied for all hosts (for Fleet Free) or for hosts that are not part of a team (for Fleet Premium). After the call, the provided list of profiles will be the active profiles for that team (or no team) - that is, any existing profile that is not part of that list will be removed, and an existing profile with the same payload identifier as a new profile will be edited. If the list of provided profiles is empty, all profiles are removed for that team (or no team).

Example

POST /api/v1/fleet/mdm/apple/profiles/batch

Default response

204

Initiate SSO during DEP enrollment

This endpoint initiates the SSO flow, the response contains an URL that the client can use to redirect the user to initiate the SSO flow in the configured IdP.

POST /api/v1/fleet/mdm/sso

Parameters

None.

Example

POST /api/v1/fleet/mdm/sso

Default response
{
  "url": "https://idp-provider.com/saml?SAMLRequest=...",
}

Complete SSO during DEP enrollment

This is the callback endpoint that the identity provider will use to send security assertions to Fleet. This is where Fleet receives and processes the response from the identify provider.

POST /api/v1/fleet/mdm/sso/callback

Parameters

Name Type In Description
SAMLResponse string body Required. The SAML response from the identity provider.

Example

POST /api/v1/fleet/mdm/sso/callback

Request body
{
  "SAMLResponse": "<SAML response from IdP>"
}
Default response

Status: 302

If the credentials are valid, the server redirects the client to the Fleet UI. The URL contains the following query parameters that can be used to complete the DEP enrollment flow:

  • enrollment_reference a reference that must be passed along with profile_token to the endpoint to download an enrollment profile.
  • profile_token is a token that can be used to download an enrollment profile (.mobileconfig).
  • eula_token (optional) if an EULA was uploaded, this contains a token that can be used to view the EULA document.

Preassign profiles to devices

Available in Fleet Premium

This endpoint stores a profile to be assigned to a host at some point in the future. The actual assignment happens when the Match preassigned profiles endpoint is called. The reason for this "pre-assign" step is to collect all profiles that are meant to be assigned to a host, and match the list of profiles to an existing team (or create one with that set of profiles if none exist) so that the host can be assigned to that team and inherit its list of profiles.

POST /api/v1/fleet/mdm/apple/profiles/preassign

Parameters

Name Type In Description
external_host_identifier string body Required. The identifier of the host as generated by the external service (e.g. Puppet).
host_uuid string body Required. The UUID of the host.
profile string body Required. The base64-encoded .mobileconfig content of the MDM profile.
group string body The group label associated with that profile. This information is used to generate team names if they need to be created.
exclude boolean body Whether to skip delivering the profile to this host.

Example

POST /api/v1/fleet/mdm/apple/profiles/preassign

Request body
{
  "external_host_identifier": "id-01234",
  "host_uuid": "c0532a64-bec2-4cf9-aa37-96fe47ead814",
  "profile": "<base64-encoded profile>",
  "group": "Workstations",
  "exclude": false
}
Default response

Status: 204

Get FileVault statistics

Available in Fleet Premium

Get aggregate status counts of disk encryption enforced on macOS hosts.

The summary can optionally be filtered by team id.

GET /api/v1/fleet/mdm/apple/filevault/summary

Parameters

Name Type In Description
team_id string query Available in Fleet Premium The team id to filter the summary.

Example

Get aggregate status counts of Apple disk encryption profiles applying to macOS hosts enrolled to Fleet's MDM that are not assigned to any team.

GET /api/v1/fleet/mdm/apple/filevault/summary

Default response

Status: 200

{
  "verified": 123,
  "verifying": 123,
  "action_required": 123,
  "enforcing": 123,
  "failed": 123,
  "removing_enforcement": 123
}

Match preassigned profiles

Available in Fleet Premium

This endpoint uses the profiles stored by the Preassign profiles to devices endpoint to match the set of profiles to an existing team if possible, creating one if none exists. It then assigns the host to that team so that it receives the associated profiles. It is meant to be called only once all desired profiles have been pre-assigned to the host.

POST /api/v1/fleet/mdm/apple/profiles/match

Parameters

Name Type In Description
external_host_identifier string body Required. The identifier of the host as generated by the external service (e.g. Puppet).

Example

POST /api/v1/fleet/mdm/apple/profiles/match

Request body
{
  "external_host_identifier": "id-01234"
}
Default response

Status: 204

Get or apply configuration files

These API routes are used by the fleetctl CLI tool. Users can manage Fleet with fleetctl and configuration files in YAML syntax.

Get queries

Returns a list of all queries in the Fleet instance. Each item returned includes the name, description, and SQL of the query.

GET /api/v1/fleet/spec/queries

Parameters

None.

Example

GET /api/v1/fleet/spec/queries

Default response

Status: 200

{
  "specs": [
    {
      "name": "query1",
      "description": "query",
      "query": "SELECT * FROM osquery_info"
    },
    {
      "name": "osquery_schedule",
      "description": "Report performance stats for each file in the query schedule.",
      "query": "SELECT name, interval, executions, output_size, wall_time, (user_time/executions) AS avg_user_time, (system_time/executions) AS avg_system_time, average_memory, last_executed FROM osquery_schedule;"
    }
]
}

Get query

Returns the name, description, and SQL of the query specified by name.

GET /api/v1/fleet/spec/queries/{name}

Parameters

Name Type In Description
name string path Required. The name of the query.

Example

GET /api/v1/fleet/spec/queries/query1

Default response

Status: 200

{
  "specs": {
    "name": "query1",
    "description": "query",
    "query": "SELECT * FROM osquery_info"
  }
}

Apply queries

Creates and/or modifies the queries included in the list. To modify an existing query, the name of the query must already be used by an existing query. If a query with the specified name doesn't exist in Fleet, a new query will be created.

If a query field is not specified in the "spec" then its default value depending on its type will be assumed, e.g. if interval is not set then 0 will be assumed, if discard_data is omitted then false will be assumed, etc.

POST /api/v1/fleet/spec/queries

Parameters

Name Type In Description
specs list body Required. The list of the queries to be created or modified.

For more information about the query fields, please refer to the Create query endpoint.

Example

POST /api/v1/fleet/spec/queries

Request body
{
  "specs": [
    {
      "name": "new_query",
      "description": "This will be a new query because a query with the name 'new_query' doesn't exist in Fleet.",
      "query": "SELECT * FROM osquery_info"
    },
    {
      "name": "osquery_schedule",
      "description": "This queries description and SQL will be modified because a query with the name 'osquery_schedule' exists in Fleet.",
      "query": "SELECT * FROM osquery_info"
    }
  ]
}
Default response

Status: 200

Get packs

Returns all packs in the Fleet instance.

GET /api/v1/fleet/spec/packs

Example

GET /api/v1/fleet/spec/packs

Default response

Status: 200

{
  "specs": [
    {
      "id": 1,
      "name": "pack_1",
      "description": "Description",
      "disabled": false,
      "targets": {
        "labels": ["All Hosts"],
        "teams": null
      },
      "queries": [
        {
          "query": "new_query",
          "name": "new_query",
          "description": "",
          "interval": 456,
          "snapshot": false,
          "removed": true,
          "platform": "windows",
          "version": "4.5.0"
        },
        {
          "query": "new_title_for_my_query",
          "name": "new_title_for_my_query",
          "description": "",
          "interval": 677,
          "snapshot": true,
          "removed": false,
          "platform": "",
          "version": ""
        },
        {
          "query": "osquery_info",
          "name": "osquery_info",
          "description": "",
          "interval": 6667,
          "snapshot": true,
          "removed": false,
          "platform": "",
          "version": ""
        },
        {
          "query": "query1",
          "name": "query1",
          "description": "",
          "interval": 7767,
          "snapshot": false,
          "removed": true,
          "platform": "",
          "version": ""
        },
        {
          "query": "osquery_events",
          "name": "osquery_events",
          "description": "",
          "interval": 454,
          "snapshot": false,
          "removed": true,
          "platform": "",
          "version": ""
        },
        {
          "query": "osquery_events",
          "name": "osquery_events-1",
          "description": "",
          "interval": 120,
          "snapshot": false,
          "removed": true,
          "platform": "",
          "version": ""
        }
      ]
    },
    {
      "id": 2,
      "name": "pack_2",
      "disabled": false,
      "targets": {
        "labels": null,
        "teams": null
      },
      "queries": [
        {
          "query": "new_query",
          "name": "new_query",
          "description": "",
          "interval": 333,
          "snapshot": false,
          "removed": true,
          "platform": "windows",
          "version": "4.5.0",
          "shard": 10,
          "denylist": null
        }
      ]
    }
  ]
}

Apply policies

Creates and/or modifies the policies included in the list. To modify an existing policy, the name of the policy included in the list must already be used by an existing policy. If a policy with the specified name doesn't exist in Fleet, a new policy will be created.

NOTE: when updating a policy, team and platform will be ignored.

POST /api/v1/fleet/spec/policies

Parameters

Name Type In Description
specs list body Required. The list of the policies to be created or modified.

Example

POST /api/v1/fleet/spec/policies

Request body
{
  "specs": [
    {
      "name": "new policy",
      "description": "This will be a new policy because a policy with the name 'new policy' doesn't exist in Fleet.",
      "query": "SELECT * FROM osquery_info",
      "resolution": "some resolution steps here",
      "critical": false
    },
    {
      "name": "Is FileVault enabled on macOS devices?",
      "query": "SELECT 1 FROM disk_encryption WHERE user_uuid IS NOT “” AND filevault_status = on LIMIT 1;",
      "description": "Checks to make sure that the FileVault feature is enabled on macOS devices.",
      "resolution": "Choose Apple menu > System Preferences, then click Security & Privacy. Click the FileVault tab. Click the Lock icon, then enter an administrator name and password. Click Turn On FileVault.",
      "platform": "darwin",
      "critical": true
    }
  ]
}

The field critical is available in Fleet Premium.

Default response

Status: 200

Apply packs

Creates and/or modifies the packs included in the list.

POST /api/v1/fleet/spec/packs

Parameters

Name Type In Description
specs list body Required. A list that includes the specs for each pack to be added to the Fleet instance.

Example

POST /api/v1/fleet/spec/packs

Request body
{
  "specs": [
    {
      "id": 1,
      "name": "pack_1",
      "description": "Description",
      "disabled": false,
      "targets": {
        "labels": ["All Hosts"],
        "teams": null
      },
      "queries": [
        {
          "query": "new_query",
          "name": "new_query",
          "description": "",
          "interval": 456,
          "snapshot": false,
          "removed": true
        },
        {
          "query": "new_title_for_my_query",
          "name": "new_title_for_my_query",
          "description": "",
          "interval": 677,
          "snapshot": true,
          "removed": false
        },
        {
          "query": "osquery_info",
          "name": "osquery_info",
          "description": "",
          "interval": 6667,
          "snapshot": true,
          "removed": false
        },
        {
          "query": "query1",
          "name": "query1",
          "description": "",
          "interval": 7767,
          "snapshot": false,
          "removed": true
        },
        {
          "query": "osquery_events",
          "name": "osquery_events",
          "description": "",
          "interval": 454,
          "snapshot": false,
          "removed": true
        },
        {
          "query": "osquery_events",
          "name": "osquery_events-1",
          "description": "",
          "interval": 120,
          "snapshot": false,
          "removed": true
        }
      ]
    },
    {
      "id": 2,
      "name": "pack_2",
      "disabled": false,
      "targets": {
        "labels": null,
        "teams": null
      },
      "queries": [
        {
          "query": "new_query",
          "name": "new_query",
          "description": "",
          "interval": 333,
          "snapshot": false,
          "removed": true,
          "platform": "windows"
        }
      ]
    }
  ]
}
Default response

Status: 200

Get pack by name

Returns a pack.

GET /api/v1/fleet/spec/packs/{name}

Parameters

Name Type In Description
name string path Required. The pack's name.

Example

GET /api/v1/fleet/spec/packs/pack_1

Default response

Status: 200

{
  "specs": {
    "id": 15,
    "name": "pack_1",
    "description": "Description",
    "disabled": false,
    "targets": {
      "labels": ["All Hosts"],
      "teams": null
    },
    "queries": [
      {
        "query": "new_title_for_my_query",
        "name": "new_title_for_my_query",
        "description": "",
        "interval": 677,
        "snapshot": true,
        "removed": false,
        "platform": "",
        "version": ""
      },
      {
        "query": "osquery_info",
        "name": "osquery_info",
        "description": "",
        "interval": 6667,
        "snapshot": true,
        "removed": false,
        "platform": "",
        "version": ""
      },
      {
        "query": "query1",
        "name": "query1",
        "description": "",
        "interval": 7767,
        "snapshot": false,
        "removed": true,
        "platform": "",
        "version": ""
      },
      {
        "query": "osquery_events",
        "name": "osquery_events",
        "description": "",
        "interval": 454,
        "snapshot": false,
        "removed": true,
        "platform": "",
        "version": ""
      },
      {
        "query": "osquery_events",
        "name": "osquery_events-1",
        "description": "",
        "interval": 120,
        "snapshot": false,
        "removed": true,
        "platform": "",
        "version": ""
      }
    ]
  }
}

Apply team

Available in Fleet Premium

If the name specified is associated with an existing team, this API route, completely replaces this team's existing agent_options and secrets with those that are specified.

If the name is not already associated with an existing team, this API route creates a new team with the specified name, agent_options, and secrets.

POST /api/v1/fleet/spec/teams

Parameters

Name Type In Description
name string body Required. The team's name.
agent_options object body The agent options spec that is applied to the hosts assigned to the specified to team. These agent options completely override the global agent options specified in the GET /api/v1/fleet/config API route
features object body The features that are applied to the hosts assigned to the specified to team. These features completely override the global features specified in the GET /api/v1/fleet/config API route
secrets list body A list of plain text strings is used as the enroll secrets. Existing secrets are replaced with this list, or left unmodified if this list is empty. Note that there is a limit of 50 secrets allowed.
mdm object body The team's MDM configuration options.
mdm.macos_updates object body The OS updates macOS configuration options for Nudge.
mdm.macos_updates.minimum_version string body The required minimum operating system version.
mdm.macos_updates.deadline string body The required installation date for Nudge to enforce the operating system version.
mdm.macos_settings object body The macOS-specific MDM settings.
mdm.macos_settings.custom_settings list body The list of .mobileconfig files to apply to hosts that belong to this team.
scripts list body A list of script files to add to this team so they can be executed at a later time.
mdm.macos_settings.enable_disk_encryption bool body Whether disk encryption should be enabled for hosts that belong to this team.
mdm.windows_settings object body The Windows-specific MDM settings.
mdm.windows_settings.custom_settings list body The list of .xml files to apply to hosts that belong to this team.
force bool query Force apply the spec even if there are (ignorable) validation errors. Those are unknown keys and agent options-related validations.
dry_run bool query Validate the provided JSON for unknown keys and invalid value types and return any validation errors, but do not apply the changes.

Example

POST /api/v1/fleet/spec/teams

Request body
{
  "specs": [
    {
      "name": "Client Platform Engineering",
      "features": {
        "enable_host_users": false,
        "enable_software_inventory": true,
        "additional_queries": {
          "foo": "SELECT * FROM bar;"
        }
      },
      "agent_options": {
        "spec": {
          "config": {
            "options": {
              "pack_delimiter": "/",
              "logger_tls_period": 10,
              "distributed_plugin": "tls",
              "disable_distributed": false,
              "logger_tls_endpoint": "/api/v1/osquery/log",
              "distributed_interval": 10,
              "distributed_tls_max_attempts": 3
            },
            "decorators": {
              "load": [
                "SELECT uuid AS host_uuid FROM system_info;",
                "SELECT hostname AS hostname FROM system_info;"
              ]
            }
          },
          "overrides": {}
        }
      },
      "secrets": [
        {
          "secret": "fTp52/twaxBU6gIi0J6PHp8o5Sm1k1kn"
        },
        {
          "secret": "bhD5kiX2J+KBgZSk118qO61ZIdX/v8On"
        }
      ],
      "mdm": {
        "macos_updates": {
          "minimum_version": "12.3.1",
          "deadline": "2023-12-01"
        },
        "macos_settings": {
          "custom_settings": ["path/to/profile1.mobileconfig"],
          "enable_disk_encryption": true
        },
        "windows_settings": {
          "custom_settings": ["path/to/profile2.xml"],
        }
      },
      "scripts": ["path/to/script.sh"],
    }
  ]
}

Default response

Status: 200

{
  "team_ids_by_name": {
    "Client Platform Engineering": 123
  }
}

Apply labels

Adds the supplied labels to Fleet. Each label requires the name, and label_membership_type properties.

If the label_membership_type is set to dynamic, the query property must also be specified with the value set to a query in SQL syntax.

If the label_membership_type is set to manual, the hosts property must also be specified with the value set to a list of hostnames.

POST /api/v1/fleet/spec/labels

Parameters

Name Type In Description
specs list path A list of the label to apply. Each label requires the name, query, and label_membership_type properties

Example

POST /api/v1/fleet/spec/labels

Request body
{
  "specs": [
    {
      "name": "Ubuntu",
      "description": "Filters Ubuntu hosts",
      "query": "SELECT 1 FROM os_version WHERE platform = 'ubuntu';",
      "label_membership_type": "dynamic"
    },
    {
      "name": "local_machine",
      "description": "Includes only my local machine",
      "label_membership_type": "manual",
      "hosts": ["snacbook-pro.local"]
    }
  ]
}
Default response

Status: 200

Get labels

GET /api/v1/fleet/spec/labels

Parameters

None.

Example

GET /api/v1/fleet/spec/labels

Default response

Status: 200

{
  "specs": [
    {
      "id": 6,
      "name": "All Hosts",
      "description": "All hosts which have enrolled in Fleet",
      "query": "SELECT 1;",
      "label_type": "builtin",
      "label_membership_type": "dynamic"
    },
    {
      "id": 7,
      "name": "macOS",
      "description": "All macOS hosts",
      "query": "SELECT 1 FROM os_version WHERE platform = 'darwin';",
      "platform": "darwin",
      "label_type": "builtin",
      "label_membership_type": "dynamic"
    },
    {
      "id": 8,
      "name": "Ubuntu Linux",
      "description": "All Ubuntu hosts",
      "query": "SELECT 1 FROM os_version WHERE platform = 'ubuntu';",
      "platform": "ubuntu",
      "label_type": "builtin",
      "label_membership_type": "dynamic"
    },
    {
      "id": 9,
      "name": "CentOS Linux",
      "description": "All CentOS hosts",
      "query": "SELECT 1 FROM os_version WHERE platform = 'centos' OR name LIKE '%centos%'",
      "label_type": "builtin",
      "label_membership_type": "dynamic"
    },
    {
      "id": 10,
      "name": "MS Windows",
      "description": "All Windows hosts",
      "query": "SELECT 1 FROM os_version WHERE platform = 'windows';",
      "platform": "windows",
      "label_type": "builtin",
      "label_membership_type": "dynamic"
    },
    {
      "id": 11,
      "name": "Ubuntu",
      "description": "Filters Ubuntu hosts",
      "query": "SELECT 1 FROM os_version WHERE platform = 'ubuntu';",
      "label_membership_type": "dynamic"
    }
  ]
}

Get label

Returns the label specified by name.

GET /api/v1/fleet/spec/labels/{name}

Parameters

None.

Example

GET /api/v1/fleet/spec/labels/local_machine

Default response

Status: 200

{
  "specs": {
    "id": 12,
    "name": "local_machine",
    "description": "Includes only my local machine",
    "query": "",
    "label_membership_type": "manual"
  }
}

Get enroll secrets

Returns the valid global enroll secrets.

GET /api/v1/fleet/spec/enroll_secret

Parameters

None.

Example

GET /api/v1/fleet/spec/enroll_secret

Default response

Status: 200

{
  "spec": {
    "secrets": [
      {
        "secret": "fTp52/twaxBU6gIi0J6PHp8o5Sm1k1kn",
        "created_at": "2021-01-07T19:40:04Z"
      },
      {
        "secret": "bhD5kiX2J+KBgZSk118qO61ZIdX/v8On",
        "created_at": "2021-01-04T21:18:07Z"
      }
    ]
  }
}

Modify enroll secrets

This replaces the active global enroll secrets with the secrets specified.

POST /api/v1/fleet/spec/enroll_secret

Parameters

Name Type In Description
secrets list body Required. The plain text string used as the enroll secret. Note that there is a limit of 50 secrets allowed.

Example

Request body
{
  "spec": {
    "secrets": [
      {
        "secret": "fTp52/twaxBU6gIi0J6PHp8o5Sm1k1kn"
      }
    ]
  }
}

POST /api/v1/fleet/spec/enroll_secret

Default response

Status: 200


Live query

These API routes are used by the Fleet UI.

Check live query status

This checks the status of Fleet's ability to run a live query. If an error is present in the response, Fleet won't be able to run a live query successfully. The Fleet UI uses this endpoint to make sure that the Fleet instance is correctly configured to run live queries.

GET /api/v1/fleet/status/live_query

Parameters

None.

Example

GET /api/v1/fleet/status/live_query

Default response

Status: 200

Check result store status

This checks Fleet's result store status. If an error is present in the response, Fleet won't be able to run a live query successfully. The Fleet UI uses this endpoint to make sure that the Fleet instance is correctly configured to run live queries.

GET /api/v1/fleet/status/result_store

Parameters

None.

Example

GET /api/v1/fleet/status/result_store

Default response

Status: 200

Search targets

Accepts a search query and a list of host IDs to omit and returns a set of up to ten matching hosts. If a query ID is provided and the referenced query allows observers to run, targets will include hosts for which the user has an observer role.

POST /api/latest/fleet/hosts/search

Parameters

Name Type In Description
query string body The query used to identify hosts to target. Searchable items include a host's hostname or IPv4 address.
query_id integer body The saved query (if any) that will be run. The observer_can_run property on the query and the user's roles affect which targets are included.
excluded_host_ids array body The list of host ids to omit from the search results.

Example

POST /api/v1/fleet/hosts/search

Request body
{
  "query": "foo",
  "query_id": 42,
  "selected": {
    "hosts": [],
    "labels": [],
    "teams": [1]
  }
}
Default response
{
  "targets": {
    "hosts": [
      {
        "created_at": "2021-02-03T16:11:43Z",
        "updated_at": "2021-02-03T21:58:19Z",
        "id": 1337,
        "detail_updated_at": "2021-02-03T21:58:10Z",
        "label_updated_at": "2021-02-03T21:58:10Z",
        "last_enrolled_at": "2021-02-03T16:11:43Z",
        "seen_time": "2021-02-03T21:58:20Z",
        "hostname": "foof41482833",
        "uuid": "a2064cef-0000-0000-afb9-283e3c1d487e",
        "platform": "rhel",
        "osquery_version": "4.5.1",
        "os_version": "CentOS 6.10.0",
        "build": "",
        "platform_like": "rhel",
        "code_name": "",
        "uptime": 32688000000000,
        "memory": 2086899712,
        "cpu_type": "x86_64",
        "cpu_subtype": "142",
        "cpu_brand": "Intel(R) Core(TM) i5-8279U CPU @ 2.40GHz",
        "cpu_physical_cores": 4,
        "cpu_logical_cores": 4,
        "hardware_vendor": "",
        "hardware_model": "",
        "hardware_version": "",
        "hardware_serial": "",
        "computer_name": "foof41482833",
        "display_name": "foof41482833",
        "primary_ip": "172.20.0.3",
        "primary_mac": "02:42:ac:14:00:03",
        "distributed_interval": 10,
        "config_tls_refresh": 10,
        "logger_tls_period": 10,
        "additional": {},
        "status": "offline",
        "display_text": "foof41482833"
      }
    ]
  }
}

Count targets

Counts the number of online and offline hosts included in a given set of selected targets.

POST /api/latest/fleet/targets/count

Parameters

Name Type In Description
query_id integer body The saved query (if any) that will be run. The observer_can_run property on the query and the user's roles determine which targets are included.
selected object body The object includes lists of selected host IDs (selected.hosts), label IDs (selected.labels), and team IDs (selected.teams). When provided, builtin label IDs, custom label IDs and team IDs become AND filters. Within each selector, selecting two or more teams, two or more builtin labels, or two or more custom labels, behave as OR filters. There's one special case for the builtin label "All hosts", if such label is selected, then all other label and team selectors are ignored (and all hosts will be selected). If a host ID is explicitly included in selected.hosts, then it is assured that the query will be selected to run on it (no matter the contents of selected.labels and selected.teams). See examples below.

Example

POST /api/latest/fleet/targets/count

Request body
{
  "query_id": 1337,
  "selected": {
    "hosts": [],
    "labels": [42],
    "teams": []
  }
}
Default response
{
  "targets_count": 813,
  "targets_offline": 813,
  "targets_online": 0
}

Run live query

Runs the specified query as a live query on the specified hosts or group of hosts and returns a new live query campaign. Individual hosts must be specified with the host's ID. Label IDs also specify groups of hosts.

After you initiate the query, get results via WebSocket.

POST /api/v1/fleet/queries/run

Parameters

Name Type In Description
query string body The SQL if using a custom query.
query_id integer body The saved query (if any) that will be run. Required if running query as an observer. The observer_can_run property on the query effects which targets are included.
selected object body Required. The object includes lists of selected host IDs (selected.hosts), label IDs (selected.labels), and team IDs (selected.teams). When provided, builtin label IDs, custom label IDs and team IDs become AND filters. Within each selector, selecting two or more teams, two or more builtin labels, or two or more custom labels, behave as OR filters. There's one special case for the builtin label "All hosts", if such label is selected, then all other label and team selectors are ignored (and all hosts will be selected). If a host ID is explicitly included in selected.hosts, then it is assured that the query will be selected to run on it (no matter the contents of selected.labels and selected.teams). See examples below.

One of query and query_id must be specified.

Example with one host targeted by ID

POST /api/v1/fleet/queries/run

Request body
{
  "query": "SELECT instance_id FROM system_info",
  "selected": {
    "hosts": [171]
  }
}
Default response

Status: 200

{
  "campaign": {
    "created_at": "0001-01-01T00:00:00Z",
    "updated_at": "0001-01-01T00:00:00Z",
    "Metrics": {
      "TotalHosts": 1,
      "OnlineHosts": 0,
      "OfflineHosts": 1,
      "MissingInActionHosts": 0,
      "NewHosts": 1
    },
    "id": 1,
    "query_id": 3,
    "status": 0,
    "user_id": 1
  }
}

Example with multiple hosts targeted by label ID

POST /api/v1/fleet/queries/run

Request body
{
  "query": "SELECT instance_id FROM system_info;",
  "selected": {
    "labels": [7]
  }
}
Default response

Status: 200

{
  "campaign": {
    "created_at": "0001-01-01T00:00:00Z",
    "updated_at": "0001-01-01T00:00:00Z",
    "Metrics": {
      "TotalHosts": 102,
      "OnlineHosts": 0,
      "OfflineHosts": 24,
      "MissingInActionHosts": 0,
      "NewHosts": 0
    },
    "id": 2,
    "query_id": 3,
    "status": 0,
    "user_id": 1
  }
}

Run live query by name

Runs the specified saved query as a live query on the specified targets. Returns a new live query campaign. Individual hosts must be specified with the host's hostname. Groups of hosts are specified by label name.

After the query has been initiated, get results via WebSocket.

POST /api/v1/fleet/queries/run_by_names

Parameters

Name Type In Description
query string body The SQL of the query.
query_id integer body The saved query (if any) that will be run. The observer_can_run property on the query effects which targets are included.
selected object body Required. The object includes lists of selected hostnames (selected.hosts), label names (labels). When provided, builtin label names and custom label names become AND filters. Within each selector, selecting two or more builtin labels, or two or more custom labels, behave as OR filters. There's one special case for the builtin label "All hosts", if such label is selected, then all other label and team selectors are ignored (and all hosts will be selected). If a host's hostname is explicitly included in selected.hosts, then it is assured that the query will be selected to run on it (no matter the contents of selected.labels). See examples below.

One of query and query_id must be specified.

Example with one host targeted by hostname

POST /api/v1/fleet/queries/run_by_names

Request body
{
  "query_id": 1,
  "selected": {
    "hosts": ["macbook-pro.local"]
  }
}
Default response

Status: 200

{
  "campaign": {
    "created_at": "0001-01-01T00:00:00Z",
    "updated_at": "0001-01-01T00:00:00Z",
    "Metrics": {
      "TotalHosts": 1,
      "OnlineHosts": 0,
      "OfflineHosts": 1,
      "MissingInActionHosts": 0,
      "NewHosts": 1
    },
    "id": 1,
    "query_id": 3,
    "status": 0,
    "user_id": 1
  }
}

Example with multiple hosts targeted by label name

POST /api/v1/fleet/queries/run_by_names

Request body
{
  "query": "SELECT instance_id FROM system_info",
  "selected": {
    "labels": ["All Hosts"]
  }
}
Default response

Status: 200

{
  "campaign": {
    "created_at": "0001-01-01T00:00:00Z",
    "updated_at": "0001-01-01T00:00:00Z",
    "Metrics": {
      "TotalHosts": 102,
      "OnlineHosts": 0,
      "OfflineHosts": 24,
      "MissingInActionHosts": 0,
      "NewHosts": 1
    },
    "id": 2,
    "query_id": 3,
    "status": 0,
    "user_id": 1
  }
}

Retrieve live query results (standard WebSocket API)

You can retrieve the results of a live query using the standard WebSocket API.

Before you retrieve the live query results, you must create a live query campaign by running the live query. Use the Run live query or Run live query by name endpoints to create a live query campaign.

Note that live queries are automatically cancelled if this method is not called to start retrieving the results within 60 seconds of initiating the query.

/api/v1/fleet/results/websocket

Parameters

Name Type In Description
token string Required. The token used to authenticate with the Fleet API.
campaignID integer Required. The ID of the live query campaign.

Example

Example script to handle request and response

const socket = new WebSocket('wss://<your-base-url>/api/v1/fleet/results/websocket');

socket.onopen = () => {
  socket.send(JSON.stringify({ type: 'auth', data: { token: <auth-token> } }));
  socket.send(JSON.stringify({ type: 'select_campaign', data: { campaign_id: <campaign-id> } }));
};

socket.onmessage = ({ data }) => {
  console.log(data);
  const message = JSON.parse(data);
  if (message.type === 'status' && message.data.status === 'finished') {
    socket.close();
  }
}

Detailed request and response walkthrough with example data

webSocket.onopen()

Response data
o

webSocket.send()

Request data
[
  {
    "type": "auth",
    "data": { "token": <insert_token_here> }
  }
]
[
  {
    "type": "select_campaign",
    "data": { "campaign_id": 12 }
  }
]

webSocket.onmessage()

Response data
// Sends the total number of hosts targeted and segments them by status

[
  {
    "type": "totals",
    "data": {
      "count": 24,
      "online": 6,
      "offline": 18,
      "missing_in_action": 0
    }
  }
]
// Sends the expected results, actual results so far, and the status of the live query

[
  {
    "type": "status",
    "data": {
      "expected_results": 6,
      "actual_results": 0,
      "status": "pending"
    }
  }
]
// Sends the result for a given host

[
  {
    "type": "result",
    "data": {
      "distributed_query_execution_id": 39,
      "host": {
        "id": 42,
        "hostname": "foobar",
        "display_name": "foobar"
      },
      "rows": [
        // query results data for the given host
      ],
      "error": null
    }
  }
]
// Sends the status of "finished" when messages with the results for all expected hosts have been sent

[
  {
    "type": "status",
    "data": {
      "expected_results": 6,
      "actual_results": 6,
      "status": "finished"
    }
  }
]

Retrieve live query results (SockJS)

You can also retrieve live query results with a SockJS client. The script to handle the request and response messages will look similar to the standard WebSocket API script with slight variations. For example, the constructor used for SockJS is SockJS while the constructor used for the standard WebSocket API is WebSocket.

Note that SockJS has been found to be substantially less reliable than the standard WebSockets approach.

/api/v1/fleet/results/

Parameters

Name Type In Description
token string Required. The token used to authenticate with the Fleet API.
campaignID integer Required. The ID of the live query campaign.

Example

Example script to handle request and response

const socket = new SockJS(`<your-base-url>/api/v1/fleet/results`, undefined, {});

socket.onopen = () => {
  socket.send(JSON.stringify({ type: 'auth', data: { token: <token> } }));
  socket.send(JSON.stringify({ type: 'select_campaign', data: { campaign_id: <campaignID> } }));
};

socket.onmessage = ({ data }) => {
  console.log(data);
  const message = JSON.parse(data);

  if (message.type === 'status' && message.data.status === 'finished') {
    socket.close();
  }
}
Detailed request and response walkthrough

socket.onopen()

Response data
o

socket.send()

Request data
[
  {
    "type": "auth",
    "data": { "token": <insert_token_here> }
  }
]
[
  {
    "type": "select_campaign",
    "data": { "campaign_id": 12 }
  }
]

socket.onmessage()

Response data
// Sends the total number of hosts targeted and segments them by status

[
  {
    "type": "totals",
    "data": {
      "count": 24,
      "online": 6,
      "offline": 18,
      "missing_in_action": 0
    }
  }
]
// Sends the expected results, actual results so far, and the status of the live query

[
  {
    "type": "status",
    "data": {
      "expected_results": 6,
      "actual_results": 0,
      "status": "pending"
    }
  }
]
// Sends the result for a given host

[
  {
    "type": "result",
    "data": {
      "distributed_query_execution_id": 39,
      "host": {
        "id": 42,
        "hostname": "foobar",
        "display_name": "foobar"
      },
      "rows": [
        // query results data for the given host
      ],
      "error": null
    }
  }
]
// Sends the status of "finished" when messages with the results for all expected hosts have been sent

[
  {
    "type": "status",
    "data": {
      "expected_results": 6,
      "actual_results": 6,
      "status": "finished"
    }
  }
]

Trigger cron schedule

This API is used by the fleetctl CLI tool to make requests to trigger an ad hoc run of all jobs in a specified cron schedule.

Trigger

This makes a request to trigger the specified cron schedule. Upon receiving the request, the Fleet server first checks the current status of the schedule, and it returns an error if a run is currently pending.

POST /api/latest/fleet/trigger

Parameters

Name Type In Description
name string query The name of the cron schedule to trigger. Supported trigger names are apple_mdm_dep_profile_assigner, automations, cleanups_then_aggregation, integrations, mdm_apple_profile_manager, usage_statistics, and vulnerabilities

Example

POST /api/latest/fleet/trigger?name=automations

Default response

Status: 200


Device-authenticated routes

Device-authenticated routes are routes used by the Fleet Desktop application. Unlike most other routes, Fleet user's API token does not authenticate them. They use a device-specific token.

Refetch device's host

Same as Refetch host route for the current device.

POST /api/v1/fleet/device/{token}/refetch

Parameters
Name Type In Description
token string path The device's authentication token.

Get device's Google Chrome profiles

Same as Get host's Google Chrome profiles for the current device.

GET /api/v1/fleet/device/{token}/device_mapping

Parameters
Name Type In Description
token string path The device's authentication token.

Get device's mobile device management (MDM) and Munki information

Same as Get host's mobile device management and Munki information for the current device.

GET /api/v1/fleet/device/{token}/macadmins

Parameters
Name Type In Description
token string path The device's authentication token.

Ping Server with Device Token

Ping the server. OK response expected if the device token is still valid.

HEAD /api/v1/fleet/device/{token}/ping

Parameters
Name Type In Description
token string path The device's authentication token.
Example

HEAD /api/v1/fleet/device/abcdef012456789/ping

Default response

Status: 200

Get Fleet Desktop information

Available in Fleet Premium

Gets all information required by Fleet Desktop, this includes things like the number of failed policies or notifications to show/hide menu items.

GET /api/v1/fleet/device/{token}/desktop

Parameters
Name Type In Description
token string path The device's authentication token.
Example

GET /api/v1/fleet/device/abcdef012456789/desktop

Default response

Status: 200

{
  "failing_policies_count": 3,
  "notifications": {
    "needs_mdm_migration": true,
    "renew_enrollment_profile": false,
    "enforce_bitlocker_encryption": false,
  },
  "config": {
    "org_info": {
      "org_name": "Fleet",
      "org_logo_url": "https://example.com/logo.jpg",
      "org_logo_url_light_background": "https://example.com/logo-light.jpg",
      "contact_url": "https://fleetdm.com/company/contact"
    },
    "mdm": {
      "macos_migration": {
        "mode": "forced"
      }
    }
  }
}

In regards to the notifications key:

  • needs_mdm_migration means that the device fits all the requirements to allow the user to initiate an MDM migration to Fleet.
  • renew_enrollment_profile means that the device is currently unmanaged from MDM but should be DEP enrolled into Fleet.
  • enforce_bitlocker_encryption applies only to Windows devices and means that it should encrypt the disk and report the encryption key back to Fleet.

Get device's policies

Available in Fleet Premium

Lists the policies applied to the current device.

GET /api/v1/fleet/device/{token}/policies

Parameters
Name Type In Description
token string path The device's authentication token.
Example

GET /api/v1/fleet/device/abcdef012456789/policies

Default response

Status: 200

{
  "policies": [
    {
      "id": 1,
      "name": "SomeQuery",
      "query": "SELECT * FROM foo;",
      "description": "this is a query",
      "resolution": "fix with these steps...",
      "platform": "windows,linux",
      "response": "pass"
    },
    {
      "id": 2,
      "name": "SomeQuery2",
      "query": "SELECT * FROM bar;",
      "description": "this is another query",
      "resolution": "fix with these other steps...",
      "platform": "darwin",
      "response": "fail"
    },
    {
      "id": 3,
      "name": "SomeQuery3",
      "query": "SELECT * FROM baz;",
      "description": "",
      "resolution": "",
      "platform": "",
      "response": ""
    }
  ]
}

Get device's API features

This supports the dynamic discovery of API features supported by the server for device-authenticated routes. This allows supporting different versions of Fleet Desktop and Fleet server instances (older or newer) while supporting the evolution of the API features. With this mechanism, an older Fleet Desktop can ignore features it doesn't know about, and a newer one can avoid requesting features about which the server doesn't know.

GET /api/v1/fleet/device/{token}/api_features

Parameters
Name Type In Description
token string path The device's authentication token.
Example

GET /api/v1/fleet/device/abcdef012456789/api_features

Default response

Status: 200

{
  "features": {}
}

Get device's transparency URL

Returns the URL to open when clicking the "Transparency" menu item in Fleet Desktop. Note that Fleet Premium is required to configure a custom transparency URL.

GET /api/v1/fleet/device/{token}/transparency

Parameters
Name Type In Description
token string path The device's authentication token.
Example

GET /api/v1/fleet/device/abcdef012456789/transparency

Default response

Status: 307

Redirects to the transparency URL.

Download device's MDM manual enrollment profile

Downloads the Mobile Device Management (MDM) enrollment profile to install on the device for a manual enrollment into Fleet MDM.

GET /api/v1/fleet/device/{token}/mdm/apple/manual_enrollment_profile

Parameters
Name Type In Description
token string path The device's authentication token.
Example

GET /api/v1/fleet/device/abcdef012456789/mdm/apple/manual_enrollment_profile

Default response

Status: 200

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<!-- ... -->
</plist>

Migrate device to Fleet from another MDM solution

Signals the Fleet server to send a webbook request with the device UUID and serial number to the webhook URL configured for MDM migration. Requires Fleet Premium license

POST /api/v1/fleet/device/{token}/migrate_mdm

Parameters
Name Type In Description
token string path The device's authentication token.
Example

POST /api/v1/fleet/device/abcdef012456789/migrate_mdm

Default response

Status: 204


Trigger FileVault key escrow

Sends a signal to Fleet Desktop to initiate a FileVault key escrow. This is useful for setting the escrow key initially as well as in scenarios where a token rotation is required. Requires Fleet Premium license

POST /api/v1/fleet/device/{token}/rotate_encryption_key

Parameters
Name Type In Description
token string path The device's authentication token.
Example

POST /api/v1/fleet/device/abcdef012456789/rotate_encryption_key

Default response

Status: 204

Report an agent error

Notifies the server about an agent error, resulting in two outcomes:

  • The error gets saved in Redis and can later be accessed using fleetctl debug archive.
  • The server consistently replies with a 500 status code, which can serve as a signal to activate an alarm through a monitoring tool.

Note: to allow fleetd agents to use this endpoint, you need to set a custom environment variable

POST /api/v1/fleet/device/{token}/debug/errors

Parameters

Name Type Description
error_source string Process name that error originated from ex. orbit, fleet-desktop
error_source_version string version of error_source
error_timestamp datetime Time in UTC that error occured
error_message string error message
error_additional_info obj Any additional identifiers to assist debugging
Default response

Status: 500


Downloadable installers

These API routes are used by the UI in Fleet Sandbox.

Download an installer

Downloads a pre-built fleet-osquery installer with the given parameters.

POST /api/v1/fleet/download_installer/{kind}

Parameters

Name Type In Description
kind string path The installer kind: pkg, msi, deb or rpm.
enroll_secret string x-www-form-urlencoded The global enroll secret.
token string x-www-form-urlencoded The authentication token.
desktop boolean x-www-form-urlencoded Set to true to ask for an installer that includes Fleet Desktop.
Default response
Status: 200
Content-Type: application/octet-stream
Content-Disposition: attachment
Content-Length: <length>
Body: <blob>

If an installer with the provided parameters is found, the installer is returned as a binary blob in the body of the response.

Installer doesn't exist

Status: 400

This error occurs if an installer with the provided parameters doesn't exist.

Check if an installer exists

Checks if a pre-built fleet-osquery installer with the given parameters exists.

HEAD /api/v1/fleet/download_installer/{kind}

Parameters

Name Type In Description
kind string path The installer kind: pkg, msi, deb or rpm.
enroll_secret string query The global enroll secret.
desktop boolean query Set to true to ask for an installer that includes Fleet Desktop.
Default response

Status: 200

If an installer with the provided parameters is found.

Installer doesn't exist

Status: 400

If an installer with the provided parameters doesn't exist.

Setup

Sets up a new Fleet instance with the given parameters.

POST /api/v1/setup

Parameters

Name Type In Description
admin object body Required. Contains the following admin user details: admin, email, name, password, and password_confirmation.
org_info object body Required. Contains the following organizational details: org_name.
server_url string body Required. The URL of the Fleet instance.
Request body
{
	"admin": {
		"admin": true,
		"email": "janedoe@example.com",
		"name": "Jane Doe",
		"password": "password!234",
		"password_confirmation": "password!234"
	},
	"org_info": {
		"org_name": "Fleet Device Management"
	},
	"server_url": "https://localhost:8080"
}
Default response

Status: 200

If the Fleet instance is provided required parameters to complete setup.

{
  "admin": {
    "created_at": "2021-01-07T19:40:04Z",
    "updated_at": "2021-01-07T19:40:04Z",
    "id": 1,
    "name": "Jane Doe",
    "email": "janedoe@example.com",
    "force_password_reset": false,
    "gravatar_url": "",
    "sso_enabled": false,
    "global_role": "admin",
    "api_only": false,
    "teams": []
  },
  "org_info": {
    "org_name": "Fleet Device Management",
    "org_logo_url": "https://fleetdm.com/logo.png"
  },
  "server_url": "https://localhost:8080",
  "osquery_enroll_secret": null,
  "token": "ur4RWGBeiNmNzer/dnGzgUQ+jxrJe19xuHg/LhLkbhuZMQu35scyBHUHs68+RJxZynxQnuTz4WTHXayAJJaGgg=="
}

Scripts

Run script asynchronously

Available in Fleet Premium

Creates a script execution request and returns the execution identifier to retrieve results at a later time.

POST /api/v1/fleet/scripts/run

Parameters

Name Type In Description
host_id integer body Required. The ID of the host to run the script on.
script_id integer body The ID of the existing saved script to run. Only one of either script_id or script_contents can be included in the request; omit this parameter if using script_contents.
script_contents string body The contents of the script to run. Only one of either script_id or script_contents can be included in the request; omit this parameter if using script_id.

Note that if both script_id and script_contents are included in the request, this endpoint will respond with an error.

Example

POST /api/v1/fleet/scripts/run

Default response

Status: 202

{
  "host_id": 1227,
  "execution_id": "e797d6c6-3aae-11ee-be56-0242ac120002"
}

Batch-apply scripts

Available in Fleet Premium

POST /api/v1/fleet/scripts/batch

Parameters

Name Type In Description
team_id number query The ID of the team to add the scripts to. Only one team identifier (team_id or team_name) can be included in the request, omit this parameter if using team_name.
team_name string query The name of the team to add the scripts to. Only one team identifier (team_id or team_name) can be included in the request, omit this parameter if using team_id.
dry_run bool query Validate the provided scripts and return any validation errors, but do not apply the changes.
scripts array body An array of objects with the scripts payloads. Each item must contain name with the script name and script_contents with the script contents encoded in base64

If both team_id and team_name parameters are included, this endpoint will respond with an error. If no team_name or team_id is provided, the scripts will be applied for all hosts.

Note that this endpoint replaces all the active scripts for the specified team (or no team). Any existing script that is not included in the list will be removed, and existing scripts with the same name as a new script will be edited. Providing an empty list of scripts will remove existing scripts.

Example

POST /api/v1/fleet/mdm/scripts/batch

Default response

204