A custom Home Assistant integration that fetches JSON data from any API endpoint and exposes it as a sensor with configurable attributes.
- 🌐 Fetch JSON data from any REST API endpoint
- 🔐 Support for authentication (Bearer tokens, custom headers)
- 🎨 Transform JSON data with Jinja2 templates
- ⚙️ Configurable scan intervals
- 📊 Automatic handling of arrays and objects
- 🔄 Works with any JSON API (Readeck, custom APIs, etc.)
- Open HACS in your Home Assistant instance
- Click on "Integrations"
- Click the three dots in the top right corner and select "Custom repositories"
- Add this repository URL and select "Integration" as the category
- Click "Install"
- Restart Home Assistant
- Copy the
custom_components/json_api_sensorfolder to your Home Assistant'scustom_componentsdirectory - If the
custom_componentsdirectory doesn't exist, create it in your Home Assistant configuration directory - Restart Home Assistant
Your directory structure should look like this:
config/
└── custom_components/
└── json_api_sensor/
├── __init__.py
├── manifest.json
└── sensor.py
Add the sensor to your configuration.yaml file:
sensor:
- platform: json_api_sensor
name: "My API Sensor"
url: "https://api.example.com/data"
scan_interval: 300 # seconds (5 minutes)sensor:
- platform: json_api_sensor
name: "My API Sensor"
url: "https://api.example.com/data"
authorization: "Bearer YOUR_TOKEN_HERE"
scan_interval: 300sensor:
- platform: json_api_sensor
name: "My API Sensor"
url: "https://api.example.com/data"
headers:
Authorization: "Bearer YOUR_TOKEN_HERE"
Content-Type: "application/json"
X-Custom-Header: "value"
scan_interval: 300Transform the JSON response to extract only what you need:
sensor:
- platform: json_api_sensor
name: "Readeck Bookmarks"
url: "https://your-readeck-instance.com/api/bookmarks"
authorization: "Bearer YOUR_TOKEN"
scan_interval: 300
attributes_template: >
{% set ns = namespace(items=[]) %}
{% for item in value_json %}
{% set ns.items = ns.items + [{'url': item.url, 'title': item.title}] %}
{% endfor %}
{{ {'bookmarks': ns.items} | tojson }}| Option | Required | Default | Description |
|---|---|---|---|
platform |
Yes | - | Must be json_api_sensor |
name |
No | JSON API Sensor |
Friendly name for the sensor |
url |
Yes | - | The API endpoint URL |
authorization |
No | - | Authorization header value (e.g., Bearer token123) |
headers |
No | {} |
Dictionary of custom headers |
scan_interval |
No | 300 |
Update interval in seconds |
attributes_template |
No | - | Jinja2 template to transform the JSON response |
Fetch bookmarks from Readeck and display only URL and title:
sensor:
- platform: json_api_sensor
name: "Readeck Bookmarks"
url: "https://bookmarks.example.com/api/bookmarks"
authorization: "Bearer YOUR_READECK_TOKEN"
scan_interval: 300
attributes_template: >
{% set ns = namespace(items=[]) %}
{% for item in value_json %}
{% set ns.items = ns.items + [{'url': item.url, 'title': item.title}] %}
{% endfor %}
{{ {'bookmarks': ns.items} | tojson }}Access in templates:
{% set bookmarks = state_attr('sensor.readeck_bookmarks', 'bookmarks') %}
{% for item in bookmarks[:5] %}
[{{ item.title }}]({{ item.url }})
{% endfor %}sensor:
- platform: json_api_sensor
name: "Weather Data"
url: "https://api.weather.com/current"
headers:
API-Key: "YOUR_API_KEY"
scan_interval: 600sensor:
- platform: json_api_sensor
name: "Device Status"
url: "http://192.168.1.100/api/status"
scan_interval: 30
attributes_template: >
{{ {'temperature': value_json.temp, 'humidity': value_json.hum, 'online': value_json.status == 'ok'} | tojson }}The attributes_template option accepts Jinja2 templates with access to the value_json variable containing the API response.
Your template should output a valid JSON string using the tojson filter:
attributes_template: >
{{ {'key': 'value'} | tojson }}Extract specific fields from an array:
attributes_template: >
{% set ns = namespace(items=[]) %}
{% for item in value_json %}
{% set ns.items = ns.items + [{'id': item.id, 'name': item.name}] %}
{% endfor %}
{{ {'items': ns.items} | tojson }}Restructure nested data:
attributes_template: >
{{ {
'summary': value_json.data.summary,
'count': value_json.data.items | length,
'first_item': value_json.data.items[0].name
} | tojson }}When no attributes_template is provided:
- Array response: State = array length, attributes stored under
itemskey - Object response: State =
OK(orcount/totalif present), all keys stored as attributes - Other types: State = string representation, stored under
rawkey
Secrets can be used for your links and authorisation codes
Sensor
sensor:
- platform: json_api_sensor
name: "Readeck Bookmarks"
url: !secret readeck_url
authorization: !secret readeck_token
scan_interval: 300Secrets.yaml
readeck_url: "https://bookmarks.example.com/api/bookmarks"
readeck_token: "Bearer YOUR_TOKEN_HERE"- Check Home Assistant logs:
Settings→System→Logs - Verify the API URL is accessible
- Check authentication credentials
- Ensure the API returns valid JSON
- Verify your template outputs valid JSON
- Test templates in Home Assistant Developer Tools → Template
- Check logs for specific error messages
- Use
{{ value_json | tojson }}to see raw API response
- Increase
scan_intervalto reduce API calls - Check if your API has rate limits
- Monitor Home Assistant logs for HTTP errors
For issues, questions, or feature requests, please open an issue on GitHub.
This project is licensed under the MIT License.
Created for Home Assistant users who need a simple way to integrate any JSON API into their smart home.