openapi: 3.1.0 info: title: Foxglove API version: v1 x-logo: url: https://foxglove.dev/images/logo-icon-round.png description: > # Python client Foxglove provides a Python client library ([`foxglove-client`](https://github.com/foxglove/foxglove-python)) to more easily interact with the Foxglove API. The SDK can be downloaded from [PyPI](https://pypi.org/project/foxglove-client/) and source is available on [GitHub](https://github.com/foxglove/foxglove-python). # Authentication All routes excluding the [Site Bucket Notifications endpoint](#tag/Sites/paths/~1site-bucket-notifications/post) require an [API key](/docs/settings#api-keys) with specific capabilities. Only organization admins can create an API key. Requests must include the API key in the `Authorization` header as a bearer token: ``` Authorization: Bearer fox_sk_1234... ``` Each endpoint in the API reference lists the capabilities required for access. An endpoint with Authorizations `ApiKey (devices.list)` would require an api key with the `devices.list` capability. # Sorting and pagination Some GET endpoints support sorting and pagination. Where supported, you will see the following query parameters in the endpoint documentation: * `sortBy` – Field name to sort by (endpoint specific) * `sortOrder` – "asc" or "desc" * `limit` – Number of records in the response * `offset` – Number of records to skip If no limit is provided, endpoints will default to a limit of 2000 items. Requesting a limit greater than 2000 items will result in a 400 response. # Timestamps Unless otherwise documented, all timestamp related fields (start, end, created, etc) use the ISO8601 conforming [RFC3339](https://www.ietf.org/rfc/rfc3339.txt) UTC "Zulu" format. In the documentation this will appear as `string` types with `` formatting (i.e. `string `). These timestamps support nanosecond resolution with up to nine fractional digits. Examples: - 2023-04-06T09:15:30Z - 2023-04-06T18:27:45.876543210Z > Note: Variants of RFC3339 using durations or offsets which are not conforming to ISO8601 are not supported. # Rate limits To help ensure responsiveness for all clients, requests to the API may be rate-limited. In this case, a request will receive a status code of 429. Your client may refer to headers, such as "Retry-After", to determine when a request should be retried. In general, if your client experiences an error, you should adjust the rate at which your client makes requests, and you may issue retries with a strategy such as exponential backoff. servers: - url: https://api.foxglove.dev/v1 description: Production security: [] tags: - name: Custom Properties description: | Custom properties are typed metadata which you can assign to devices. For example, you can create a device custom property identified with a key `locationId` and a type of `string`. This enables you to assign a location to each of your devices, view that data in Foxglove, and filter devices by a location ID. - name: Devices description: > Devices represent robots in your organization. It is common to have devices for both physical and virtual robots. Devices are referenced by other resources like recordings and events. A device may have [Foxlet](https://docs.foxglove.dev/docs/fleet/foxlet) installed on it. In this case, you may configure the retention period for recordings on the device by setting its `retainRecordingsSeconds`. To help manage your devices, you may define [custom properties](#tag/Custom-Properties) and assign metadata to each device via its `properties`. - name: Coverage description: > Coverage provides the ability to see which time spans are available within Foxglove. - name: Imports description: > **The Imports endpoints are deprecated. Use the [Recordings](#tag/Recordings) endpoints instead.** Imports are recordings that are available at a Primary Site. - name: Topics description: | Topics provide schema information for messages in the data source. - name: Events description: > Adding events can help you quickly identify, categorize, and search for points of interest in your data. Each event is tied to a device and time span, and can contain metadata. You can list events by devices, time ranges, and metadata. - name: Event Types description: > Event types help ensure data quality through validation, enable better filtering and analytics, and provide visual distinctions between categories of events. - name: Recordings description: > A recording is a resource representing the content of an MCAP file or ROS bag managed by Data Platform. - name: Sessions description: > Sessions are logical groupings of recordings from a single device. They allow you to manage and interact with recording data independent of how the recordings are stored. - name: Recording Attachments description: > A recording attachment resource represents information about an MCAP attachment imported to Foxglove. Attachments are available for individual download or with their recording. - name: Sites description: > A site is a logical grouping of storage and compute for storing Recording data. - name: Device Tokens description: | Device tokens authenticate a device to the API. - name: Webhook Payloads description: > [Webhooks](/docs/webhooks) send POST request notifications to your HTTPS endpoint when events occur within Foxglove. This section describes the JSON request body format your endpoint should expect for each event type. ## recording.created `recording.created` events occur when a recording is created. Recordings are created when a file is [uploaded](/api#tag/Recordings/paths/~1data~1upload/post), added to [Edge Site](/docs/edge-sites) storage, or created on a device that runs [Foxlet](/docs/fleet/foxlet). ## recording.imported `recording.imported` events occur when a recording is [imported](/docs/importing-data) and is ready for streaming. ## session.created `session.created` events occur when a new [Session](/docs/data/sessions) is created. Sessions group related recordings and can be created via the API or when recordings are associated with a session. ## device.created `device.created` events occur when a new [Device](/docs/importing-data#add-a-device) is created. ## device.updated `device.updated` events occur when a [Device](/docs/importing-data#add-a-device) is updated. ## event.created `event.created` events occur when a new [Event](/docs/events) is created in Foxglove. ## event.updated `event.updated` events occur when an [Event](/docs/events) is updated. ## ping The `ping` event type is used to test webhook connectivity. - name: Site Tokens description: > Site tokens are credentials a [self-hosted Primary Site](https://docs.foxglove.dev/docs/primary-sites#self-hosted) or [Edge Site](https://docs.foxglove.dev/docs/edge-sites) use to communicate with the Foxglove API. - name: Site Inbox Notification Tokens description: > Site inbox notification tokens are credentials used to authenticate bucket notifications for a [Primary Site](https://docs.foxglove.dev/docs/primary-sites) (self-managed or BYOS) to the Foxglove API. - name: Lake files description: > MCAP files stored in the lake bucket of a [self-hosted Primary Site](https://docs.foxglove.dev/docs/primary-sites#self-hosted). You must have an Enterprise account to use lake file endpoints. - name: Projects description: > [Projects](https://docs.foxglove.dev/docs/projects) are a container for organizing data and resources in Foxglove. Your plan must support managing projects. x-tagGroups: - name: Data Platform tags: - Coverage - Custom Properties - Device Tokens - Devices - Events - Event Types - Imports - Lake files - Projects - Recording Attachments - Recordings - Sessions - Site Tokens - Site Inbox Notification Tokens - Sites - Stream data - Topics - name: Webhooks tags: - Webhook Payloads - name: Visualization tags: - Extensions - Layouts paths: /devices: get: tags: - Devices security: - ApiKey: - devices.list summary: List devices description: > Retrieve a list of devices. **Filtering by custom properties** Use the `query` parameter to filter devices on custom properties. Syntax: * `properties.key:value`: matches devices with a property that contains a key named `key` with a value of `value`; use double quotes if the value contains spaces or special characters * `properties.key:value1,value2`: matches devices with a property that contains a key named `key` and its value is either `value1` or `value2` * `properties.key:*`: matches devices with a property that contains a key named `key` and any value * `*:value`: matches devices with a property that contains a key with any name and a value of `value` * `foo`: matches devices with properties where any key or stringified value contains `foo` Multiple qualifiers can be used in the same query string; this will filter devices matching the intersection of the qualifiers (AND). x-codeSamples: - lang: python label: Python source: | from foxglove.client import Client token = "" client = Client(token=token) client.get_devices() parameters: - in: query name: projectId description: Filter devices by project schema: type: string required: false - in: query name: sortBy description: >- Field to sort items by ("id", "name", or a custom property key prefixed with `properties.`) schema: type: string required: false - in: query name: query description: >- Space-separated query string for device custom properties. Each custom property key must be valid and prefixed with "properties.". See above for syntax and examples. schema: type: string - $ref: '#/components/parameters/sortOrder' - $ref: '#/components/parameters/limit' - $ref: '#/components/parameters/offset' responses: '200': description: List of devices content: application/json: schema: type: array items: allOf: - $ref: '#/components/schemas/Device' - $ref: '#/components/schemas/DeviceDetails' - $ref: '#/components/schemas/DeviceRemoteAccessState' post: tags: - Devices summary: Create a device security: - ApiKey: - devices.create x-codeSamples: - lang: python label: Python source: | from foxglove.client import Client token = "" client = Client(token=token) client.create_device( name=name, project_id="", ) requestBody: required: true content: application/json: schema: type: object properties: name: $ref: '#/components/schemas/deviceName' properties: $ref: '#/components/schemas/CustomPropertyValues' description: > A key-value map, where each key is one of your pre-defined device custom property keys. Keys which are not recognized as custom properties will be ignored. required: [] projectId: description: >- The project ID that the device belongs to. Required for multi-project orgs. type: string required: - name responses: '200': description: The newly created device content: application/json: schema: allOf: - $ref: '#/components/schemas/Device' - $ref: '#/components/schemas/DeviceDetails' /recordings: get: tags: - Recordings summary: List recordings security: - ApiKey: - recordings.list x-codeSamples: - lang: python label: Python source: | from foxglove.client import Client token = "" client = Client(token=token) client.get_recordings() parameters: - $ref: '#/components/parameters/start' description: > Start of inclusive time range: return all recordings with data on or after this value - $ref: '#/components/parameters/end' description: > End of inclusive time range: return all recordings with data on or before this value - in: query name: path description: Filter response to recordings with this path schema: type: string - in: query name: site.id description: >- Filter response to recordings stored at the Primary Site with this ID schema: type: string - in: query name: edgeSite.id description: Filter response to recordings stored at the Edge Site with this ID schema: type: string - in: query name: deviceId description: >- Filter response to recordings for the device with this ID, empty string for those without any schema: type: string - in: query name: deviceName description: Filter response to recordings for the device with this name schema: type: string - in: query name: topic description: Filter response to recordings containing the topic schema: type: string - in: query name: device.id description: Equivalent to deviceId, and ignored if deviceId is supplied schema: type: string deprecated: true - in: query name: device.name description: Equivalent to deviceName, and ignored if deviceName is supplied schema: type: string deprecated: true - in: query name: importStatus description: Filter response to recordings with this import status schema: type: string enum: - none - pending - importing - failed - complete - in: query name: projectId description: Filter recordings by project schema: type: string required: false - in: query name: sessionId description: >- Filter response to recordings in the session with this ID, or empty string for recordings with no associated session schema: type: string - in: query name: sessionKey description: >- Filter response to recordings in the session with this key (sessions group recordings from a specific device) schema: type: string - in: query name: metadataQuery description: > Filter recordings by metadata using a query syntax. Supports key-value search variations (see [Recordings Search](https://docs.foxglove.dev/docs/data/recordings#search)): * `key:value`: matches recordings with metadata that contains a key named `key` with a value of `value` * `key:value1,value2`: matches recordings with metadata that contains a key named `key` with a value of either `value1` or `value2` * `key:*`: matches recordings where any metadata contains a key named `key` * `*:value`: matches recordings where any metadata contains `value` as a value * `search term`: matches recordings with metadata where any key or value string contains `search term` Multiple qualifiers can be used in the same query string; this will filter recordings where metadata matches the intersection of the qualifiers (AND). **Examples:** * `temperature:high` - find recordings with sensor metadata where temperature is high * `status:* device:camera1` - find recordings with any status AND device camera1 * `*:error` - find any key with "error" value * `warehouseName:"leaping llama"` - use quotes for values with spaces or special characters As this is a query parameter, the value must be URL-encoded. schema: type: string required: false - $ref: '#/components/parameters/limit' - $ref: '#/components/parameters/offset' - in: query name: sortBy description: > Sort returned recordings by a field in the response type. Specifying `duration` sorts by the duration between the recording `start` and `end` fields. schema: type: string enum: - deviceName - device.name - createdAt - start - end - duration - path - importedAt - $ref: '#/components/parameters/sortOrder' responses: '200': description: Success content: application/json: schema: type: array items: $ref: '#/components/schemas/Recording' /recordings/{keyOrId}: parameters: - in: path name: keyOrId schema: type: string required: true description: Recording Key or ID get: tags: - Recordings summary: Get a recording description: | Get details on a specific recording. parameters: [] security: - ApiKey: - recordings.list responses: '200': description: A Recording content: application/json: schema: $ref: '#/components/schemas/Recording' delete: tags: - Recordings summary: Delete a recording description: > Deletes a recording. Deleting a recording also deletes the data for that recording (including attachments, messages, metadata, etc). Note: If the recording was imported from an Edge Site, only the imported data is removed; the edge copy on the Edge Site is unchanged and the recording can be imported again. The recording remains associated with any session it belongs to, and re-importing restores it on that session. security: - ApiKey: - recordings.delete responses: '200': description: The deleted recording ID content: application/json: schema: type: object properties: recordingId: type: string description: The recording ID required: - recordingId /recordings/{keyOrId}/import: parameters: - in: path name: keyOrId schema: type: string required: true description: Recording ID post: tags: - Recordings summary: Import from edge description: > Request import of a recording from an Edge Site to a Primary Site. Importing a recording makes the data (messages, metadata, attachments, etc.) available for download and streaming. If the recording is successfully queued for import, is already imported, or already queued for import, this endpoint will return a 200 response and include the recording ID and the `importStatus`. An import status of `complete` indicates the recording is already imported. Poll the `GET v1/recordings/{id}` endpoint to observe changes to the `importStatus`. If the recording cannot be found or is unavailable for import because the edge copy or site is deleted, this endpoint will return a 404 response. security: - ApiKey: - data.upload responses: '200': description: Success content: application/json: schema: type: object properties: id: type: string description: Recording ID importStatus: $ref: '#/components/schemas/RecordingImportStatus' /sessions: get: tags: - Sessions summary: List sessions description: > Retrieve a list of recording sessions. **Filtering by custom properties** Use the `query` parameter to filter sessions on custom properties. Syntax: * `key:value`: matches sessions with a property that contains a key named `key` with a value of `value`; use double quotes if the value contains spaces or special characters * `key:value1,value2`: matches sessions with a property that contains a key named `key` and its value is either `value1` or `value2` * `key:*`: matches sessions with a property that contains a key named `key` and any value * `*:value`: matches sessions with a property where any key has the value `value` * `foo`: matches sessions with properties where any key or stringified value contains `foo` Multiple qualifiers can be used in the same query string; this will filter sessions matching the intersection of the qualifiers (AND). security: - ApiKey: - sessions.list parameters: - in: query name: projectId description: Filter sessions by project schema: type: string required: false - in: query name: deviceId description: Filter sessions by device ID schema: type: string required: false - in: query name: deviceName description: Filter sessions by device name schema: type: string required: false - in: query name: keyMatches description: Partial match on session key (case-insensitive) schema: type: string required: false - $ref: '#/components/parameters/start' - $ref: '#/components/parameters/end' - in: query name: sortBy description: Field to sort items by ("id", "createdAt", "updatedAt") schema: type: string enum: - id - createdAt - updatedAt required: false - in: query name: query description: >- Space-separated query string for session custom properties. Each custom property key must be valid. See above for syntax and examples. schema: type: string required: false - $ref: '#/components/parameters/sortOrder' - $ref: '#/components/parameters/limit' - $ref: '#/components/parameters/offset' responses: '200': description: List of recording sessions content: application/json: schema: type: array items: $ref: '#/components/schemas/RecordingSessionListItem' post: tags: - Sessions summary: Create a session description: > Create a new recording session. Either `deviceId` or `recordingIds` must be provided. If `recordingIds` are provided without a `deviceId`, the device is inferred from the recordings, which must all belong to the same device. The session inherits its org and project from the device. security: - ApiKey: - sessions.create requestBody: required: true content: application/json: schema: type: object properties: deviceId: description: >- The ID of the device to associate with the session. If omitted, inferred from `recordingIds`. type: string key: description: A user-supplied identifier, unique within the project. minLength: 1 type: string recordingIds: description: >- IDs of recordings to associate with the new session. All recordings must belong to the same device and project. type: array items: type: string properties: $ref: '#/components/schemas/CustomPropertyValues' description: > A key-value map, where each key is one of your pre-defined session custom property keys. Keys which are not recognized as custom properties will be ignored. required: [] responses: '200': description: The newly created session content: application/json: schema: $ref: '#/components/schemas/RecordingSession' /sessions/{keyOrId}: parameters: - in: path name: keyOrId schema: type: string required: true description: Recording Session Key or ID get: tags: - Sessions summary: Get a session description: | Get details on a specific session. security: - ApiKey: - sessions.list parameters: - in: query name: projectId schema: type: string description: Filter sessions by project. Required for multi-project orgs. responses: '200': description: Success content: application/json: schema: $ref: '#/components/schemas/RecordingSession' patch: tags: - Sessions summary: Update recordings in a session description: >- Add or remove recordings associated with the session. All recordings must belong to the same device and project. security: - ApiKey: - sessions.update parameters: - in: query name: projectId schema: type: string description: Filter sessions by project. Required for multi-project orgs. requestBody: required: true content: application/json: schema: type: object properties: addRecordingIds: type: array items: type: string description: Recording display IDs to add to the session. removeRecordingIds: type: array items: type: string description: Recording display IDs to remove from the session. properties: description: > Custom properties to assign to the session. Keys which are not included in the request, but exist on the session, will be unchanged. To unset a property, pass `null` as the value. type: object additionalProperties: true required: [] responses: '200': description: Updated session content: application/json: schema: $ref: '#/components/schemas/RecordingSession' delete: tags: - Sessions summary: Delete a session description: | Soft-delete a recording session and unlink all recordings from it. Does not delete recording data. security: - ApiKey: - sessions.delete parameters: - in: query name: projectId schema: type: string description: Filter sessions by project. Required for multi-project orgs. responses: '200': description: Success content: application/json: schema: type: object properties: id: type: string description: The ID of the deleted session required: - id /actions/devices/{nameOrId}/update-property-time-interval: parameters: - in: path name: nameOrId schema: type: string required: true description: > Device name or ID. Device names must be URI-encoded if they contain non-URI-safe characters. If a device is named with another device's ID, the device with the matching name will be returned. post: tags: - Devices - Properties summary: Update property time interval description: > Specify a value that was set for a given time range, or specify no value was set for that range. Existing records overlapping that time range may be split, trimmed, or deleted to accommodate this assertion. This endpoint should only be used for updating past time intervals. To update the current value of a property use the [update device](#tag/Devices/paths/~1devices~1%7BnameOrId%7D/patch) endpoint. security: - ApiKey: - devices.update x-projectIdOptional: true requestBody: required: true content: application/json: schema: type: object properties: projectId: type: string description: > The project ID of the device. Required for multi-project orgs. key: type: string description: > The key of the property. Must be an existing device custom property key for your organization. value: description: > The value of the property over the given time range. Omit to specify no value was set for that range. oneOf: - type: string - type: number - type: boolean - type: array items: type: string uniqueItems: true start: type: string format: date-time description: >- Inclusive start of the property's effective time range. Must be in the past. end: type: string format: date-time description: >- Exclusive end of the property's effective time range. Must be in the past. required: - key - start - end responses: '204': description: Success /data/imports: get: deprecated: true tags: - Imports summary: List imports description: > **This endpoint is deprecated. Use the [list recordings](#tag/Recordings/paths/~1recordings/get) endpoint instead.** security: - ApiKey: - data.imports.list x-codeSamples: - lang: python label: Python source: | from foxglove.client import Client token = "" client = Client(token=token) client.get_imports() parameters: - in: query name: deviceId description: ID of device associated with the exported data schema: type: string - in: query name: filename description: Filename to match schema: type: string - $ref: '#/components/parameters/start' description: Inclusive start of import time - $ref: '#/components/parameters/end' description: Inclusive end of import time - in: query name: dataStart description: Inclusive start of message log time schema: type: string format: date-time - in: query name: dataEnd description: Inclusive end of message log time schema: type: string format: date-time - in: query name: sortBy description: Sort by a single field of the import type schema: type: string enum: - importId - deviceId - importTime - dataStart - dataEnd - $ref: '#/components/parameters/sortOrder' - $ref: '#/components/parameters/limit' - $ref: '#/components/parameters/offset' responses: '200': description: Success content: application/json: schema: type: array items: $ref: '#/components/schemas/Import' delete: deprecated: true tags: - Imports summary: Delete multiple imports description: >- Deletes multiple imports by ID. Returns an array of result objects, which indicate whether a given import was successfully deleted. An import that has already been deleted will result in "notFound". _Note: All imports must belong to the same site. If any import belongs to a different site, the entire request is rejected with a 400 response._ security: - ApiKey: - data.imports.delete parameters: - in: query name: id description: >- ID of import to delete. You can specify up to 50 IDs (for example, `?id=abc&id=def&...`). required: true schema: type: array items: type: string description: an import ID maxItems: 50 style: form explode: true responses: '200': description: Success content: application/json: schema: type: object properties: deletionResults: type: array items: type: object properties: importId: type: string description: The import ID that was provided result: type: string description: The result of the deletion attempt. enum: - success - notFound required: - importId - result required: - deletionResults /data/imports/{importId}: parameters: - in: path name: importId schema: type: string required: true description: The `importId` of an import delete: deprecated: true tags: - Imports summary: Delete an import description: > **This endpoint is deprecated. Use the [delete recording](#tag/Recordings/paths/~1recordings~1%7Bid%7D/delete) endpoint instead.** Deleting an import deletes all data associated with the import. **This action is permanent and cannot be undone.** security: - ApiKey: - data.imports.delete x-codeSamples: - lang: python label: Python source: | from foxglove.client import Client token = "" client = Client(token=token) client.delete_import( device_id=device_id, import_id=import_id, ) parameters: - in: query name: deviceId deprecated: true description: The deviceId from the import record schema: type: string required: false responses: '200': description: Success content: application/json: schema: type: object properties: id: type: string required: - id /data/pending-imports: get: tags: - Recordings summary: List pending imports description: > List the pending imports. These are in-progress import jobs for newly uploaded recordings. security: - ApiKey: - data.imports.pending.list parameters: - in: query name: requestId description: A specific import request ID schema: type: string - in: query name: key description: The unique key optionally provided when importing schema: type: string - in: query name: deviceId description: ID of device associated with the pending import schema: type: string - in: query name: deviceName description: Name of device associated with the pending import schema: type: string - in: query name: device.name description: Equivalent to deviceName, and ignored if deviceName is supplied schema: type: string deprecated: true - in: query name: device.id description: Equivalent to deviceId, and ignored if deviceId is supplied schema: type: string deprecated: true - in: query name: error deprecated: true description: Deprecated. Use `/import-errors` instead. schema: type: string - in: query name: filename description: Filename to exactly match schema: type: string - in: query name: updatedSince description: Filter pending imports updated since this time schema: type: string format: date-time - in: query name: showCompleted description: Include completed requests schema: type: boolean default: false - in: query name: showQuarantined description: Include quarantined requests schema: type: boolean default: false - in: query name: siteId description: Filter response to imports at site with this ID schema: type: string - in: query name: projectId description: Filter pending imports by project schema: type: string - in: query name: sortBy description: Sort by a single field of the import type schema: type: string enum: - createdAt - deviceId - deviceName - device.name - device.id - error - importId - requestId - updatedAt - $ref: '#/components/parameters/sortOrder' - $ref: '#/components/parameters/limit' - $ref: '#/components/parameters/offset' responses: '200': description: Success content: application/json: schema: type: array items: $ref: '#/components/schemas/PendingImport' /recording-attachments: get: tags: - Recording Attachments summary: List attachments security: - ApiKey: - recordings.list x-codeSamples: - lang: python label: Python source: | from foxglove.client import Client token = "" client = Client(token=token) client.get_attachments() parameters: - in: query name: recordingId description: filter by recording ID schema: type: string - in: query name: siteId description: filter by Primary Site ID schema: type: string - in: query name: deviceId description: filter by device ID schema: type: string - in: query name: deviceName description: filter by device name schema: type: string - in: query name: device.id description: Equivalent to deviceId, and ignored if deviceId is supplied schema: type: string deprecated: true - in: query name: device.name description: Equivalent to deviceName, and ignored if deviceName is supplied schema: type: string deprecated: true - in: query name: sortBy description: Sort by a single field of the attachment schema: type: string enum: - logTime - in: query name: projectId description: Filter attachments by project schema: type: string - $ref: '#/components/parameters/sortOrder' - $ref: '#/components/parameters/limit' - $ref: '#/components/parameters/offset' responses: '200': description: Success content: application/json: schema: type: array items: $ref: '#/components/schemas/RecordingAttachment' /recording-attachments/{id}: parameters: - in: path name: id schema: type: string required: true description: ID of the attachment get: tags: - Recording Attachments summary: Get an attachment security: - ApiKey: - recordings.list - QueryServiceToken: [] responses: '200': description: Success content: application/json: schema: $ref: '#/components/schemas/RecordingAttachment' /recording-attachments/{id}/download: parameters: - in: path name: id schema: type: string required: true description: ID of the attachment to download get: tags: - Recording Attachments summary: Download an attachment description: > To download an attachment make a request to this endpoint and follow the 302 redirect. The attachment will download directly from the Primary Site. Note: The redirect link expires after 15 minutes. security: - ApiKey: - recordings.list x-codeSamples: - lang: python label: Python source: | from foxglove.client import Client token = "" client = Client(token=token) bytes = client.download_attachment(id='att_0dHT6ZvqJhfwOcml') responses: '302': description: Found headers: Location: schema: type: string /data/coverage: get: tags: - Coverage summary: List coverage description: >- A coverage range represents a time span for which Foxglove has data for a given device. You must specify the `start` and `end` arguments when making a coverage request. Note: By default, only coverage ranges with imported recordings are returned. To include coverage ranges with unimported recordings from an Edge Site or a device running Foxlet, set the `includeEdgeRecordings` query parameter to true security: - ApiKey: - data.coverage.list x-codeSamples: - lang: python label: Python source: | from foxglove.client import Client from datetime import datetime, timedelta token = "" client = Client(token=token) client.get_coverage( start=datetime.now() - timedelta(hours=3), end=datetime.now() - timedelta(hours=1), ) parameters: - $ref: '#/components/parameters/start' - $ref: '#/components/parameters/end' - in: query name: tolerance description: > Minimum interval (in seconds) that ranges must be separated by to be considered discrete. Currently, the minimum meaningful value is 14s and smaller values will be clamped to this value. schema: type: number minimum: 0 required: false - in: query name: deviceId description: Filter coverage by device ID schema: type: string required: false - in: query name: deviceName description: Name of device associated with the data schema: type: string required: false - in: query name: device.name description: Equivalent to deviceName, and ignored if deviceName is supplied schema: type: string required: false deprecated: true - in: query name: device.id description: Equivalent to deviceId, and ignored if deviceId is supplied schema: type: string required: false deprecated: true - in: query name: includeEdgeRecordings description: > Include recordings from an Edge Site or a device running Foxlet in the response. When edge recordings are included, each item in the response array will also include the `importStatus` for the coverage range. schema: type: boolean default: false required: false - in: query deprecated: true name: importId description: Filter coverage by import ID schema: type: string required: false - in: query name: recordingId description: Filter coverage by recording ID schema: type: string required: false - in: query name: recordingKey description: Filter coverage by recordingKey schema: type: string required: false - in: query name: sessionId description: Filter coverage to recordings in the session with this ID schema: type: string required: false - in: query name: sessionKey description: Filter coverage to recordings in the session with this key schema: type: string required: false - in: query name: projectId description: Filter coverage by project schema: type: string responses: '200': description: Coverage content: application/json: schema: type: array items: $ref: '#/components/schemas/Coverage' /data/import-errors: get: tags: - Recordings summary: List import errors description: > List import errors. These are failed pending imports that have encountered errors during processing. security: - ApiKey: - data.imports.pending.list parameters: - in: query name: deviceName description: Name of device associated with the import error schema: type: string - in: query name: filenameMatches description: Pattern to match against filename schema: type: string - in: query name: error description: A string to filter based on error messages schema: type: string - in: query name: projectId description: Filter import errors by project schema: type: string - in: query name: sortBy description: Sort by a single field schema: type: string enum: - createdAt - deviceName - error - requestId - updatedAt - $ref: '#/components/parameters/sortOrder' - $ref: '#/components/parameters/limit' - $ref: '#/components/parameters/offset' responses: '200': description: Success content: application/json: schema: type: array items: $ref: '#/components/schemas/PendingImport' /data/stream: post: tags: - Stream data summary: Download data x-projectIdOptional: true description: > This endpoint returns a `link` URL where you can download your data as an `.mcap` or `.bag` file. To download your data: 1. Make a request to this endpoint. 2. Make a `GET` request to the `link` URL. One of `recordingId`, `key`, `importId` (deprecated) or all three of `deviceId`/`deviceName`, `start`, and `end` must be specified. _Note: You can only export a `.bag` file if you originally uploaded a `.bag` file._ security: - ApiKey: - data.stream x-codeSamples: - lang: python label: Python source: | from foxglove.client import Client, CompressionFormat, OutputFormat from datetime import datetime, timedelta token = "" client = Client(token=token) bytes = client.download_data( device_id=device_id, start=datetime.now() - timedelta(hours=3), end=datetime.now() - timedelta(hours=1), topics=["/clock", "/tracked_objects"], output_format=OutputFormat.mcap, compression_format=CompressionFormat.lz4, callback=lambda progress: print(".", end=""), ) # Or, to download using a recording ID: bytes = client.download_recording_data(id="rec_0dHT6g6cOfff9m5U") requestBody: required: true content: application/json: schema: type: object properties: topics: type: array items: type: string description: >- List of topics to include in the exported file (defaults to all topics) outputFormat: type: string description: | Output file format. * `bag1` - output a .bag file * `mcap` - output a .mcap file * `mcap0` - Deprecated. Use `mcap`. enum: - bag1 - mcap - mcap0 compressionFormat: type: string description: > Output compression format for chunks. Only valid if `outputFormat` is `mcap`. * `""` - no compression * `zstd` - zstd compression * `lz4` - LZ4 compression (default) default: lz4 enum: - '' - zstd - lz4 includeAttachments: type: boolean description: > Include attachments in streamed data. One of `recordingId` or `importId` (deprecated) must also be set. Only valid for mcap outputFormat. isHosted: type: boolean description: true if the import is hosted replayPolicy: type: string description: > If set to "lastPerChannel", then the stream will include the most recent message on each channel, even if it comes before the requested `start`, as long as it is within the window of `replayLookbackSeconds` seconds before `start`. The default, `""` (no policy), means no messages before `start` are included. enum: - lastPerChannel - '' replayLookbackSeconds: type: number description: > The maximum amount of time (in seconds) to look back before `start` in order to find the latest message. Only used if `replayPolicy` is set to "lastPerChannel". minimum: 0 deviceId: type: string description: ID of device associated with the exported data minLength: 1 device.id: type: string description: Equivalent to deviceId, and ignored if deviceId is supplied deprecated: true minLength: 1 deviceName: type: string description: Name of device associated with the exported data. minLength: 1 device.name: type: string description: >- Equivalent to deviceName, and ignored if deviceName is supplied deprecated: true minLength: 1 start: type: string format: date-time description: >- Inclusive start of requested time range. If start is provided, end must be too. end: type: string format: date-time description: >- Inclusive end of requested time range. If end is provided, start must be too. importId: type: string description: ID of the import to stream deprecated: true minLength: 1 recordingId: type: string description: ID of the recording to stream minLength: 1 recordingKey: type: string description: Key of recording to stream minLength: 1 key: type: string deprecated: true description: Key of recording to stream minLength: 1 sessionId: type: string description: ID of a session to stream minLength: 1 sessionKey: type: string description: >- Key of a session to stream. Ensure projectId is provided if streaming by sessionKey. minLength: 1 projectId: type: string description: > ID of a project to scope the streaming to. Recommended when streaming by deviceName. Required if the device name exists in multiple projects. Required when streaming by sessionKey. minLength: 1 responses: '200': description: Success content: application/json: schema: type: object properties: link: type: string description: >- A signed url to access the data. This link expires after 15 seconds. required: - link /data/upload: post: tags: - Recordings summary: Upload a recording description: > Use this endpoint to upload data to your `foxglove-hosted` site. The upload is a two-request process. 1. Make a request to this upload endpoint to create an upload `link`. 2. Issue a PUT HTTP request to the `link` response field URL. _Your PUT request header should have `Content-Type: application/octet-stream`, and your request body should contain your file content._ Note: If you are using a self-hosted site, see [this guide](https://docs.foxglove.dev/docs/primary-sites/self-hosting/manage-data) for uploading data. #### Size considerations While we support processing very large files, we generally recommend avoiding large (50GB+) files to reduce the chance of upload failures or processing issues. If you have tooling that generates very large files, consider splitting them up into smaller chunks. security: - ApiKey: - data.upload x-codeSamples: - lang: python label: Python source: | from foxglove.client import Client from pathlib import Path token = "" client = Client(token=token) with Path("my_mcap_data.mcap").open("rb") as byte_stream: client.upload_data( device_id=device_id, filename="my_mcap_data.mcap", data=byte_stream, callback=lambda size, progress: print(size, progress), project_id="", ) requestBody: required: true description: >- In addition to `filename`, one of `deviceId`, `deviceName`, or `key` is required and `projectId` is recommended. content: application/json: schema: type: object properties: deviceId: type: string description: Foxglove ID of the associated device deviceName: type: string description: >- Unique name of the associated device. If no device exists with this name, the device will be created. device.name: type: string deprecated: true description: >- Equivalent to deviceName, and ignored if deviceName is supplied device.id: type: string deprecated: true description: Equivalent to deviceId, and ignored if deviceId is supplied filename: type: string description: Name of the file that will be uploaded key: type: string minLength: 1 description: A unique key to identify the recording projectId: type: string description: >- The project ID that the recording belongs to. Required for multi-project orgs if an existing device is not provided sessionId: type: string description: ID of an existing session to associate the upload with. sessionKey: type: string description: >- Key of a session to associate the upload with. If no session exists with this key, a new session will be created using the provided device. required: - filename responses: '200': description: Upload details content: application/json: schema: type: object properties: link: type: string description: >- A signed upload URL. Upload your data to this URL using a PUT request. requestId: type: string required: - link - requestId /data/topics: get: tags: - Topics summary: List topics description: >- Get a list of topics available for a device within a given time range. By default, this endpoint will not return the `schema` for each topic. To include the schemas, you must provide the `includeSchemas` query parameter. Use `start` and `end` to limit the response to overlapping recording ranges. Topics for not-imported recordings are only returned if no parameter is provided besides recordingId or recordingKey. This is because most parameters need the imported files to filter, and can only return an empty list if imports are unavailable. security: - ApiKey: - data.topics.list x-codeSamples: - lang: python label: Python source: | from foxglove.client import Client from datetime import datetime, timedelta token = "" client = Client(token=token) client.get_topics( device_id=device_id, start=datetime.now() - timedelta(hours=3), end=datetime.now() - timedelta(hours=1), ) parameters: - $ref: '#/components/parameters/start' description: | Return all topics appearing in recordings ending on or after `start` - $ref: '#/components/parameters/end' description: > Return all topics appearing in recordings starting on or before `end` (updated March 2024 to be `<=` instead of `<`) - in: query name: importId description: ID of the import from which to list topics deprecated: true schema: type: string minLength: 1 required: false - in: query name: recordingId description: ID of the recording from which to list topics schema: type: string minLength: 1 required: false - in: query name: recordingKey description: Key of the recording from which to list topics schema: type: string minLength: 1 required: false - in: query name: deviceId description: ID of device being queried schema: type: string minLength: 1 required: false - in: query name: device.name description: Equivalent to deviceName, and ignored if deviceName is supplied schema: type: string minLength: 1 required: false deprecated: true - in: query name: deviceName description: Name of device being queried schema: type: string minLength: 1 required: false - in: query name: device.id description: Equivalent to deviceId, and ignored if deviceId is supplied schema: type: string minLength: 1 required: false deprecated: true - in: query name: sessionId description: ID of a recording session to list topics from schema: type: string minLength: 1 required: false - in: query name: sessionKey description: Key of a recording session to list topics from schema: type: string minLength: 1 required: false - in: query name: includeSchemas description: Whether full schemas should be included in the response schema: type: boolean default: false required: false - in: query name: sortBy description: Sort by a single field of the topic type ("topic" or "version") schema: type: string enum: - topic - version required: false - in: query name: projectId description: Filter topics matching project ID schema: type: string required: false - $ref: '#/components/parameters/sortOrder' - $ref: '#/components/parameters/limit' - $ref: '#/components/parameters/offset' responses: '200': description: List of topics content: application/json: schema: type: array items: $ref: '#/components/schemas/Topic' /devices/{nameOrId}: parameters: - in: path name: nameOrId schema: type: string required: true description: > Device name or ID. Device names must be URI-encoded if they contain non-URI-safe characters. If a device is named with another device's ID, the device with the matching name will be returned. get: tags: - Devices summary: Get a device description: | Get details on a specific device. security: - ApiKey: - devices.list x-projectIdOptional: true x-codeSamples: - lang: python label: Python source: | from foxglove.client import Client token = "" client = Client(token=token) client.get_device( device_id=device_id, ) parameters: - in: query name: projectId description: Filter devices by project schema: type: string required: false responses: '200': description: Success content: application/json: schema: allOf: - $ref: '#/components/schemas/Device' - $ref: '#/components/schemas/DeviceRemoteAccessState' delete: tags: - Devices summary: Delete a device description: > Delete a device. Once a device is deleted, it will no longer show up in your list of devices. _Before deleting a device, you must delete all associated data._ security: - ApiKey: - devices.delete x-projectIdOptional: true x-codeSamples: - lang: python label: Python source: | from foxglove.client import Client token = "" client = Client(token=token) client.delete_device(device_id=device_id) parameters: - in: query name: projectId description: Filter devices by project schema: type: string required: false responses: '200': description: Success content: application/json: schema: type: object properties: id: type: string description: The ID of the deleted device required: - id patch: tags: - Devices summary: Update a device security: - ApiKey: - devices.update x-projectIdOptional: true parameters: - in: query name: projectId description: Filter devices by project schema: type: string required: false requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: Device names must be unique within a project. retainRecordingsSeconds: type: integer minimum: 0 description: > Optionally set a retention period for recordings created on a device running Foxlet. If set to zero, recordings are retained indefinitely. This is only relevant for devices that have Foxlet installed. properties: description: > A key-value map, where each key is one of your pre-defined device custom property keys. Keys which are not recognized as custom properties will be ignored. Keys which are not included in the request, but exist on the device, will be unchanged. To unset a property, pass `null` as the value. type: object additionalProperties: true required: [] enabled: description: > Whether this device is enabled. Devices are enabled by default, unless they are created with a device token with `preapproved` set to false. Disabled devices show up in the device list, but you can't upload recordings for them. A device token linked to a disabled device does not grant access to the API. type: boolean remoteAccessEnabled: description: > Whether remote access is enabled for this device. When disabled, the device cannot establish new remote access sessions. type: boolean autoDeleteAfterImport: description: > Whether recordings on a device running Foxlet are automatically deleted once they have been successfully uploaded and accepted for import. This is only relevant for devices that have Foxlet installed. Foxlet versions older than 1.5.0 ignore this setting until upgraded. type: boolean responses: '200': description: Update device content: application/json: schema: $ref: '#/components/schemas/Device' /devices/{nameOrId}/property-time-intervals: parameters: - in: path name: nameOrId schema: type: string required: true description: > Device name or ID. Device names must be URI-encoded if they contain non-URI-safe characters. If a device is named with another device's ID, the device with the matching name will be returned. get: tags: - Devices - Properties summary: List property time intervals description: > Returns a list of values and the time intervals for which they were in effect for a device. Use the `query` parameter to filter property history on custom property key/value criteria. Syntax: * `key:value`: matches rows where the property key is `key` and the value equals `value`; use double quotes if the value contains spaces or special characters * `key:value1,value2`: matches rows where the property key is `key` and the value is either `value1` or `value2` * `key:*`: matches rows where the property key is `key` and any value * `*:value`: matches rows where any key has the value `value` * `foo`: matches rows where any key or stringified value contains `foo` Multiple qualifiers can be used in the same query string; this will filter rows matching the intersection of the qualifiers (AND). security: - ApiKey: - devices.list x-projectIdOptional: true parameters: - in: query name: projectId description: >- The project ID that the device belongs to. Required for multi-project orgs. schema: type: string required: false - in: query name: query description: >- Space-separated query string for device property history. Each custom property key must be valid. See above for syntax and examples. schema: type: string required: false - in: query name: start description: Properties active on or after this time will be included. schema: type: string format: date-time required: false - in: query name: end description: Properties active before this time will be included. schema: type: string format: date-time required: false - in: query name: sortBy description: Field to sort items by ("id", "key", "start", "end") schema: type: string enum: - id - key - start - end required: false - $ref: '#/components/parameters/sortOrder' - $ref: '#/components/parameters/offset' - $ref: '#/components/parameters/limit' responses: '200': description: Property time intervals content: application/json: schema: type: array items: $ref: '#/components/schemas/DeviceCustomPropertyTimeInterval' /devices/{nameOrId}/property-time-intervals/{id}: parameters: - in: path name: nameOrId schema: type: string required: true description: > Device name or ID. Device names must be URI-encoded if they contain non-URI-safe characters. If a device is named with another device's ID, the device with the matching name will be returned. - in: path name: id schema: type: string required: true description: | Property Time Interval ID. get: tags: - Devices - Properties summary: Get a device property time interval description: | Returns a specific device property time interval for a device. security: - ApiKey: - devices.list x-projectIdOptional: true parameters: - in: query name: projectId description: >- The project ID that the device belongs to. Required for multi-project orgs. schema: type: string required: false responses: '200': description: Property time interval content: application/json: schema: $ref: '#/components/schemas/DeviceCustomPropertyTimeInterval' /extension-upload: post: tags: - Extensions summary: Publish an extension description: >- **Available on Free, Pro, and Enterprise plans** Publish a new [Foxglove extension](https://docs.foxglove.dev/docs/extensions) or an updated version of an existing extension. When uploaded, the extension will automatically be installed for users in your organization. See our packaging tool [`create-foxglove-extension`](https://github.com/foxglove/create-foxglove-extension/) for more information on how to create an extension. Read the [docs](https://docs.foxglove.dev/docs/extensions) for more information on Foxglove extensions. requestBody: description: >- The request headers must contain `Content-Type: application/octet-stream`. The request body must contain the contents of your (`.foxe`) extension file. All other information about the extension will be parsed from the package.json file. **`package.json` requirements** An extension is uniquely identified by its publisher and name, which are both required in your `package.json`. Both values are case-insensitive, so a package named `custompanel` would be the same as one named `CustomPanel`. To update an extension, change its version in `package.json`, create a new `.foxe` bundle, and upload it via this endpoint. Version numbers must be unique to each extension. There are no other restrictions on versioning schemes. To publish an extension to your organization, your `package.json` must define a `displayName`. This is displayed to users in your organization. Once an extension is uploaded, its `displayName` may not be changed by future versions. required: true content: application/octet-stream: schema: type: string format: binary security: - ApiKey: - extensions.create responses: '200': description: Extension ID content: application/json: schema: properties: id: type: string required: - id '409': description: Conflict with package name and version content: application/json: schema: $ref: '#/components/schemas/Error' /extensions: get: tags: - Extensions summary: List extensions description: >- Organization admins can share and manage Foxglove extensions. Check out the [docs](https://docs.foxglove.dev/docs/extensions) to learn more. security: - ApiKey: - extensions.list responses: '200': description: List of extensions content: application/json: schema: type: array items: $ref: '#/components/schemas/Extension' /extensions/{id}: parameters: - in: path name: id schema: type: string required: true description: Extension ID get: tags: - Extensions summary: Get an extension security: - ApiKey: - extensions.list responses: '200': description: Extension details content: application/json: schema: $ref: '#/components/schemas/ExtensionWithSignedLink' delete: tags: - Extensions summary: Delete an extension description: > Once deleted, the extension will no longer be available within your organization. security: - ApiKey: - extensions.delete responses: '200': description: Success content: application/json: schema: type: object properties: id: type: string description: The ID of the deleted extension required: - id /events: get: tags: - Events security: - ApiKey: - events.list summary: List events description: > Retrieve a list of events. Use the `query` parameter to filter events on key/value criteria. The `queryFields` parameter can be used in combination with `query` to specify which fields to filter events by. Syntax: * `key:value`: matches events with metadata that contains a key named `key` with a value of `value`; use double quotes if the value contains spaces or special characters * `key:value1,value2`: matches events with metadata that contains a key named `key` with a value of either `value1` or `value2` * `key:*`: matches events where any metadata that contains a key named `key` * `*:value`: matches events where any metadata that contains `value` as a value * `foo`: matches events with metadata where any key or value string contains `foo` Multiple qualifiers can be used in the same query string; this will filter events where metadata matches the intersection of the qualifiers (AND). Examples: * `key1:value1 key2:value2`: matches metadata that contains both a key named `key1` with its value `value1` and another key named `key2` with its value `value2` * `key:"value with spaces"`: matches metadata with a key named `key` and its value `value with spaces` * `key:value foo`: matches metadata that contains both a key named `key` with its value `value` and any key or value that contains the text `foo` > Note: The `start` and `end` query arguments will find any events which intersect the query range (inclusive of start and end). x-codeSamples: - lang: python label: Python source: | from foxglove.client import Client from datetime import datetime, timedelta token = "" client = Client(token=token) client.get_events( device_id=device_id, sort_by=sort_by, sort_order=sort_order, limit=limit, offset=offset, start=datetime.now() - timedelta(hours=3), end=datetime.now() - timedelta(hours=1), query="key:val" ) parameters: - $ref: '#/components/parameters/start' - $ref: '#/components/parameters/end' - in: query name: createdAfter description: | Return all events created after this date and time schema: type: string format: date-time - in: query name: updatedAfter description: | Return all events updated after this date and time schema: type: string format: date-time - in: query name: projectId description: Filter events by project schema: type: string required: false - in: query name: deviceId description: Filter events matching device ID schema: type: string - in: query name: eventId description: Filter events by exact event ID schema: type: string - in: query name: deviceName description: Name of device associated with the event schema: type: string - in: query name: device.name description: Equivalent to deviceName, and ignored if deviceName is supplied schema: type: string deprecated: true - in: query name: device.id description: Equivalent to deviceId, and ignored if deviceId is supplied schema: type: string deprecated: true - in: query name: query description: >- Event query string. Comprises a space-separated list of event queries, where the syntax of those queries is described above. schema: type: string - in: query name: queryFields description: Which fields to query events by. Defaults to "metadata". explode: false schema: type: array items: type: string enum: - metadata - properties - in: query name: sortBy description: field to sort response items by schema: type: string enum: - id - deviceId - deviceName - device.name - device.id - start - createdAt - updatedAt - in: query name: eventTypeId description: Filter events by their event type. schema: type: string - $ref: '#/components/parameters/sortOrder' - $ref: '#/components/parameters/limit' - $ref: '#/components/parameters/offset' responses: '200': description: A list of device events content: application/json: schema: type: array items: $ref: '#/components/schemas/Event' post: tags: - Events security: - ApiKey: - events.create x-projectIdOptional: true summary: Create an event description: | Create a new event. Note: Creating an new event currently requires a device ID or device name, however the `device` field on the Event resource responses is optional to allow future API expansion for attaching events to other types of resources. x-codeSamples: - lang: python label: Python source: | from foxglove.client import Client from datetime import datetime, timedelta token = "" client = Client(token=token) event_time = datetime.now() client.create_event( device_id=device_id, start=event_time, end=event_time, metadata={"message": "Hi from python!"} ) requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/EventCreateInput' responses: '200': description: The created event content: application/json: schema: $ref: '#/components/schemas/Event' /events/{id}: parameters: - in: path name: id schema: type: string required: true description: ID of the event get: tags: - Events summary: Get an event security: - ApiKey: - events.list responses: '200': description: The event content: application/json: schema: $ref: '#/components/schemas/Event' delete: tags: - Events security: - ApiKey: - events.delete summary: Delete an event x-codeSamples: - lang: python label: Python source: | from foxglove.client import Client token = "" client = Client(token=token) client.delete_event( event_id=event_id, ) responses: '200': description: ID of the deleted event content: application/json: schema: $ref: '#/components/schemas/EventDeleteResponse' patch: tags: - Events summary: Update an event security: - ApiKey: - events.update requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/EventUpdateInput' responses: '200': description: The updated event content: application/json: schema: $ref: '#/components/schemas/Event' /event-types: get: tags: - Event Types summary: List event types security: - ApiKey: - eventTypes.list parameters: [] responses: '200': description: A list of event types content: application/json: schema: type: array items: allOf: - $ref: '#/components/schemas/EventType' - type: object post: tags: - Event Types summary: Create an event type security: - ApiKey: - eventTypes.create requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: Name of the event type minLength: 1 maxLength: 32 colorName: type: string description: Color name of the event type, e.g. "red" minLength: 1 maxLength: 32 customProperties: type: array items: $ref: '#/components/schemas/EventTypeCustomProperty' description: >- Ordered array of custom properties associated with the event type required: - name - customProperties responses: '200': description: The created event type content: application/json: schema: $ref: '#/components/schemas/EventType' /event-types/{id}: parameters: - in: path name: id schema: type: string required: true description: ID of the event type get: tags: - Event Types summary: Get an event type security: - ApiKey: - eventTypes.list parameters: [] responses: '200': description: The event type content: application/json: schema: allOf: - $ref: '#/components/schemas/EventType' - type: object patch: tags: - Event Types summary: Update an event type security: - ApiKey: - eventTypes.update requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: Name of the event type minLength: 1 maxLength: 32 colorName: type: string description: Color name of the event type, e.g. "red" minLength: 1 maxLength: 32 customProperties: type: array items: $ref: '#/components/schemas/EventTypeCustomProperty' description: >- Ordered array of custom properties associated with the event type. This will replace the existing customProperties list. minProperties: 1 responses: '200': description: The updated event type content: application/json: schema: $ref: '#/components/schemas/EventType' delete: tags: - Event Types summary: Delete an event type security: - ApiKey: - eventTypes.delete responses: '200': description: ID of the deleted event type content: application/json: schema: type: object properties: id: type: string description: ID of the deleted event type required: - id /lake-files: get: tags: - Lake files summary: List lake files description: > This endpoint returns a list of MCAP files in the lake bucket for a given Primary Site. For each recording that has been imported, multiple files are created — one per topic. This endpoint is only supported for self-managed sites. A query must be limited to a specific device or recording using one of the following parameters: - deviceId - deviceName - recordingId - recordingKey If querying by a device (ID or name), you must also provide `start` and `end` parameters to limit the range of files included. Queries for a specific recording do not require `start` and `end`. The range expressed by `start` and `end` must not exceed 24h. security: - ApiKey: - data.stream parameters: - in: query name: siteId schema: type: string description: >- The ID of a self-managed Primary Site for which the files have been imported required: true - in: query name: deviceId schema: type: string minLength: 1 description: ID of the device associated with the imported files required: false - in: query name: deviceName schema: type: string minLength: 1 description: Name of the device associated with the imported files required: false - in: query name: recordingId schema: type: string minLength: 1 description: A recording ID for which the files have been imported required: false - in: query name: recordingKey schema: type: string minLength: 1 description: A recording key for which the files have been imported required: false - in: query name: sessionId schema: type: string minLength: 1 description: Filter to files for recordings in the session with this ID required: false - in: query name: sessionKey schema: type: string minLength: 1 description: Filter to files for recordings in the session with this key required: false - in: query name: start schema: type: string format: date-time description: >- Inclusive start of an imported recording's time range. If start is provided, end must be too. required: false - in: query name: end schema: type: string format: date-time description: >- Inclusive end of an imported recording's time range. If end is provided, start must be too. required: false - in: query name: topic schema: type: string description: Include only imported files matching this topic name required: false responses: '200': description: Success content: application/json: schema: type: array items: type: object properties: path: type: string description: The full path of the file in the lake bucket topics: description: The topic names associated with this file type: array items: type: string required: - path - topics /layouts: get: tags: - Layouts summary: List layouts description: > List the org layouts. Note: Only layouts shared with the org are returned in the response; no personal layouts are returned. security: - ApiKey: - layouts.list parameters: - in: query name: updatedSince description: Return only layouts updated since this time. schema: type: string format: date-time - in: query name: includeData description: > When set to false, the `data` field is omitted from the response items. This can be used to limit bandwidth when querying many Layouts. schema: type: boolean default: true responses: '200': description: List of org layouts content: application/json: schema: type: array items: $ref: '#/components/schemas/Layout' post: tags: - Layouts summary: Create a layout description: | Creates a layout. API keys can only create shared layouts. security: - ApiKey: - layouts.create requestBody: required: true content: application/json: schema: type: object properties: id: type: string maxLength: 36 name: type: string savedAt: type: string format: date-time folderName: type: string pattern: ^[^/]*$ description: | The folder name used to organize layouts in the UI. It cannot contain forward slashes. permission: $ref: '#/components/schemas/LayoutPermission' data: type: object additionalProperties: true description: > The layout contents. This format is not yet stable and may change without notice; treat it as opaque and round-trip values returned by the API. required: - data - name - permission responses: '200': description: Success content: application/json: schema: $ref: '#/components/schemas/Layout' '400': description: Invalid request content: application/json: schema: $ref: '#/components/schemas/Error' '409': description: Conflict with ID content: application/json: schema: $ref: '#/components/schemas/Error' /layouts/{id}: parameters: - in: path name: id schema: type: string required: true description: Layout ID get: tags: - Layouts summary: Get a layout security: - ApiKey: - layouts.list parameters: - in: query name: includeData description: Include data in response schema: type: boolean default: false responses: '200': description: Success content: application/json: schema: $ref: '#/components/schemas/Layout' '404': description: Not found content: application/json: schema: $ref: '#/components/schemas/Error' delete: tags: - Layouts summary: Delete a layout description: | Soft-deletes a layout. API keys can only delete shared layouts. security: - ApiKey: - layouts.delete responses: '200': description: Success content: application/json: schema: $ref: '#/components/schemas/GenericSuccess' '403': description: Caller is not permitted to delete this layout. content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Not found content: application/json: schema: $ref: '#/components/schemas/Error' patch: tags: - Layouts summary: Update a layout description: | Updates an existing layout. API keys can only update shared layouts. security: - ApiKey: - layouts.update requestBody: required: true content: application/json: schema: type: object properties: name: type: string folderName: type: string pattern: ^[^/]*$ description: > The folder name used to organize layouts in the UI. It cannot contain forward slashes. "" will unset the folderName. permission: $ref: '#/components/schemas/LayoutPermission' data: type: object additionalProperties: true description: > The layout contents. This format is not yet stable and may change without notice; treat it as opaque and round-trip values returned by the API. required: [] responses: '200': description: Success content: application/json: schema: $ref: '#/components/schemas/Layout' '400': description: Invalid request content: application/json: schema: $ref: '#/components/schemas/Error' '403': description: Caller is not permitted to update this layout. content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Not found content: application/json: schema: $ref: '#/components/schemas/Error' '409': description: Conflict content: application/json: schema: $ref: '#/components/schemas/Error' /layouts/{id}/restore: parameters: - in: path name: id schema: type: string required: true description: Layout ID post: tags: - Layouts summary: Restore a layout description: > Restores a soft-deleted layout. API keys can only restore shared layouts. security: - ApiKey: - layouts.delete responses: '200': description: Success content: application/json: schema: $ref: '#/components/schemas/GenericSuccess' '403': description: Caller is not permitted to restore this layout. content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Not found content: application/json: schema: $ref: '#/components/schemas/Error' /custom-properties: get: tags: - Custom Properties summary: List custom properties security: - ApiKey: - properties.list parameters: - in: query name: resourceType description: Filter properties matching a resource type schema: type: string enum: - device - event - session required: false responses: '200': description: The custom properties content: application/json: schema: type: array items: $ref: '#/components/schemas/CustomProperty' post: tags: - Custom Properties summary: Create a custom property security: - ApiKey: - properties.create requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/NewCustomProperty' responses: '200': description: The custom property content: application/json: schema: $ref: '#/components/schemas/CustomProperty' /custom-properties/{id}: parameters: - in: path name: id schema: type: string required: true description: Custom Property ID get: tags: - Custom Properties summary: Get a custom property security: - ApiKey: - properties.list responses: '200': description: The custom property content: application/json: schema: $ref: '#/components/schemas/CustomProperty' patch: tags: - Custom Properties summary: Edit a custom property security: - ApiKey: - properties.update requestBody: required: true content: application/json: schema: type: object properties: label: description: Display label for user interfaces type: string minLength: 1 maxLength: 32 values: description: >- Moved to `enumValues`. Reorder or add to enum values. Must be a superset of existing values. deprecated: true type: array items: type: string uniqueItems: true enumValues: description: >- Reorder or add to enum values. Must be a superset of existing values. type: array items: type: string uniqueItems: true required: [] responses: '200': description: The custom property content: application/json: schema: $ref: '#/components/schemas/CustomProperty' delete: tags: - Custom Properties summary: Delete a custom property description: > Deleting a device custom property removes all values associated with it. Event custom properties can only be deleted when they are not currently associated with any event values. security: - ApiKey: - properties.delete responses: '200': description: ID of the deleted custom property content: application/json: schema: type: object properties: id: type: string required: - id /sites: get: tags: - Sites summary: List sites description: | Retrieve a list of sites. security: - ApiKey: - sites.list responses: '200': description: List of sites content: application/json: schema: type: array items: $ref: '#/components/schemas/Site' post: tags: - Sites summary: Create a Site description: | Create a new site. security: - ApiKey: - sites.create requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: A name for this site type: type: string description: | The type of site to create. enum: - self-hosted - edge retainRecordingsSeconds: type: number minimum: 0 description: > Optionally set a retention period for recordings created at this site. If set to zero, recordings are retained indefinitely. (only available on Edge Sites) required: - name - type responses: '200': description: The new site content: application/json: schema: $ref: '#/components/schemas/Site' /sites/{id}: parameters: - in: path name: id schema: type: string required: true description: Site ID get: tags: - Sites summary: Get site details security: - ApiKey: - sites.list description: | Get details for a specific site. responses: '200': description: Site content: application/json: schema: $ref: '#/components/schemas/Site' patch: tags: - Sites summary: Update site details description: | Update the name or retention period for a Site. security: - ApiKey: - sites.update requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: A name for this site retainRecordingsSeconds: type: number description: > Optionally set a retention period for recordings created at this Edge Site. If set to zero, recordings are retained indefinitely. (only available on Edge Sites) url: type: string description: > The URL a self-hosted Primary Site exposes for accessing available data. See [The self-hosting installation guide](https://docs.foxglove.dev/docs/primary-sites/self-hosting/installation#configure-foxglove) for details. responses: '200': description: Updated site content: application/json: schema: $ref: '#/components/schemas/Site' delete: tags: - Sites summary: Delete a site security: - ApiKey: - sites.delete description: > Delete a site. _NOTE: Site deletion is permanent and cannot be undone. Any recordings stored at this site will no longer be available through Foxglove._ For `edge` and `self-hosted` sites, you should shut down your deployment before deleting the site through the API. If the site type is `self-hosted`, the contents of your inbox and lake buckets will not be affected by this action, and should be cleaned up separately after deleting the site. If the site type is `edge`, any files in edge storage will not be affected by this action. responses: '200': description: Success content: application/json: schema: type: object properties: id: type: string description: ID of the deleted site required: - id /site-inbox-notification-tokens: get: tags: - Site Inbox Notification Tokens summary: List inbox notification tokens security: - ApiKey: - sites.list parameters: - in: query name: siteId description: Restrict responses to site with this ID schema: type: string required: false responses: '200': description: List of inbox notification tokens content: application/json: schema: type: array items: $ref: '#/components/schemas/InboxNotificationToken' post: tags: - Site Inbox Notification Tokens summary: Create a site inbox notification token description: > Create a token that authenticates bucket notifications for a Primary Site in your org (self-managed or BYOS). See the [Primary Site Installation](https://docs.foxglove.dev/docs/data/primary-sites/installation#bucket-push-notifications) documentation for more details. security: - ApiKey: - sites.create requestBody: required: true content: application/json: schema: type: object properties: siteId: type: string description: Site associated with the newly created token required: - siteId responses: '200': description: The newly created inbox notification token content: application/json: schema: allOf: - $ref: '#/components/schemas/InboxNotificationToken' - type: object properties: token: type: string description: Generated token. This is only available on creation. /site-inbox-notification-tokens/{id}: parameters: - in: path name: id schema: type: string required: true description: Inbox notification token ID delete: tags: - Site Inbox Notification Tokens summary: Delete an inbox notification token security: - ApiKey: - sites.delete responses: '200': description: ID of the deleted token content: application/json: schema: type: object properties: id: type: string description: ID of the deleted inbox notification token required: - id /device-tokens: get: tags: - Device Tokens summary: List device tokens security: - ApiKey: - deviceTokens.list parameters: - in: query name: deviceId description: Filter by device ID schema: type: string required: false responses: '200': description: List of device tokens content: application/json: schema: type: array items: $ref: '#/components/schemas/DeviceToken' post: tags: - Device Tokens summary: Create a device token security: - ApiKey: - deviceTokens.create requestBody: content: application/json: schema: type: object properties: deviceId: type: string description: >- Device ID associated with the newly created token. If not given, the token will be "unassociated" with a device and will only be usable after using it to create a device. projectId: type: string description: >- Project ID associated with the newly created token. If deviceId is provided, this must match the project of the device. If deviceId is omitted, this is required. enabled: type: boolean description: Whether this token is enabled or not. preapproved: type: boolean description: >- Whether devices created with this token are preapproved or not. responses: '200': description: A new device token content: application/json: schema: allOf: - $ref: '#/components/schemas/DeviceToken' - type: object properties: token: type: string description: Generated token. This is only available on creation. /device-tokens/{id}: parameters: - in: path name: id schema: type: string required: true description: Device token ID get: tags: - Device Tokens summary: Get a device token security: - ApiKey: - deviceTokens.list responses: '200': description: The device token content: application/json: schema: $ref: '#/components/schemas/DeviceToken' patch: tags: - Device Tokens summary: Edit a device token security: - ApiKey: - deviceTokens.update requestBody: required: true content: application/json: schema: type: object properties: enabled: type: boolean description: Enables or disables the device token. required: - enabled responses: '200': description: The device token content: application/json: schema: $ref: '#/components/schemas/DeviceToken' delete: tags: - Device Tokens summary: Delete a device token security: - ApiKey: - deviceTokens.delete responses: '200': description: The deleted device token ID content: application/json: schema: type: object properties: id: type: string description: The device token ID required: - id /site-tokens: get: tags: - Site Tokens summary: List site tokens security: - ApiKey: - siteTokens.list parameters: - in: query name: siteId description: Filter by site ID schema: type: string required: false responses: '200': description: List of site tokens content: application/json: schema: type: array items: $ref: '#/components/schemas/SiteToken' post: tags: - Site Tokens summary: Create a site token security: - ApiKey: - siteTokens.create requestBody: required: true content: application/json: schema: type: object properties: siteId: type: string description: Site associated with the newly created token required: - siteId responses: '200': description: A new site token content: application/json: schema: allOf: - $ref: '#/components/schemas/SiteToken' - type: object properties: token: type: string description: Generated token. This is only available on creation. /site-tokens/{id}: parameters: - in: path name: id schema: type: string required: true description: Site token ID delete: tags: - Site Tokens summary: Delete a site token security: - ApiKey: - siteTokens.delete responses: '200': description: success content: application/json: schema: $ref: '#/components/schemas/GenericSuccess' /site-bucket-notifications: post: tags: - Sites summary: Notify new recording description: > Notify your primary site of a new recording to ingest. Most users should set up [Bucket notifications](/docs/data/primary-sites/installation#bucket-push-notification) instead. This endpoint requires a Site Bucket Notification Token as bearer token in the Authorization header: ``` Authorization: Bearer fox_snt_1234... ``` security: - SiteBucketNotificationBearerToken: [] requestBody: required: true content: application/json: schema: type: object properties: messageId: type: string description: >- Unique message identifier. Notifications will be deduplicated based on this value. fileName: type: string description: The name of the recording file in the bucket. minLength: 1 bucketName: type: string description: Bucket name minLength: 1 storageProvider: type: string enum: - google_cloud - aws - azure - s3_compatible description: > Storage provider used for the bucket. This must match the storage provider configured for your primary site's inbox bucket or indexed bucket. deviceId: type: string description: > Device to associate with the recording. This takes precedence over values provided in [object metadata or MCAP metadata](/docs/primary-sites/self-hosting/manage-data#adding-metadata-to-imports). minLength: 1 deviceName: type: string description: > Name of the device to associate with the recording. The device is looked up by name and created if it does not already exist. `deviceId` takes precedence over `deviceName` when both are provided. An existing device with a unique name resolves without a `projectId`. Provide `projectId` to disambiguate when the name matches devices in multiple projects, or to choose which project a new device is created in when your organization has multiple projects. This takes precedence over values provided in [object metadata or MCAP metadata](/docs/primary-sites/self-hosting/manage-data#adding-metadata-to-imports). minLength: 1 projectId: type: string description: > Project to associate with the recording. This takes precedence over values provided in [object metadata or MCAP metadata](/docs/primary-sites/self-hosting/manage-data#adding-metadata-to-imports). minLength: 1 required: - messageId - fileName - bucketName - storageProvider responses: '200': description: success content: application/json: schema: $ref: '#/components/schemas/GenericSuccess' /projects: get: tags: - Projects summary: List projects description: List all projects available to the authorized client security: - ApiKey: - projects.list responses: '200': description: Success content: application/json: schema: type: array items: $ref: '#/components/schemas/Project' /projects/{id}: parameters: - in: path name: id schema: type: string required: true description: Project ID components: securitySchemes: Session: type: apiKey in: cookie name: fox.session description: User permissions when signed into the website ApiKey: type: http scheme: bearer description: API key authentication using HTTP Bearer auth SiteBucketNotificationBearerToken: type: http scheme: bearer description: Site bucket notification authentication using HTTP Bearer auth schemas: Import: type: object properties: id: type: string description: Opaque ID importId: type: string deprecated: true orgId: type: string deviceId: type: string deviceName: type: string filename: type: string importTime: type: string format: date-time description: Imported timestamp start: type: string format: date-time description: Message log time start of imported data end: type: string format: date-time description: Message log time end of imported data inputType: type: string description: 'Supported input type: ROS 1 bag ("bag1") or MCAP v0.x ("mcap0") file' outputType: type: string description: >- Supported output type: ROS 1 bag ("bag1") or MCAP v0.x ("mcap0") file inputSize: type: number description: Size in bytes of the uploaded file format: bigint totalOutputSize: type: number description: Size in bytes of the data after processing format: bigint date: type: string description: Message log time start date in YYYYMMDD format e.g. 20170322 deleted: type: boolean required: - id - importId - orgId - filename - importTime - start - end PendingImport: properties: createdAt: type: string format: date-time description: When the pending import was created deviceId: type: string description: ID of device deviceName: type: string description: Name of the device from which the import originated error: type: string description: Error message, if status is "error" filename: type: string description: Filename of the import importId: type: string description: ID of import; undefined until status is "complete" orgId: type: string description: ID of org to which the import belongs pipelineStage: type: string description: stage in the import pipeline the import currently occupies requestId: type: string description: ID of the import request projectId: type: string description: ID of the project to which the import belongs siteId: type: string description: ID of Primary Site where import will be stored status: type: string description: Status of initiated import enum: - received - processing - ready for indexing - error - complete updatedAt: type: string format: date-time description: When the pending import was last updated quarantinedAt: type: string format: date-time description: When the pending import was quarantined required: - createdAt - filename - orgId - pipelineStage - requestId - updatedAt - siteId Extension: type: object properties: id: type: string description: Assigned by backend name: type: string description: Name as it appears in your package.json publisher: type: string description: Publisher as it appears in your package.json displayName: type: string description: Display name as it appears in your package.json description: type: string nullable: true description: Description as it appears in the active version's package.json activeVersion: type: string nullable: true description: Version string as it appears in the active version's package.json sha256Sum: type: string nullable: true description: SHA-256 sum of the active version contents, encoded as hex required: - id - name - publisher - displayName - description - activeVersion - sha256Sum ExtensionWithSignedLink: allOf: - $ref: '#/components/schemas/Extension' - type: object properties: foxe: type: string description: Signed download link for the extension required: - foxe Coverage: type: object description: >- A coverage range represents a time span for which Foxglove has data for a given device. Recordings without devices are omitted except when queried by recording ID or import ID. properties: deviceId: type: string description: ID of device. device: description: Device summary. $ref: '#/components/schemas/CoverageDeviceSummary' start: type: string format: date-time description: Start of this coverage end: type: string format: date-time description: End of this coverage status: type: string deprecated: true description: The status of the coverage range enum: - at-edge - import-pending - imported importStatus: $ref: '#/components/schemas/RecordingImportStatus' required: - start - end - status Topic: type: object description: A topic to which messages can be published. properties: encoding: type: string description: Encoding of the topic schema: type: string description: >- Full schema, base-64 encoded; included only if the request's includeSchemas is true schemaEncoding: type: string description: Encoding of the topic schema schemaName: type: string description: Name of the topic schema topic: type: string description: Topic name version: type: string description: Topic version required: - encoding - schemaEncoding - schemaName - topic - version EventTypeCustomProperty: type: object properties: id: type: string description: ID of the custom property required: type: boolean description: Whether the custom property is required for this event type required: - id - required EventType: type: object properties: id: type: string description: ID of the event type name: type: string description: Name of the event type createdAt: type: string format: date-time description: When the event type was created updatedAt: type: string format: date-time description: When the event type was last updated colorName: type: string description: Color name of the event type, e.g. "red" customProperties: type: array items: $ref: '#/components/schemas/EventTypeCustomProperty' description: Ordered array of custom properties associated with the event type required: - id - name - createdAt - updatedAt RecordingAttachment: type: object description: >- An attachment resource represents information about an MCAP attachment imported to Foxglove. properties: id: type: string description: ID of the attachment recordingId: type: string description: ID of the recording with which the attachment is associated siteId: type: string description: ID of the Primary Site where the attachment data is stored name: type: string description: Name field from the attachment record mediaType: type: string description: Media type from the attachment record logTime: type: string description: Log time field from the attachment record createTime: type: string description: Create time field from the attachment record crc: type: number description: CRC field from the attachment record as a decimal number dataOffset: type: integer description: Offset to the start of the attachment in bytes size: type: integer description: Size of the attachment in bytes fingerprint: type: string description: > A hash of the attachment content (algorithm subject to change). Two attachments with the same fingerprint will have identical content. lakePath: type: string description: >- Path of attachment in lake storage. Only provided for [self-hosted Primary Sites](https://docs.foxglove.dev/docs/primary-sites#self-hosted). required: - id - recordingId - siteId - name - mediaType - logTime - createTime - crc - size - fingerprint LayoutPermission: type: string enum: - CREATOR_WRITE - ORG_READ - ORG_WRITE Layout: type: object properties: id: type: string description: ID of the layout name: type: string description: Name of the layout createdAt: type: string format: date-time description: Timestamp when the layout was created on the server updatedAt: type: string format: date-time description: Timestamp when the layout was last updated on the server savedAt: type: string format: date-time description: Timestamp when the layout was last saved locally folderName: type: string description: Name of the folder the layout belongs to. permission: $ref: '#/components/schemas/LayoutPermission' data: type: object description: > An object containing the layout data. Note: The layout data format is not considered stable and may change over time. additionalProperties: true required: - id - name - createdAt - updatedAt - permission NewCustomProperty: type: object properties: key: description: > An immutable identifier for this custom property; it cannot be edited once saved. This key is used to identify the custom property in queries; for example, when filtering your devices by a custom property ("partNumber:456"). type: string minLength: 1 maxLength: 32 pattern: ^[A-Za-z0-9_-]+$ label: description: Display label for user interfaces. May be changed after saving. type: string minLength: 1 maxLength: 32 resourceType: description: Resource type to which this custom property may be assigned type: string enum: - device - event - session valueType: description: | The type of the values associated with this custom property Number values will be treated as IEEE 754 64-bit floats. type: string enum: - string - multiline-string - number - enum - boolean - multi-enum values: description: >- Moved to `enumValues`. Allowed string values; required if `valueType` is "enum" deprecated: true type: array items: type: string uniqueItems: true enumValues: description: Allowed string values; required if `valueType` is "enum" type: array items: type: string uniqueItems: true required: - key - label - resourceType - valueType CustomProperty: type: object allOf: - type: object properties: id: type: string description: ID of the custom property required: - id - hasAssociatedData - $ref: '#/components/schemas/NewCustomProperty' Site: type: object properties: id: type: string description: Unique identifier for this site name: type: string description: Name for this site type: type: string description: > The type of the site. - `foxglove-hosted`: A [Foxglove-hosted Primary Site](https://docs.foxglove.dev/docs/primary-sites#foxglove-hosted). - `self-hosted`: A [self-hosted Primary Site](https://docs.foxglove.dev/docs/primary-sites#self-hosted). - `edge`: An [Edge Site](https://docs.foxglove.dev/docs/edge-sites). - `byob`: A [Bring Your Own Storage Site](https://docs.foxglove.dev/docs/primary-sites#bring-your-own-storage). enum: - foxglove-hosted - self-hosted - edge - byob url: type: string description: | The REST API endpoint your site deployment exposes (only available for self-hosted Primary Sites). retainRecordingsSeconds: type: number minimum: 0 description: > An optional retention period for recordings created at this site. If set to zero, recordings are retained indefinitely. (only available on Edge Sites) required: - id - name - type InboxNotificationToken: type: object description: >- An inbox notification token authenticates bucket notifications for a Primary Site (self-managed or BYOS) to the Foxglove API. properties: id: type: string orgId: type: string createdAt: type: string format: date-time description: Timestamp of the inbox notification token's creation siteId: type: string description: ID of the associated Primary Site required: - id - orgId - createdAt - siteId DeviceToken: type: object description: A DeviceToken authenticates a device to the API. properties: id: type: string createdAt: type: string format: date-time description: Timestamp of the device token's creation deviceId: type: string nullable: true description: ID of the associated device projectId: type: string description: ID of the associated project enabled: type: boolean description: Whether this token is enabled or not preapproved: type: boolean description: Whether devices created with this token are preapproved required: - id - createdAt - projectId - enabled - preapproved SiteToken: type: object description: >- A SiteToken resource provides site controllers with authentication to the api. properties: id: type: string description: ID of the site token createdAt: type: string format: date-time description: Timestamp of the site token's creation siteId: type: string description: ID of the associated Primary or Edge Site required: - id - createdAt - siteId RecordingImportStatus: type: string description: > The import status of recordings. Status will be one of: - `none`: The recording has not yet been imported, and import has not been requested. - `pending`: Foxglove has received a request to import this recording. - `importing`: The recording data is being processed for access via Foxglove. - `failed`: The recording data could not be imported. - `complete`: The contents of the recording are available for access via Foxglove. Note: `none` and `pending` statuses are applicable only to recordings originating from an Edge Site or a device running Foxlet. The set of `importStatus` values may expand in the future. enum: - none - pending - importing - failed - complete DeviceSummary: type: object description: | ID and name of a device. properties: id: type: string name: type: string required: - id - name EdgeSiteSummary: type: object description: | ID and name of an edge site. properties: id: type: string name: type: string required: - id - name PrimarySiteSummary: type: object description: | ID and name of a primary site. properties: id: type: string name: type: string indexingStrategy: type: string enum: - split-files - index-in-place required: - id - name - indexingStrategy webhook_payloads: Common: type: object properties: type: description: The event type type: string timestamp: description: When the webhook event occurred format: date-time type: string attemptedAt: description: When the delivery was attempted format: date-time type: string webhookEventId: description: ID of the associated webhook event type: string webhookId: description: ID of the webhook that notified your endpoint type: string required: - type - timestamp - attemptedAt - webhookId - webhookEventId Recording: allOf: - $ref: '#/components/schemas/webhook_payloads/Common' - properties: recording: properties: id: description: Recording ID type: string key: description: User-assigned key (if specified during recording upload) type: string sessionId: description: ID of the session associated with this recording type: string importStatus: $ref: '#/components/schemas/RecordingImportStatus' path: description: The filepath the recording was created with type: string device: $ref: '#/components/schemas/DeviceSummary' edgeSite: $ref: '#/components/schemas/EdgeSiteSummary' site: $ref: '#/components/schemas/PrimarySiteSummary' required: - id - path - importStatus type: object projectId: description: The ID of the project this recording belongs to type: string required: - recording - projectId type: object RecordingCreated: allOf: - $ref: '#/components/schemas/webhook_payloads/Recording' - properties: type: type: string const: recording.created RecordingImported: allOf: - $ref: '#/components/schemas/webhook_payloads/Recording' - properties: type: type: string const: recording.imported DeviceCreated: allOf: - $ref: '#/components/schemas/webhook_payloads/Common' - properties: device: properties: id: description: Device ID type: string required: - id type: object projectId: description: The ID of the project this device belongs to type: string required: - device - projectId type: object DeviceUpdated: allOf: - $ref: '#/components/schemas/webhook_payloads/Common' - properties: device: properties: id: description: Device ID type: string required: - id type: object projectId: description: The ID of the project this device belongs to type: string required: - device - projectId type: object SessionCreated: allOf: - $ref: '#/components/schemas/webhook_payloads/Common' - properties: session: properties: id: description: Session ID type: string device: $ref: '#/components/schemas/DeviceSummary' key: description: User-assigned key (if specified) type: string required: - id type: object projectId: description: The ID of the project this session belongs to type: string required: - session - projectId type: object EventCreated: allOf: - $ref: '#/components/schemas/webhook_payloads/Common' - properties: event: properties: id: description: Event ID type: string required: - id type: object projectId: description: The ID of the project this event belongs to type: string required: - event - projectId type: object EventUpdated: allOf: - $ref: '#/components/schemas/webhook_payloads/Common' - properties: event: properties: id: description: Event ID type: string required: - id type: object projectId: description: The ID of the project this event belongs to type: string required: - event - projectId type: object Ping: allOf: - $ref: '#/components/schemas/webhook_payloads/Common' - properties: webhook: properties: id: description: Webhook ID type: string required: - id type: object type: type: string const: ping required: - event type: object CustomPropertyValues: type: object additionalProperties: oneOf: - type: string - type: number - type: boolean - type: array items: type: string uniqueItems: true Device: type: object properties: id: type: string description: Opaque identifier name: type: string description: Organization-chosen device name projectId: type: string description: The project ID that the device belongs to retainRecordingsSeconds: type: number description: > The retention period for recordings created on this device. If set to zero, recordings are retained indefinitely. This is only relevant for devices that have Foxlet installed. properties: $ref: '#/components/schemas/CustomPropertyValues' description: > A key-value map of the custom properties associated with this device. enabled: type: boolean description: > Whether this device is enabled. Devices are enabled by default, unless they are created with a device token with `preapproved` set to false. Disabled devices show up in the device list, but you can't upload recordings for them. A device token linked to a disabled device does not grant access to the API. remoteAccessEnabled: type: boolean description: > Whether remote access is enabled for this device. When disabled, the device cannot establish new remote access sessions. autoDeleteAfterImport: type: boolean description: > Whether recordings on this device are automatically deleted once they have been successfully uploaded and accepted for import. This is only relevant for devices that have Foxlet installed. required: - id - name - projectId - enabled - remoteAccessEnabled - autoDeleteAfterImport - agentSupportsAutoDelete DeviceDetails: type: object properties: orgId: type: string createdAt: type: string format: date updatedAt: type: string format: date-time DeviceRemoteAccessState: type: object deviceName: type: string maxLength: 100 description: The name of the device. pattern: ^[A-Za-z0-9_.-]+$ RecordingMetadata: type: object description: | MCAP metadata pertaining to a recording. properties: name: type: string metadata: type: object additionalProperties: type: string required: - name - metadata Recording: type: object description: > A resource representing the content of an MCAP file or ROS bag managed by Foxglove. properties: id: type: string description: ID of the recording projectId: type: string description: The project ID that the recording belongs to path: type: string description: > The filepath of the recording as it was originally provided to Foxglove. For recordings originated at the edge, this is the full path of the recording file in the edge controller store. For recordings uploaded directly to Foxglove, this is the `filename` query arg provided to `/data/upload`. size: type: number description: The size of the recording file, in bytes format: bigint createdAt: type: string format: date-time description: Timestamp when the recording file was added to Foxglove. importedAt: type: string format: date-time description: Timestamp when the recording was imported to a primary site. start: type: string format: date description: The log time of the first message in the recording. end: type: string format: date description: The log time of the last message in the recording. importStatus: $ref: '#/components/schemas/RecordingImportStatus' site: description: The primary site for this recording. $ref: '#/components/schemas/PrimarySiteSummary' edgeSite: description: The edge site for this recording. $ref: '#/components/schemas/EdgeSiteSummary' device: $ref: '#/components/schemas/DeviceSummary' key: type: string description: > The unique, user-specified key assigned to a recording in MCAP metadata or during the upload process. This can be used to identify the recording, in addition to its `id`. metadata: type: array description: The metadata records of the original MCAP file content items: $ref: '#/components/schemas/RecordingMetadata' sessionId: type: string description: The ID of the session this recording belongs to. required: - id - projectId - path - size - start - end - createdAt - importStatus RecordingSession: type: object description: > A recording session represents a logical grouping of recordings from a single device. properties: id: type: string description: ID of the recording session projectId: type: string description: The project ID that the session belongs to device: $ref: '#/components/schemas/DeviceSummary' key: type: string description: | A user-supplied identifier, unique within the project. createdAt: type: string format: date-time description: Timestamp when the session was created. updatedAt: type: string format: date-time description: Timestamp when the session was last updated. properties: $ref: '#/components/schemas/CustomPropertyValues' description: > A key-value map of the custom properties associated with this session. recordings: type: array items: type: object properties: id: type: string description: ID of the recording path: type: string description: > The filepath of the recording as it was originally provided to Foxglove. For recordings originated at the edge, this is the full path of the recording file in the edge controller store. For recordings uploaded directly to Foxglove, this is the `filename` query arg provided to `/data/upload`. start: type: string format: date-time description: The log time of the first message in the recording. end: type: string format: date-time description: The log time of the last message in the recording. required: - id - path - start - end description: Recordings associated with this session. required: - id - projectId - device - createdAt - updatedAt - recordings RecordingSessionListItem: allOf: - $ref: '#/components/schemas/RecordingSession' - type: object properties: recordingCount: type: number readOnly: true description: Number of recordings associated with this session. recordingStart: type: string format: date-time readOnly: true description: >- Earliest log time among visible recordings associated with this session. recordingEnd: type: string format: date-time readOnly: true description: >- Latest log time among visible recordings associated with this session. required: - recordingCount CoverageDeviceSummary: allOf: - $ref: '#/components/schemas/DeviceSummary' - type: object properties: pendingCoverageUpdate: type: object optional: true description: > If the device has a pending coverage update, this object will contain the timestamp when the coverage refresh was last enqueued. If null, the device has no pending coverage update. properties: nextInvalidationRequestedAt: type: string format: date-time description: >- The timestamp when the device's coverage refresh was last enqueued. DeviceCustomPropertyTimeInterval: type: object properties: id: type: string description: ID of the property time interval. deviceId: type: string description: ID of the associated device. key: type: string description: Key of the property. value: description: Value of the property. oneOf: - type: string - type: number - type: boolean - type: array items: type: string uniqueItems: true start: type: string format: date-time description: Inclusive start time this value was in effect. end: type: string format: date-time description: >- Exclusive end time this value was in effect. When absent the value is still in effect. required: - id - deviceId - key - value - start Error: type: object properties: error: type: string required: - error Event: type: object properties: id: type: string description: ID of the event start: type: string format: date-time description: Event start time (inclusive) end: type: string format: date-time description: Event end time (inclusive) deviceId: type: string deprecated: true description: | ID of the device associated with the event. **deprecated**: Use `device.id` instead. device: $ref: '#/components/schemas/DeviceSummary' metadata: type: object additionalProperties: true required: [] description: Any metadata associated with the event createdAt: type: string format: date-time description: When the event was created updatedAt: type: string format: date-time description: When the event was last updated eventTypeId: type: string description: ID of the event type. properties: $ref: '#/components/schemas/CustomPropertyValues' description: | A key-value map of the custom properties associated with this event. required: - id - start - end - metadata - createdAt - updatedAt EventMetadataInput: type: object additionalProperties: type: string required: [] description: >- An object with user-defined string keys and string values; key order is not preserved EventCreateInput: type: object properties: deviceId: type: string description: ID of the device to associate with the event deviceName: type: string description: Name of the device to associate with the event projectId: type: string description: >- Optional project ID used to disambiguate deviceName and deviceId lookups device.id: type: string description: Equivalent to deviceId, and ignored if deviceId is supplied deprecated: true device.name: type: string description: Equivalent to deviceName, and ignored if deviceName is supplied deprecated: true metadata: $ref: '#/components/schemas/EventMetadataInput' start: type: string description: Event start time (inclusive) format: date-time end: type: string description: Event end time (inclusive) format: date-time eventTypeId: type: string description: If provided, the event must conform to the event type's schema. properties: $ref: '#/components/schemas/CustomPropertyValues' description: > A key-value map, where each key is one of your pre-defined event custom property keys. Keys which are not recognized as custom properties will be ignored. required: [] required: - start - end EventDeleteResponse: type: object properties: id: type: string description: ID of the deleted event. required: - id EventUpdatePropertiesInput: description: > A key-value map, where each key is one of your pre-defined event custom property keys. Keys which are not recognized as custom properties will be ignored. Keys which are not included in the request, but exist on the event, will be unchanged. To unset a property, pass `null` as the value. type: object additionalProperties: true required: [] EventUpdateEventTypeIdInput: type: string description: >- If provided, the event must conform to the event type's schema. An empty string will remove the event type. EventUpdateInput: type: object properties: metadata: $ref: '#/components/schemas/EventMetadataInput' start: type: string description: Event start time (inclusive) format: date-time end: type: string description: Event end time (inclusive) format: date-time properties: $ref: '#/components/schemas/EventUpdatePropertiesInput' eventTypeId: $ref: '#/components/schemas/EventUpdateEventTypeIdInput' GenericSuccess: type: object properties: success: type: boolean const: true required: - success Project: type: object properties: id: type: string name: type: string orgMemberCount: type: number description: Number of org members that can access this project lastSeenAt: type: string format: date-time description: Timestamp of the last recording uploaded to this project isInviteOnly: type: boolean description: >- Whether this project is invite-only. If true, org members with the user role will need explicit permission to access the project required: - id - isInviteOnly parameters: sortOrder: in: query name: sortOrder description: Sort order for the `sortBy` field schema: type: string enum: - asc - desc limit: in: query name: limit description: Maximum number of items to return schema: type: number minimum: 0 maximum: 2000 default: 2000 offset: in: query name: offset description: Number of items to skip before returning the results schema: type: integer minimum: 0 default: 0 start: in: query name: start description: Start of an inclusive time range schema: type: string format: date-time end: in: query name: end description: End of an inclusive time range schema: type: string format: date-time