Hubble Network Packets API

The Packets API from Hubble Network — 2 operation(s) for packets.

Operations 3

Each operation below carries the questions people ask an LLM about it and the instructions they give an agent to run it. Generated by API Evangelist overlay

GET /v1/org/{org_id}/packets Retrieve or stream device packets · Retrieve Packets #
Ask an LLM
“How do I pull the packets my devices have sent to the network?”
“Can I fetch packets for just one device over a specific time range?”
Tell an agent
Retrieve packets for organization {org_id} received between {start} and {end}.
Get packets from device {device_id} in org {org_id}.
POST /v1/org/{org_id}/packets/decode Decode Packets #
POST /v1/webhook/testBatch See the packet batch format a webhook receives · Packet Webhook Example #
Ask an LLM
“What does the payload look like when packet batches are posted to my webhook?”
“Which header should my receiving endpoint check to confirm a request really came from Hubble?”
Tell an agent
Post the example packet batch {packets} to the sample receiver with token {HTTP-X-HUBBLE-TOKEN}.
Show me how the reference webhook receiver accepts a packet batch signed with {HTTP-X-HUBBLE-TOKEN}.

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/hubble-network:hubble-network-packets-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

hubble-network-packets-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Hubble Platform Packets API
  description: 'The Hubble platform is built API-first. Use our Cloud API to manage your devices

    and access device data programmatically. We''ve designed our API following RESTful principles. Each endpoint returns standard HTTP status codes and may include JSON payloads. ---


    ## API Access

    Use API Keys to authenticate with the Hubble Cloud API for your organization. ### Generate an API Key

    Log in to your Hubble dashboard. Navigate to **Developer Tools > API Tokens** to create a new API Key. Provide a name for the token, and set an appropriate expiration date for temporary access. ### Organization ID

    You will need `org_id` to make API requests. From your Hubble dashboard, navigate to

    **Developer Tooks > API Tokens**, or **Organization Settings**, to find your Organization ID. ### Authorization Scopes

    API endpoints require specific authorization scopes to perform the intended operation. **Required Scope** is always provided in the API documentation. API Keys can be created with specific authorization scopes that control what operations the key can perform. If no scopes are specified, the key will be created with all available scopes (admin-level access). | **Scope** | **Access** |

    |------------------------------|-------------------------------------------------|

    | **read-api-keys** | View API keys and their metadata |

    | **write-api-keys** | Create, update, and delete API keys |

    | **read-users** | View user information and roles |

    | **write-users** | Add, update, and remove users from the organization |

    | **read-organization-metadata** | View organization details and settings |

    | **write-organization-metadata** | Update organization information |

    | **read-devices** | View device information and status |

    | **write-devices** | Register and manage devices |

    | **read-invitations** | View pending invitations |

    | **write-invitations** | Create and revoke user invitations |

    | **read-packets** | Access packet data and retrieval endpoints |

    | **read-platform-metrics** | View platform metrics and analytics |

    | **read-billing-usage** | View billing usage information |

    | **read-billing-invoices** | View billing invoices |

    | **read-webhooks** | View webhook configurations |

    | **write-webhooks** | Create and manage webhook endpoints |

    | **read-satellites** | View satellite ephemeris and pass data |


    **Example Scope Combinations**

    - Create a key with read-only access: `["read-api-keys", "read-users", "read-devices"]`

    - Create a key for device management: `["read-devices", "write-devices"]`

    - Create a key for user management: `["read-users", "write-users", "read-invitations", "write-invitations"]`


    **Best Practices for Data Security**

    - Create keys with the minimum required scopes for your use case

    - Regularly review and rotate API keys

    - Use descriptive names for your keys to track their purpose

    - Set appropriate expiration dates for temporary access


    ---


    ## Import API Definition

    You can quickly import the Hubble Cloud API into your preferred developer environment (such as Postman or Insomnia) using our **public OpenAPI definition**. Simply download or import the YAML file directly:


    https://hubble.com/docs/openapi.yaml


    ---


    ## Pagination

    When the number of objects requested exceeds the maximum page size for an endpoint, the API response will be paginated. This means you will receive a subset of the total results, along with a `Continuation-Token` in the Response Header that can be used to fetch subsequent subsets. To retrieve the next set of data, you must use the provided `Continuation-Token` in the Request Header of your next API call to the same endpoint. Continue using the provided token in each successive request until no `Continuation-Token` is returned, which indicates you have retrieved all available data. ---


    ## Rate Limits

    The Hubble Cloud API follows a leaky bucket approach to rate limiting. Endpoints are rate limited to three (3) requests per second. Your organization is limited to a total of 15 requests per second.'
  version: 1.0.0
