Collect JSON data from an HTTP API

Poll a REST API on an interval, parse the JSON response into metrics, and write them to InfluxDB 3. This example collects live station status from Citi Bike, New York City’s public bike-share system, which publishes JSON without authentication.

Configuration

[[inputs.http]]
  ## URL for NYC's Citi Bike station data in JSON format
  urls = ["https://gbfs.citibikenyc.com/gbfs/en/station_status.json"]

  ## Overwrite measurement name from default `http` to `citibike`
  name_override = "citibike"

  ## Exclude url and host items from tags
  tagexclude = ["url", "host"]

  ## Parse the JSON response with the json_v2 parser
  data_format = "json_v2"

  [[inputs.http.json_v2]]
    [[inputs.http.json_v2.object]]
      ## Parse data in the `data.stations` path only
      path = "data.stations"

      ## Set station metadata as tags
      tags = ["station_id"]

      ## Latest station information reported at `last_reported`
      timestamp_key = "last_reported"

      ## Time is reported as a Unix timestamp
      timestamp_format = "unix"

[[outputs.influxdb_v3]]
  urls = ["http://localhost:8181"]
  token = "
AUTH_TOKEN
"
database = "
DATABASE_NAME
"

Replace the following:

  • AUTH_TOKEN: your InfluxDB authorization token
  • DATABASE_NAME: the database to write to

How it works

  • urls lists the endpoints to poll. The plugin requests each URL on every collection interval. For authenticated APIs, the http plugin supports header, basic-auth, token, and OAuth 2.0 options.
  • name_override replaces the default http measurement name with citibike.
  • tagexclude drops the url and host tags the plugin adds by default, which aren’t useful for this data.
  • The json_v2 object table selects the data.stations array. Each element of the array becomes one metric. The station_id key becomes a tag, last_reported becomes the metric timestamp, and every other key becomes a field. To build the path for your own API, test a GJSON path against a sample response. For parser details, see Parse JSON objects.

Test the configuration

Run a single collection and print the results without writing them:

telegraf --config citibike.conf --test

Example output

citibike,station_id=4703 eightd_has_available_keys=false,is_installed=1,is_renting=1,is_returning=1,legacy_id="4703",num_bikes_available=6,num_bikes_disabled=2,num_docks_available=26,num_docks_disabled=0,num_ebikes_available=0,station_status="active" 1641505084000000000
citibike,station_id=4704 eightd_has_available_keys=false,is_installed=1,is_renting=1,is_returning=1,legacy_id="4704",num_bikes_available=10,num_bikes_disabled=2,num_docks_available=36,num_docks_disabled=0,num_ebikes_available=0,station_status="active" 1641505084000000000
citibike,station_id=4711 eightd_has_available_keys=false,is_installed=1,is_renting=1,is_returning=1,legacy_id="4711",num_bikes_available=9,num_bikes_disabled=0,num_docks_available=36,num_docks_disabled=0,num_ebikes_available=1,station_status="active" 1641505084000000000

Extend this example

  • Poll multiple endpoints by adding URLs to urls, or add a second [[inputs.http]] instance with different parser settings.
  • If your API reports flat JSON, the simpler JSON input data format may be all you need. For deeply nested or array-heavy responses, see the XPath JSON input data format.

Was this page helpful?

Thank you for your feedback!