While developing my TrueNAS Replication Monitoring Pipeline, I found that the easy to use REST API will be deprecated. This forces me to decide whether to keep using the REST API or redesign the system to adopt the new method. My old project will need a rework too MRi-LE/TrueNas-Replication-Monitor: TrueNas Replication Live Monitor / Dashboard ( vibe coded ) . So what has iX System planned for us ..
Offical Source: REST API Removal Notice
The legacy REST API has been deprecated in TrueNAS 25.04 and will be removed entirely in TrueNAS SCALE 26. The platform now requires integrations to use the versioned JSON-RPC 2.0 over WebSocket API instead. Anyone still relying on the old REST API must migrate to the WebSocket API before upgrading.
What changed:
- TrueNAS deprecated the REST API in 25.04
- TrueNAS 25.10.1 started warning you when deprecated REST endpoints were still being used
- TrueNAS 26 removes those REST endpoints entirely
- The supported replacement is the versioned JSON-RPC 2.0 over WebSocket API
What this means in practice
For most home lab and selfhosted setups, this affects things like:
- dashboard widgets / integrations
- custom monitoring scripts / cron jobs or shell scripts
- API wrappers you copied months ago and forgot about
- self-written tools using old API calls
- third-party apps that never added WebSocket support
Old infrastructure tends to survive quietly right up until the day it doesn’t.
If one of those tools still depends on the deprecated REST API, it might work fine today on older releases, show warnings on 25.10.1, and then simply stop working after upgrading to 26.
My recommendation before upgrading
- Make a list of anything external that talks to your TrueNAS
- Check which integrations are still using the deprecated REST API
- Look for updated versions, forks, or newer configs that support the WebSocket API
- Test everything in a non-production setup if possible
- Upgrade only after your critical integrations are confirmed working
This is especially important for setups where TrueNAS feeds dashboards or automations that are easy to forget until they suddenly go dark.
What the new API looks like
The replacement API uses JSON-RPC 2.0 over WebSocket, not the older request-per-endpoint REST style.
{
"jsonrpc": "2.0",
"id": 1,
"method": "system.info",
"params": []
}
And the response comes back in standard JSON-RPC format:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"version": "TrueNAS-26",
"uptime": "..."
}
}
The bigger takeaway is not the syntax itself – it’s that integrations now need to support a WebSocket session and JSON-RPC method call!
Here is a practical comparison using dataset operations:
Old REST style
# Create a dataset
curl -X POST "https://truenas.example/api/v2.0/pool/dataset" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "tank/mydataset"
}'
# Read a dataset
curl -X GET "https://truenas.example/api/v2.0/pool/dataset/id/tank%2Fmydataset" \
-H "Authorization: Bearer YOUR_API_KEY"
# Update a dataset
curl -X PUT "https://truenas.example/api/v2.0/pool/dataset/id/tank%2Fmydataset" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"comments": "Updated from API"
}'
# Delete a dataset
curl -X DELETE "https://truenas.example/api/v2.0/pool/dataset/id/tank%2Fmydataset" \
-H "Authorization: Bearer YOUR_API_KEY"
New WebSocket / JSON-RPC style
{ "jsonrpc": "2.0", "id": 1, "method": "pool.dataset.create", "params": [{ "name": "tank/mydataset" }] }
{ "jsonrpc": "2.0", "id": 2, "method": "pool.dataset.get_instance", "params": ["tank/mydataset"] }
{ "jsonrpc": "2.0", "id": 3, "method": "pool.dataset.update", "params": ["tank/mydataset", { "comments": "Updated from API" }] }
{ "jsonrpc": "2.0", "id": 4, "method": "pool.dataset.delete", "params": ["tank/mydataset"] }
Core Changes
- In the old REST model, the URL identified the resource.
- In the old REST model, the HTTP verb defined the action.
- In the old REST model, every operation was a separate HTTP request.
- In the new WebSocket model, the session stays open.
- In the new WebSocket model, the action is named explicitly in
method. - In the new WebSocket model, arguments are passed in
params. - In the new WebSocket model, the same connection can also receive event notifications.
That means the migration is not just changing a URL. It usually means changing how your integration connects, authenticates, sends requests, and handles responses.
Easy mental mapping
REST: VERB + /resource/path
WebSocket: method name + params[]
For example:
POST /pool/dataset -> pool.dataset.create
GET /pool/dataset/id/{id_} -> pool.dataset.get_instance
PUT /pool/dataset/id/{id_} -> pool.dataset.update
DELETE /pool/dataset/id/{id_} -> pool.dataset.delete
GET /system/info -> system.info