servers:
- url: https://api.hubble.com
  description: Production
security:
- BearerAuth: []
tags:
- name: Packets
paths:
  /v1/org/{org_id}/packets:
    get:
      tags:
      - Packets
      operationId: retrieve-organization-packets
      x-criticality: high
      summary: Retrieve Packets
      description: 'Stream or query packets for your organization.


        **Required Scope:** `read-packets`


        ## Overview

        This endpoint acts as a data stream. Use the `Continuation-Token` to track your consumer''s position in the stream and ingest incrementally.

        Packets are returned in ascending order based on when they were detected by Hubble Network.


        ## Pagination and Streaming

        Use the `Continuation-Token` to capture new packets incrementally.

        If provided, all other query parameters are ignored, as the token persists the initial query''s configuration.


        ### Response Headers

        * `Continuation-Token`: an opaque cursor for your position in the stream. The max page size is 1,000 packets.

        * If you supplied an `end` time, an empty string indicates you have reached that end time and there is no more data in the requested window.

        * If you left `end` open, the token never goes empty, since the stream has no end to reach — it always points at your current position, whether or not new packets are waiting there.

        * `Retry-After`: the recommended number of seconds to wait before your next poll request (max value is 300 seconds). This is the signal to watch on an open stream: its presence means you are caught up to the live edge, so treat it as your polling backoff rather than looking for an empty `Continuation-Token`.


        ## Query Parameters (Initial Request)

        When starting a new stream (no `Continuation-Token` exists) or to query for data from a period of time, use these parameters to begin polling:


        ### Time Period (UTC, in seconds)

        * `start` time defaults to 7 days ago when not specified.

        * Omit `end` time to leave the stream open and poll for new packets indefinitely.

        * Supply an `end` time if your consumer needs a terminating, empty-token stop condition.


        :::tip

        Granular packet data is available up to **30 days** in the past.

        :::


        ### Device Filtering

        * When `device_id` is provided, only packets from that device will be returned.

        * Note: you cannot page indefinitely for single-device queries. The stream closes when it reaches current time.


        :::warning

        Device filtering is provided for troubleshooting. It should not be used for high-volume data retrieval.

        :::


        ---


        ## Packet Data Definitions (Response)


        ### Location Object

        For **TERRESTRIAL** packets, all `location` fields represent the scanning gateway''s most recent GPS lock:

        * `location.timestamp` is the timestamp of the location lock.

        * `location.latitude` and `location.longitude` are the location coordinates.

        * `location.horizontal_accuracy` and `location.vertical_accuracy` represent accuracy variance in meters.


        For **SATELLITE** packets, `location.timestamp` and `device.timestamp` are identical: both represent the time the packet was detected by the satellite.


        ### Device Object

        For **TERRESTRIAL** packets,

        * `device.timestamp` is the timestamp when the data packet was detected by the gateway.

        * `device.rssi` is the received signal strength measured by the gateway.


        ### Gateway Object

        For **self-provided** packets (packets your organization contributed and is also reading back, i.e. `provider_id == org_id`), the response optionally includes a top-level `gateway` object. These fields describe the **scanning gateway** that received the BLE advertisement.

        * `gateway.gateway_id` is the stable gateway UUID issued by Hubble when you register using the Gateway API.

        * `gateway.service_id` is the normalized 16-bit service UUID from the scanned BLE advertisement (e.g. `fca6`).


        :::note

        The `gateway` block is **omitted entirely** for packets sourced from a different organization (e.g. third-party crowdsourced traffic), and is also omitted on self-provided packets when no gateway context was attached at ingest.

        :::'
      parameters:
      - $ref: '#/components/parameters/orgIdPathParam'
      - $ref: '#/components/parameters/continuationTokenHeader'
      - $ref: '#/components/parameters/startQueryParam'
      - $ref: '#/components/parameters/endQueryParam'
      - $ref: '#/components/parameters/deviceIdQueryParam'
      responses:
        '200':
          description: A page of packets
          headers:
            Continuation-Token:
              $ref: '#/components/headers/ContinuationTokenHeader'
            Retry-After:
              $ref: '#/components/headers/RetryAfterHeader'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/packetBatch'
        '429':
          description: An error when too many requests have been made to retrieve packets
          headers:
            Continuation-Token:
              $ref: '#/components/headers/ContinuationTokenHeader'
            Retry-After:
              $ref: '#/components/headers/RetryAfterHeader'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/errorResponse'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '500':
          $ref: '#/components/responses/ErrorInternalServer'
  /v1/org/{org_id}/packets/decode:
    post:
      tags:
      - Packets
      operationId: decode-packets
      x-criticality: high
      summary: Decode Packets
      description: 'Synchronously decode and decrypt a small batch of BLE advertisement packets for your organization.


        **Required Scope:** `read-packets`


        The input advertisements are also forwarded to the asynchronous ingest pipeline (the same

        pipeline used by `GET /v1/org/{org_id}/packets`) so that packets are persisted regardless of

        the synchronous decode outcome.


        Only packets that successfully decode and that belong to the calling organization are

        returned in the response. Packets that fail to decode, or that belong to a different

        organization, are omitted from the response and are instead handled by the asynchronous

        pipeline.


        ## Limits

        * Maximum **25** advertisements per request.'
      parameters:
      - $ref: '#/components/parameters/orgIdPathParam'
      - $ref: '#/components/parameters/contentTypeJsonHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/decodePacketsRequestBody'
      responses:
        '200':
          description: A batch of decoded packets belonging to the calling organization.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/synchronousDecodePacketBatch'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '500':
          $ref: '#/components/responses/ErrorInternalServer'
  /v1/webhook/testBatch:
    post:
      tags:
      - Packets
      operationId: packet-webhook-example
      x-criticality: high
      summary: Packet Webhook Example
      description: 'This endpoint is an example webhook endpoint that each organization can implement in order to receive packet data.

        Packet data that has been decrypted for your organization will be forwarded to these webhooks.


        ### Batching

        Packets are sent in batches to minimize HTTP overhead from sending packets individually.

        Batch sizes are configurable per webhook endpoint.

        The actual number of packets per request will range between 1 and the configured `max_batch_size`.'
      parameters:
      - $ref: '#/components/parameters/contentTypeJsonHeader'
      - $ref: '#/components/parameters/webhookSecretHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/packetBatch'
      responses:
        '200':
          description: Message delivered.
        '500':
          description: Internal Server Error. Please Retry.
