API endpoints

So the Websocket API endpoint on SCALE through 24.10 is ws://host/websocket (or wss://). In 25.04, it changes to /api/current, but /websocket still works (at least as of RC1). How long will /websocket continue to work?

The context is, naturally, that I have a script that uses the API, and I’d like it to work across as many releases of SCALE as possible. I could make the user specify the API endpoint via a config file, but that seems kind of user-hostile. Is there a way I can determine which API endpoint to use programmatically? Better yet, to do it when the script is running on a different system from the NAS?

I think probably the simplest solution for API consumers is the following: for 25.04.0 we’re adding a api/versions path so you can do something like this:

>>> requests.get('http://127.0.0.1/api/versions').json()
['v24.10', 'v25.04.0', 'v25.04.1', 'v25.10.0']

This will allow versioning scripts based on which API version is available. If you get a 404 on that path then /websocket (you know you’re dealing with an older TrueNAS version).

For example:

>>> import requests
>>> resp = requests.get('http://127.0.0.1/api/versions')
>>> resp.status_code
404

This is my 10-second hint about how one can do this rather than formal documentation.

1 Like

If I try to curl that URL on 25.04-RC1, I get 404. Is that yet to be added?

It will be in Fangtooth nightlies in a day or so, and will be present for 25.04.0 release.

1 Like

Well, good news: the /api/versions path does now give a response in the 4/6 nightly. And requests to that path on 25.04-RC1 without the HTTP → HTTPS redirect enabled give 404. Bad news: any version with that redirect enabled responds with a 302 redirect to /ui, which in turn gives 200–so just testing for a 200 status code clearly isn’t going to do the trick.

I guess the fallback course of action is to test whether the result can be parsed, and if so, the system’s running 25.04+. If not, it’s an earlier version.

edit: with assistance from ChatGPT, this seems to do the trick, with or without a http->https redirect, on 25.04-Nightly and other versions:

# Determine API path
valid_versions = []
invalid_response = False

try:
    response = requests.get(f"http://{CONNECT_HOST}/api/versions", timeout=10)
    response.raise_for_status()

    data = response.json()
    if isinstance(data, list) and all(isinstance(v, str) and v.startswith("v") for v in data):
        valid_versions = data
        logger.debug(f"✅ Valid versions received: {valid_versions}")
    else:
        invalid_response = True
        logger.debug(f"⚠️ Unexpected response structure: {data}")

except Exception as e:
    invalid_response = True
    logger.debug(f"❌ Failed to retrieve or parse the response: {e}")

if invalid_response==True:
    API_PATH="/websocket"
    logger.debug(f"API path is {API_PATH}")
else:
    API_PATH="/api/current"
    logger.debug(f"API path is {API_PATH}")