All docsStellar LinkRF bench · by Stellar Systems v0.1.0

API Reference

Profiles

Radio profile discovery and apply

GET/api/v1/profiles

List#

Responses

200List of all loaded profilesapplication/json

array of ProfileSummaryDRO

namerequired

string

display_name

string · nullable

modulationrequired

string

symbol_rate_baudrequired

number · double

center_frequency_hzrequired

integer · int64

≥ 0

Request

curl "http://192.168.2.1:8080/api/v1/profiles"

Response

[
  {
    "name": "string",
    "display_name": "string",
    "modulation": "string",
    "symbol_rate_baud": 0.0,
    "center_frequency_hz": 0
  }
]
GET/api/v1/profiles/active

Active#

Responses

200The active profile and whether it still describes the boardapplication/json
name

string · nullable

dirtyrequired

boolean

A manual change landed AFTER the profile was applied.

dirty_reason

string · nullable

What made it dirty — the route or register. "dirty" alone sends the reader looking through everything.

Request

curl "http://192.168.2.1:8080/api/v1/profiles/active"

Response

{
  "name": "string",
  "dirty": true,
  "dirty_reason": "string"
}
POST/api/v1/profiles/validate

Validate#

Request body application/jsonrequired

ProfileDRO

Responses

200OKapplication/json
okrequired

boolean

errorsrequired

array of string

Request

curl -X POST "http://192.168.2.1:8080/api/v1/profiles/validate" \
  -H "Content-Type: application/json" \
  -d '{}'

Response

{
  "ok": true,
  "errors": [
    "string"
  ]
}
GET/api/v1/profiles/{name}

Get one#

Path parameters

namerequired

string

Profile identifier

Responses

200OKapplication/json

ProfileDRO

404Profile not foundapplication/json

ApiErrorDRO

Request

curl "http://192.168.2.1:8080/api/v1/profiles/<name>"

Response

{}
PUT/api/v1/profiles/{name}

Register#

Push a profile the daemon does not have.

WHY THIS EXISTS. Until now a profile could only reach the board inside a firmware build: apply takes a NAME out of the set loaded from profiles_dir at startup. So trying a profile meant a release cycle, and an external client — a control centre, an example script — holding a perfectly good profile had no way to use it.

THE BODY IS PARSED AS YAML, WHICH ALSO ACCEPTS JSON, because YAML is a superset of it. One parse path, and a client may send whichever it has; profiles are written as YAML files, so a script that reads one off disk can forward the bytes unchanged instead of converting them.

IT IS TRANSIENT, AND THE REPLY SAYS SO. Nothing is written to profiles_dir — the rootfs is a ramdisk in any case. The client keeps the file and stays the source of truth; a copy quietly persisted on the board would be a second one, free to drift from the first.

Path parameters

namerequired

string

Name to register the profile under

Request body text/plainrequired

The profile, as YAML or JSON

string

Responses

200OKapplication/json
namerequired

string

replacedrequired

boolean

True when a profile of this name already existed and was replaced.

persistedrequired

boolean

Always false today, and present so a client never has to assume.

noterequired

string

Request

curl -X PUT "http://192.168.2.1:8080/api/v1/profiles/<name>" \
  -H "Content-Type: text/plain" \
  --data-binary @body.txt

Response

{
  "name": "string",
  "replaced": true,
  "persisted": true,
  "note": "string"
}
POST/api/v1/profiles/{name}/apply

Apply#

Path parameters

namerequired

string

Profile to apply

Responses

200OKapplication/json
profile_namerequired

string

cfg_epochrequired

integer · int32

≥ 0

tuningrequired

string

What the apply did to the RADIO, in one sentence — tuned, or why not.

Applying a profile used to leave the AD9361 exactly where it was while the reply said nothing about it (STE-994), so a UHF profile could be "applied" onto a part listening in S-band and every field in this struct stayed green. A tuning that did not happen has to be visible where the apply is.

404Profile not foundapplication/json

ApiErrorDRO

Request

curl -X POST "http://192.168.2.1:8080/api/v1/profiles/<name>/apply"

Response

{
  "profile_name": "string",
  "cfg_epoch": 0,
  "tuning": "string"
}
GET/api/v1/profiles/{name}/revisions

List revisions#

Path parameters

namerequired

string

Profile identifier

Responses

200Revision history sorted newest-firstapplication/json

array of ProfileRevisionDRO

versionrequired

integer · int32

≥ 0

cfg_epochrequired

integer · int32

≥ 0

applied_atrequired

string · date-time

applied_by

string · nullable

message

string · nullable

Request

curl "http://192.168.2.1:8080/api/v1/profiles/<name>/revisions"

Response

[
  {
    "version": 0,
    "cfg_epoch": 0,
    "applied_at": "2026-09-29T08:30:00Z",
    "applied_by": "string",
    "message": "string"
  }
]

↑↓ to moveEnter to open