components:
  schemas:
    deviceId:
      type: string
      format: uuid
      description: Primary UUID identifier for a registered device
    deviceName:
      type: string
      description: Assigned name for the device
      maxLength: 250
    orgId:
      type: string
      format: uuid
      description: The ID for an organization
    gateway:
      type: object
      description: 'Metadata about the scanning gateway that received this packet — the relay

        that detected the BLE advertisement, not the device that emitted it.

        Only present on self-provided packets (`provider_id == org_id`) where

        gateway context was attached at ingest. Both fields are optional.

        '
      properties:
        gateway_id:
          type: string
          format: uuid
          description: 'Stable unique identifier of the gateway device that received the packet.

            This is the gateway UUID issued at registration time and is consistent

            across all packets from the same gateway.

            '
        service_id:
          type: string
          description: 'Normalized 16-bit BLE service UUID that the advertisement was scanned

            under (lowercase hex, e.g. `fca6` for Hubble packets). Identifies which

            BLE service profile the gateway matched when it captured this packet.

            '
          example: fca6
    packet:
      type: object
      properties:
        location:
          $ref: '#/components/schemas/location'
        device:
          type: object
          required:
          - id
          - payload
          - timestamp
          properties:
            id:
              $ref: '#/components/schemas/deviceId'
            name:
              $ref: '#/components/schemas/deviceName'
            tags:
              $ref: '#/components/schemas/deviceTags'
            payload:
              type: string
              description: A packet's decrypted payload in Base64 format
            rssi:
              type: number
            timestamp:
              $ref: '#/components/schemas/utcTimestampNumber'
            counter:
              type: number
              description: 'The time-based counter associated with this packet.

                '
            sequence_number:
              type: number
              description: 'The sequence number of this packet

                '
        network_type:
          type: string
          enum:
          - TERRESTRIAL
          - SATELLITE
        gateway:
          $ref: '#/components/schemas/gateway'
    utcTimestampInteger:
      type: integer
      format: int64
      description: An UTC second-precision timestamp formatted as an integer
    decodePacketsRequestBody:
      type: object
      required:
      - advertisements
      properties:
        advertisements:
          type: array
          minItems: 1
          maxItems: 25
          description: 'A flat list of BLE advertisement packets to decode. Each item carries its own

            `location`. Maximum 25 packets per request.

            '
          items:
            type: object
            required:
            - payload
            - rssi
            - timestamp
            - location
            properties:
              payload:
                type: string
                description: Raw BLE advertisement payload in Base64 format.
              rssi:
                type: number
                description: Signal strength in dBm.
              timestamp:
                $ref: '#/components/schemas/utcTimestampNumber'
              location:
                $ref: '#/components/schemas/location'
              metadata:
                allOf:
                - $ref: '#/components/schemas/providerMetadata'
                description: 'Optional per-advertisement provider/gateway metadata.

                  '
        metadata:
          allOf:
          - $ref: '#/components/schemas/providerMetadata'
          description: 'Optional batch-level provider/gateway metadata

            '
    synchronousDecodePacketBatch:
      type: object
      properties:
        packets:
          type: array
          items:
            $ref: '#/components/schemas/synchronousDecodePacket'
    providerMetadata:
      type: object
      description: 'Provider/gateway metadata describing the submitting client.

        '
      properties:
        platform:
          type: string
          description: Free-form platform identifier (e.g. `"android"`, `"ios"`, `"linux"`).
        platform_version:
          type: string
          description: Free-form platform / SDK version string.
        os:
          type: string
          description: Operating system name.
        os_version:
          type: string
          description: Operating system version string.
    location:
      type: object
      required:
      - latitude
      - longitude
      - altitude
      - timestamp
      properties:
        latitude:
          type: number
          description: Latitude in Decimal Degrees DDD.DDDDD°
        longitude:
          type: number
          description: Longitude in Decimal Degrees DDD.DDDDD°
        altitude:
          type: number
          description: Altitude in meters for the provided gps coordinates
        horizontal_accuracy:
          type: number
          description: Horizontal accuracy in meters for the provided gps coordinates
        vertical_accuracy:
          type: number
          description: Vertical accuracy in meters for the provided gps coordinates
        timestamp:
          $ref: '#/components/schemas/utcTimestampNumber'
    packetBatch:
      type: object
      properties:
        packets:
          type: array
          items:
            $ref: '#/components/schemas/packet'
    synchronousDecodePacket:
      description: 'A successfully decoded packet returned by `POST /v1/org/{org_id}/packets/decode`.

        '
      allOf:
      - $ref: '#/components/schemas/packet'
      - type: object
        properties:
          advertisement:
            type: object
            properties:
              payload:
                type: string
                description: 'The Base64-encoded BLE advertisement payload that was submitted for

                  decoding. Identical to the `payload` field on the corresponding input

                  advertisement object.

                  '
    deviceTags:
      type: object
      additionalProperties:
        type: string
      description: "Tags are user-defined key/value pairs that can be attributed to a device. \nA device may have up to 10 tags.\n**Custom tags:** create your own tags with `key` length up to 32 characters and `value` length up to 128 characters.\n**Platform tags:** use Hubble-defined tags to organize devices.\n- `_env` tag: `production` indicates if a device belongs to the live environment, and `sandbox` for the test environment. A device will always have an `_env` tag assigned.\n"
      example:
        _env: production
    utcTimestampNumber:
      type: number
      format: double
      description: An UTC second-precision timestamp formatted as a floating point number
    errorResponse:
      type: object
      properties:
        code:
          type: integer
          description: The HTTP status code
        description:
          type: string
          description: 'A description for the error.

            For user errors, we attempt to be as descriptive as possible to help with diagnosing the issue.

            For internal errors, the error description is only indicates that a retry should occur but we log the full error so that we can diagnose it.

            Error descriptions can change over time and should not be programmed against.

            '
        name:
          type: string
          enum:
          - Bad Request
          - Unauthorized
          - Not Found
          - Request Entity Too Large
          - Too Many Requests
          - Internal Server Error
          description: '`name` is a short name for the error.

            '
    webhookSecret:
      type: string
      description: 'A confidential, unique string generated for your webhook endpoint to validate that the request came from Hubble.

        Hubble will send this token in the HTTP header `HTTP-X-HUBBLE-TOKEN` when making HTTPS requests to your endpoint.

        '
  headers:
    RetryAfterHeader:
      description: 'The number of seconds to wait to attempt a retry.

        When attached to a 200, this is a suggestion because the most recent data has been retrieved already.

        When attached to a 429, this delay is a recommendation to reduce repeat 429s.

        '
      schema:
        type: integer
        minimum: 0
        maximum: 300
    ContinuationTokenHeader:
      description: A token to indicate how to continue paging
      schema:
        type: string
  parameters:
    orgIdPathParam:
      name: org_id
      in: path
      required: true
      schema:
        $ref: '#/components/schemas/orgId'
      description: Your organization ID
    deviceIdQueryParam:
      name: device_id
      in: query
      required: false
      schema:
        $ref: '#/components/schemas/deviceId'
      description: 'Filter packets to a specific device

        '
    webhookSecretHeader:
      name: HTTP-X-HUBBLE-TOKEN
      in: header
      required: true
      schema:
        $ref: '#/components/schemas/webhookSecret'
      description: 'A confidential, unique string generated for your webhook endpoint to validate that the request came from Hubble.

        '
    continuationTokenHeader:
      name: Continuation-Token
      in: header
      required: false
      schema:
        type: string
      description: A token to indicate how to continue paging
    startQueryParam:
      name: start
      in: query
      required: false
      schema:
        $ref: '#/components/schemas/utcTimestampInteger'
      description: "UTC timestamp (in seconds) indicating when to start retrieving packets. \nThis timestamp corresponds to when the packet was received by the network.\nIf omitted, defaults to 7 days before the current UTC time.\n"
    endQueryParam:
      name: end
      in: query
      required: false
      schema:
        $ref: '#/components/schemas/utcTimestampInteger'
      description: 'UTC timestamp (in seconds) indicating when to end retrieving packets.

        This timestamp corresponds to when the packet was received by the network.

        If omitted, defaults to empty (meaning the pagination will continue indefinitely).

        If specified, pagination will continue until all packets received prior to the timestamp have been returned.

        '
    contentTypeJsonHeader:
      name: Content-Type
      in: header
      schema:
        type: string
      description: An indication that the payload is JSON
      example: application/json
  responses:
    ErrorBadRequest:
      description: Bad Request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/errorResponse'
          example:
            code: 400
            description: The request could not be understood by the server due to malformed syntax.
            name: Bad Request
    ErrorInternalServer:
      description: Internal Server Error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/errorResponse'
          example:
            code: 500
            description: An unknown error has occurred.
            name: Unknown
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
x-provenance:
  method: harvested
  publisher: Hubble Network
  source: https://hubble.com/docs/openapi.yaml
  note: split by refine-openapis from the provider's own published document, verified by fetch (openapi/_original/*.fetch.json);
    stamped by stamp-openapi-provenance.py (roadmap#793)