API Reference
The RadioShaq API is a FastAPI application. All protected endpoints require a Bearer JWT from POST /auth/token (query params: subject, role, station_id).
Interactive docs: When the API is running, see http://localhost:8000/docs (Swagger UI) and http://localhost:8000/redoc.
Overview
| Area | Prefix | Purpose |
|---|---|---|
| Health | /health, /health/ready |
Liveness and readiness (DB, orchestrator) |
| Metrics | /metrics |
Prometheus scrape (uptime, callsigns, optional GPU). See Response & compliance. |
| Auth | /auth/token, /auth/refresh, /auth/me |
Issue token, refresh, current user |
| Messages | /messages/process, /messages/whitelist-request, /messages/from-audio, /messages/inject-and-store |
Orchestration and whitelist flow |
| Relay | /messages/relay |
Band translation (e.g. 40m → 2m). Stores source + relayed transcripts; optional inject/TX when config enables. Recipients poll GET /transcripts?callsign=<callsign>&destination_only=true&band=<band> to retrieve relayed messages. |
| Callsigns | /callsigns, /callsigns/register, /callsigns/register-from-audio, /callsigns/registered/{callsign} |
Registered callsigns and registration |
| Config | /api/v1/config/llm, /api/v1/config/memory, /api/v1/config/overrides |
LLM, memory (Hindsight), and per-role overrides (GET/PATCH; keys redacted). See Configuration. |
| Audio | /api/v1/config/audio, /api/v1/audio/devices, /api/v1/audio/pending, approve/reject |
Audio config and pending response queue |
| Transcripts | /transcripts, /transcripts/{id}, /transcripts/{id}/play |
Search and play transcripts |
| Radio | /radio/status, /radio/propagation, /radio/bands, /radio/send-tts |
Radio connected?, propagation, band list, send TTS |
| GIS | /gis/location, /gis/location/{callsign}, /gis/operators-nearby |
Store/retrieve operator location (lat/lon), find operators within radius. v1: explicit coordinates only; location_text alone returns 400. Source user_disclosed and timestamp in responses. |
| Inject | /inject/message |
Demo: push message into RX injection queue |
| Internal | /internal/bus/inbound |
MessageBus inbound (e.g. Lambda) |
GIS location (PostGIS)
- POST /gis/location — Store operator location. Body:
callsign(required),latitudeandlongitude(required for v1), optionalaccuracy_meters,altitude_meters. If onlylocation_textis sent, returns 400 witherror: "ambiguous_location". Response:id,callsign,latitude,longitude,source(e.g.user_disclosed),timestamp,confidence. Coordinates0.0, 0.0are valid. - GET /gis/location/{callsign} — Latest stored location for callsign (explicit lat/lon). 404 if none.
- GET /gis/operators-nearby — Query:
latitude,longitude,radius_meters(default 50000), optionalrecent_hours(default 24),max_results(default 100). Returns list of operators withdistance_meters.
Generated API reference from the FastAPI OpenAPI spec (run python radioshaq/scripts/export_openapi.py from repo root before building to produce docs/api/openapi.json):
RadioShaq API 0.1.0
Strategic Autonomous Ham Radio and Knowledge Operations Dispatch System
health
GET /health
Health
??? note "Description" Liveness probe.
Responses
GET /health/ready
Ready
??? note "Description" Readiness probe: DB (if configured), orchestrator, optional audio agent.
Responses
auth
POST /auth/token
Create Token
??? note "Description" Create an access token (e.g. for field station).
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
role |
query | string | field | No | |
station_id |
query | No | |||
subject |
query | string | No |
Responses
??? hint "Schema of the response body"
POST /auth/refresh
Refresh Token
??? note "Description" Exchange refresh token for new access token.
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
refresh_token |
query | string | No |
Responses
??? hint "Schema of the response body"
GET /auth/me
Me
??? note "Description" Return current token claims (requires Bearer token).
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
HTTPBearer |
header | string | N/A | No | JWT Bearer token |
Responses
radio
GET /radio/propagation
Propagation
??? note "Description" Get propagation prediction between two points.
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
HTTPBearer |
header | string | N/A | No | JWT Bearer token |
lat_dest |
query | number | No | Destination latitude | |
lat_origin |
query | number | No | Origin latitude | |
lon_dest |
query | number | No | Destination longitude | |
lon_origin |
query | number | No | Origin longitude |
Responses
??? hint "Schema of the response body"
GET /radio/bands
Bands
??? note "Description" List supported bands (from band plan).
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
HTTPBearer |
header | string | N/A | No | JWT Bearer token |
Responses
POST /radio/send-tts
Send Tts
??? note "Description" Send arbitrary text as TTS over the radio (audio out).
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
HTTPBearer |
header | string | N/A | No | JWT Bearer token |
Request body
??? hint "Schema of the request body"
{
"properties": {
"message": {
"type": "string",
"minLength": 1,
"title": "Message"
},
"frequency_hz": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"title": "Frequency Hz"
},
"mode": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Mode"
}
},
"type": "object",
"required": [
"message"
],
"title": "SendTTSBody",
"description": "Body for POST /radio/send-tts."
}
Responses
??? hint "Schema of the response body"
messages
POST /messages/process
Process Message
??? note "Description" Submit a message for REACT orchestration. Requires orchestrator to be set in app state (lifespan). Optional body fields: channel, chat_id, sender_id (InboundMessage shape for routing).
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
HTTPBearer |
header | string | N/A | No | JWT Bearer token |
Request body
Responses
??? hint "Schema of the response body"
POST /messages/whitelist-request
Whitelist Request
??? note "Description" Whitelist entry point: request access to gated services (e.g. messaging between bands). Text or audio → orchestrator evaluates → response as text and optionally TTS. Accepts application/json: { "text" or "message", "callsign?", "send_audio_back?" } or multipart/form-data: file (audio), callsign, send_audio_back.
Approved/message can come from either the orchestrator final message (tool path:
LLM used register_callsign tool and replied) or a completed whitelist agent task
(agent path: ACTING ran the whitelist agent; result in completed_tasks).
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
HTTPBearer |
header | string | N/A | No | JWT Bearer token |
Responses
POST /messages/from-audio
Message From Audio
??? note "Description" Upload audio; run ASR; whitelist check; store transcript. Optionally inject to RX queue.
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
HTTPBearer |
header | string | N/A | No | JWT Bearer token |
Request body
{
"file": "string",
"source_callsign": "string",
"destination_callsign": null,
"band": null,
"mode": "string",
"frequency_hz": 10.12,
"session_id": null,
"inject": true
}
??? hint "Schema of the request body"
{
"properties": {
"file": {
"type": "string",
"contentMediaType": "application/octet-stream",
"title": "File"
},
"source_callsign": {
"type": "string",
"title": "Source Callsign"
},
"destination_callsign": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Destination Callsign"
},
"band": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Band"
},
"mode": {
"type": "string",
"title": "Mode",
"default": "PSK31"
},
"frequency_hz": {
"type": "number",
"title": "Frequency Hz",
"default": 0.0
},
"session_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Session Id"
},
"inject": {
"type": "boolean",
"title": "Inject",
"default": false
}
},
"type": "object",
"required": [
"file",
"source_callsign"
],
"title": "Body_message_from_audio_messages_from_audio_post"
}
Responses
??? hint "Schema of the response body"
POST /messages/inject-and-store
Inject And Store
??? note "Description" Inject message into RX queue and store to DB (whitelist enforced).
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
HTTPBearer |
header | string | N/A | No | JWT Bearer token |
Request body
{
"text": "string",
"band": null,
"frequency_hz": 10.12,
"mode": "string",
"source_callsign": null,
"destination_callsign": null,
"audio_path": null,
"metadata": {}
}
??? hint "Schema of the request body"
{
"properties": {
"text": {
"type": "string",
"minLength": 1,
"title": "Text"
},
"band": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Band"
},
"frequency_hz": {
"type": "number",
"title": "Frequency Hz",
"default": 0.0
},
"mode": {
"type": "string",
"title": "Mode",
"default": "PSK31"
},
"source_callsign": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Source Callsign"
},
"destination_callsign": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Destination Callsign"
},
"audio_path": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Audio Path"
},
"metadata": {
"additionalProperties": true,
"type": "object",
"title": "Metadata"
}
},
"type": "object",
"required": [
"text"
],
"title": "InjectAndStoreBody",
"description": "Body for POST /messages/inject-and-store."
}
Responses
??? hint "Schema of the response body"
POST /messages/relay
Relay Message Between Bands
??? note "Description" Translate a message from one band to another and store both sides.
Scenario: User A emits on band A (e.g. 40m), message is received and stored;
then it is "relayed" to band B (e.g. 2m) for User B. Stores:
1. Original (or reference) transcript on source band
2. Relay transcript on target band with metadata linking to source
Body:
- message (str): Text to relay
- source_band (str): e.g. "40m"
- source_frequency_hz (float, optional): exact freq if known
- source_callsign (str): who sent on source band
- target_band (str): e.g. "2m"
- target_frequency_hz (float, optional): target freq; else use band default
- destination_callsign (str, optional): who receives on target band
- session_id (str, optional): default generated
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
HTTPBearer |
header | string | N/A | No | JWT Bearer token |
Request body
{
"message": "string",
"source_band": "string",
"target_band": "string",
"source_frequency_hz": null,
"target_frequency_hz": null,
"source_callsign": "string",
"destination_callsign": null,
"session_id": null,
"source_audio_path": null,
"target_audio_path": null
}
??? hint "Schema of the request body"
{
"properties": {
"message": {
"type": "string",
"minLength": 1,
"title": "Message"
},
"source_band": {
"type": "string",
"title": "Source Band"
},
"target_band": {
"type": "string",
"title": "Target Band"
},
"source_frequency_hz": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"title": "Source Frequency Hz"
},
"target_frequency_hz": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"title": "Target Frequency Hz"
},
"source_callsign": {
"type": "string",
"title": "Source Callsign",
"default": "UNKNOWN"
},
"destination_callsign": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Destination Callsign"
},
"session_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Session Id"
},
"source_audio_path": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Source Audio Path"
},
"target_audio_path": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Target Audio Path"
}
},
"type": "object",
"required": [
"message",
"source_band",
"target_band"
],
"title": "RelayBody",
"description": "Body for POST /messages/relay (band translation)."
}
Responses
??? hint "Schema of the response body"
transcripts
GET /transcripts
Search Transcripts
??? note "Description" Search transcripts (received/relayed messages). Use for demo so User 2 can poll for messages on a band or for their callsign (e.g. after relay from 40m to 2m). When whitelist is configured, only transcripts whose source/destination is in the whitelist are returned.
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
HTTPBearer |
header | string | N/A | No | JWT Bearer token |
band |
query | No | Filter by band name (e.g. 40m, 2m); uses extra_data.band | ||
callsign |
query | No | Filter by source or destination callsign | ||
frequency_max |
query | No | Maximum frequency (Hz) | ||
frequency_min |
query | No | Minimum frequency (Hz) | ||
limit |
query | integer | 100 | No | Max results |
mode |
query | No | Filter by mode (FM, PSK31, etc.) | ||
since |
query | No | Only transcripts after this time (ISO 8601) |
Responses
??? hint "Schema of the response body"
GET /transcripts/{transcript_id}
Get Transcript
??? note "Description" Get a single transcript by id (for play or display).
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
HTTPBearer |
header | string | N/A | No | JWT Bearer token |
transcript_id |
path | integer | No |
Responses
??? hint "Schema of the response body"
POST /transcripts/{transcript_id}/play
Play Transcript Over Radio
??? note "Description" Load transcript, generate TTS, and send over radio (audio out).
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
HTTPBearer |
header | string | N/A | No | JWT Bearer token |
transcript_id |
path | integer | No |
Responses
??? hint "Schema of the response body"
callsigns
GET /callsigns
List Registered
??? note "Description" List all registered callsigns (whitelist).
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
HTTPBearer |
header | string | N/A | No | JWT Bearer token |
Responses
POST /callsigns/register
Register Callsign
??? note "Description" Register a callsign so it is automatically accepted for store/relay.
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
HTTPBearer |
header | string | N/A | No | JWT Bearer token |
Request body
??? hint "Schema of the request body"
{
"properties": {
"callsign": {
"type": "string",
"maxLength": 10,
"minLength": 3,
"title": "Callsign"
},
"source": {
"type": "string",
"title": "Source",
"description": "api or audio",
"default": "api"
}
},
"type": "object",
"required": [
"callsign"
],
"title": "RegisterBody",
"description": "Body for POST /callsigns/register."
}
Responses
??? hint "Schema of the response body"
POST /callsigns/register-from-audio
Register From Audio
??? note "Description" Upload audio; run ASR and register the extracted or confirmed callsign.
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
HTTPBearer |
header | string | N/A | No | JWT Bearer token |
callsign |
query | No |
Request body
??? hint "Schema of the request body"
Responses
??? hint "Schema of the response body"
DELETE /callsigns/registered/{callsign}
Unregister Callsign
??? note "Description" Remove a callsign from the registry.
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
HTTPBearer |
header | string | N/A | No | JWT Bearer token |
callsign |
path | string | No |
Responses
??? hint "Schema of the response body"
inject
POST /inject/message
Inject Message
??? note "Description" Inject a message into the RX path for demo/testing.
The message will be available to receivers (radio_rx / digital_modes)
when they poll the injection queue. Use for:
- User injection script (e.g. audio → text → this endpoint)
- Simulating one user emitting on a band for another to receive
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
HTTPBearer |
header | string | N/A | No | JWT Bearer token |
Request body
{
"text": "string",
"band": null,
"frequency_hz": 10.12,
"mode": "string",
"source_callsign": null,
"destination_callsign": null,
"audio_path": null,
"metadata": {}
}
??? hint "Schema of the request body"
{
"properties": {
"text": {
"type": "string",
"minLength": 1,
"title": "Text",
"description": "Message text to inject as received"
},
"band": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Band",
"description": "Band name (e.g. 40m, 2m)"
},
"frequency_hz": {
"type": "number",
"title": "Frequency Hz",
"description": "Frequency in Hz",
"default": 0.0
},
"mode": {
"type": "string",
"title": "Mode",
"description": "Mode (PSK31, FT8, FM, etc.)",
"default": "PSK31"
},
"source_callsign": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Source Callsign",
"description": "Source callsign"
},
"destination_callsign": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Destination Callsign",
"description": "Destination callsign"
},
"audio_path": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Audio Path",
"description": "Optional path to audio file (stored with transcript)"
},
"metadata": {
"additionalProperties": true,
"type": "object",
"title": "Metadata"
}
},
"type": "object",
"required": [
"text"
],
"title": "InjectMessageBody",
"description": "Body for POST /inject/message (user injection for demo)."
}
Responses
??? hint "Schema of the response body"
internal
POST /internal/bus/inbound
Publish Inbound
??? note "Description" Accept an inbound message (e.g. from Lambda) and publish to MessageBus. Body: channel, sender_id, chat_id, content; optional media, metadata, session_key_override. Orchestrator consumer must be running elsewhere to process (e.g. run_inbound_consumer).
Request body
Responses
??? hint "Schema of the response body"
audio
GET /api/v1/config/audio
Get Audio Config
??? note "Description" Get current audio configuration (env/file + optional runtime overrides).
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
HTTPBearer |
header | string | N/A | No | JWT Bearer token |
Responses
PATCH /api/v1/config/audio
Update Audio Config
??? note "Description" Update audio configuration (runtime overlay only; does not persist to file).
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
HTTPBearer |
header | string | N/A | No | JWT Bearer token |
Request body
Responses
??? hint "Schema of the response body"
POST /api/v1/config/audio/reset
Reset Audio Config
??? note "Description" Clear runtime audio config overrides.
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
HTTPBearer |
header | string | N/A | No | JWT Bearer token |
Responses
GET /api/v1/audio/devices
List Audio Devices
??? note "Description" List available audio input/output devices (requires voice_rx).
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
HTTPBearer |
header | string | N/A | No | JWT Bearer token |
Responses
POST /api/v1/audio/devices/{device_id}/test
Test Audio Device
??? note "Description" Test an audio device by ID (placeholder).
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
HTTPBearer |
header | string | N/A | No | JWT Bearer token |
device_id |
path | integer | No |
Responses
??? hint "Schema of the response body"
GET /api/v1/audio/pending
List Pending Responses
??? note "Description" List pending responses awaiting human confirmation.
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
HTTPBearer |
header | string | N/A | No | JWT Bearer token |
Responses
POST /api/v1/audio/pending/{pending_id}/approve
Approve Pending Response
??? note "Description" Approve a pending response (send it over the radio).
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
HTTPBearer |
header | string | N/A | No | JWT Bearer token |
pending_id |
path | string | No |
Request body
Responses
??? hint "Schema of the response body"
POST /api/v1/audio/pending/{pending_id}/reject
Reject Pending Response
??? note "Description" Reject a pending response.
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
HTTPBearer |
header | string | N/A | No | JWT Bearer token |
pending_id |
path | string | No |
Request body
Responses
??? hint "Schema of the response body"
Schemas
Body_message_from_audio_messages_from_audio_post
| Name | Type | Description |
|---|---|---|
band |
||
destination_callsign |
||
file |
string | |
frequency_hz |
number | |
inject |
boolean | |
mode |
string | |
session_id |
||
source_callsign |
string |
Body_register_from_audio_callsigns_register_from_audio_post
| Name | Type | Description |
|---|---|---|
file |
string |
HTTPValidationError
| Name | Type | Description |
|---|---|---|
detail |
Array<ValidationError> |
InjectAndStoreBody
| Name | Type | Description |
|---|---|---|
audio_path |
||
band |
||
destination_callsign |
||
frequency_hz |
number | |
metadata |
||
mode |
string | |
source_callsign |
||
text |
string |
InjectMessageBody
| Name | Type | Description |
|---|---|---|
audio_path |
Optional path to audio file (stored with transcript) | |
band |
Band name (e.g. 40m, 2m) | |
destination_callsign |
Destination callsign | |
frequency_hz |
number | Frequency in Hz |
metadata |
||
mode |
string | Mode (PSK31, FT8, FM, etc.) |
source_callsign |
Source callsign | |
text |
string | Message text to inject as received |
RegisterBody
| Name | Type | Description |
|---|---|---|
callsign |
string | |
source |
string | api or audio |
RelayBody
| Name | Type | Description |
|---|---|---|
destination_callsign |
||
message |
string | |
session_id |
||
source_audio_path |
||
source_band |
string | |
source_callsign |
string | |
source_frequency_hz |
||
target_audio_path |
||
target_band |
string | |
target_frequency_hz |
SendTTSBody
| Name | Type | Description |
|---|---|---|
frequency_hz |
||
message |
string | |
mode |
ValidationError
| Name | Type | Description |
|---|---|---|
ctx |
||
input |
||
loc |
Array<> | |
msg |
string | |
type |
string |
Security schemes
| Name | Type | Scheme | Description |
|---|---|---|---|
| HTTPBearer | http | bearer |