Spothole is a utility to aggregate "spots" from amateur radio DX clusters and xOTA spotting sites, and provide an open JSON API as well as a website to browse the data.
While there are other web-based interfaces to DX clusters, and sites that aggregate spots from various outdoor activity programmes for amateur radio, Spothole differentiates itself by supporting a large number of data sources, and by being "API first" rather than just providing a web front-end. This allows other software to be built on top of it. Spothole itself is also open source, Public Domain licenced code that anyone can take and modify.
The API calls described below allow third-party software to access data from Spothole, and receive data on spots and alerts in a consistent format regardless of the data sources used by Spothole itself. Utility calls are also provided for general data lookups.
Please note that the data coming out of Spothole is only as good as the data going in. People mis-hear and make typos when spotting callsigns all the time, and there are plenty of areas where Spothole's location data may be inaccurate. If you are doing something where accuracy is important, such as contesting, you should not rely on Spothole's data to fill in any gaps in your log.
Spothole's source code is located at https://git.ianrenton.com/ian/spothole and the README there provides setup instructions if you would like to run your own copy. A demonstration server of Spothole is located at https://spothole.app.
## Changelog
### 2.0
@@ -24,7 +24,7 @@ info:
* **Breaking change:** A user's QRZ.com and HamQTH credentials are now supplied as request headers (`X-QRZ-Username`, `X-QRZ-Password`, `X-QRZ-Session-Key`, `X-HamQTH-Username`, `X-HamQTH-Password`, `X-HamQTH-Session-ID`) rather than query parameters, to keep credentials out of server logs.
### 1.3
* `/solar` response now includes `ionosonde_data`, which contains ionosonde station measurements (LUF, foF2 and MUF) sourced from the GIRO Data Center as well as implied band states.
* `/spots`, `/spots/stream`, `/alerts`, `/alerts/stream`, and `/lookup/call` now accept optional QRZ.com and HamQTH credentials as query parameters. When supplied, returned data is enriched with operator name, home location etc. from those services.
@@ -67,7 +67,11 @@ paths:
tags:
- Spots
summary:Get spots
description:The main API call that retrieves spots from the system. Supply this with no query parameters to retrieve all spots known to the system. Supply query parameters to filter what is retrieved. If QRZ.com or HamQTH credentials are supplied, returned spots will be enriched with operator name, home location etc. from those services.
description:>
The main API call that retrieves spots from the system. Supply this with no query parameters to
retrieve all spots known to the system. Supply query parameters to filter what is retrieved. If
QRZ.com or HamQTH credentials are supplied, returned spots will be enriched with operator name,
home location etc. from those services.
operationId:spots
parameters:
- $ref:'#/components/parameters/SpotLimit'
@@ -108,7 +112,11 @@ paths:
tags:
- Spots
summary:Get spot stream
description:Request a Server-Sent Event stream which will return individual spots immediately when they are added to the system. Only spots that match the provided filters will be returned. If QRZ.com or HamQTH credentials are supplied, streamed spots will be enriched with operator name, home location etc. from those services.
description:>
Request a Server-Sent Event stream which will return individual spots immediately when they are
added to the system. Only spots that match the provided filters will be returned. If QRZ.com or
HamQTH credentials are supplied, streamed spots will be enriched with operator name, home
location etc. from those services.
operationId:spots-stream
parameters:
- $ref:'#/components/parameters/SpotSource'
@@ -145,7 +153,11 @@ paths:
tags:
- Alerts
summary:Get alerts
description:Retrieves alerts (indications of upcoming activations) from the system. Supply this with no query parameters to retrieve all alerts known to the system. Supply query parameters to filter what is retrieved. If QRZ.com or HamQTH credentials are supplied, returned alerts will be enriched with operator names from those services.
description:>
Retrieves alerts (indications of upcoming activations) from the system. Supply this with no
query parameters to retrieve all alerts known to the system. Supply query parameters to filter
what is retrieved. If QRZ.com or HamQTH credentials are supplied, returned alerts will be
enriched with operator names from those services.
operationId:alerts
parameters:
- $ref:'#/components/parameters/AlertLimit'
@@ -177,7 +189,11 @@ paths:
tags:
- Alerts
summary:Get alert stream
description:Request a Server-Sent Event stream which will return individual alerts immediately when they are added to the system. Only alerts that match the provided filters will be returned. If QRZ.com or HamQTH credentials are supplied, streamed alerts will be enriched with operator names from those services.
description:>
Request a Server-Sent Event stream which will return individual alerts immediately when they are
added to the system. Only alerts that match the provided filters will be returned. If QRZ.com or
HamQTH credentials are supplied, streamed alerts will be enriched with operator names from those
services.
operationId:alerts-stream
parameters:
- $ref:'#/components/parameters/AlertMaxDuration'
@@ -207,7 +223,10 @@ paths:
tags:
- Propagation & DX
summary:Get solar and band conditions
description:Returns the current solar conditions and HF/VHF propagation condition summaries. This data is sourced from external providers (e.g. HamQSL) and updated periodically. All fields may be null if no provider has successfully fetched data yet.
description:>
Returns the current solar conditions and HF/VHF propagation condition summaries. This data is
sourced from external providers (e.g. HamQSL) and updated periodically. All fields may be null
if no provider has successfully fetched data yet.
operationId:solar
responses:
'200':
@@ -223,7 +242,10 @@ paths:
tags:
- Propagation & DX
summary:Get spot counts by continent and band
description:Returns a three-level nested object of spot counts from the current spot database, grouped by DE continent, then DX continent, then band. Only spots in the last hour are counted, regardless of what the server owner has set the spot expiry time to.
description:>
Returns a three-level nested object of spot counts from the current spot database, grouped by DE
continent, then DX continent, then band. Only spots in the last hour are counted, regardless of
what the server owner has set the spot expiry time to.
operationId:dxstats
responses:
'200':
@@ -259,7 +281,14 @@ paths:
tags:
- General
summary:Get enumeration options
description:Retrieves the list of options for various enumerated types, which can be found in the spots and also provided back to the API as query parameters. While these enumerated options are defined in this spec anyway, providing them in an API call allows us to define extra parameters, like the colours associated with bands, and also allows clients to set up their filters and features without having to have internal knowledge about, for example, what bands the server knows about. The call also returns a variety of other parameters that may be of use to a web UI or other client.
description:>
Retrieves the list of options for various enumerated types, which can be found in the spots and
also provided back to the API as query parameters. While these enumerated options are defined in
this spec anyway, providing them in an API call allows us to define extra parameters, like the
colours associated with bands, and also allows clients to set up their filters and features
without having to have internal knowledge about, for example, what bands the server knows about.
The call also returns a variety of other parameters that may be of use to a web UI or other
client.
operationId:options
responses:
'200':
@@ -274,7 +303,10 @@ paths:
tags:
- Utilities
summary:Look up callsign details
description:Perform a lookup of data about a certain callsign, using any of the lookup services available to the Spothole server. If QRZ.com or HamQTH credentials are supplied, the response will be able to use these services to perform a lookup.
description:>
Perform a lookup of data about a certain callsign, using any of the lookup services available to
the Spothole server. If QRZ.com or HamQTH credentials are supplied, the response will be able to
use these services to perform a lookup.
operationId:call
parameters:
- $ref:'#/components/parameters/CallParam'
@@ -305,7 +337,10 @@ paths:
tags:
- Utilities
summary:Look up SIG ref details
description:Perform a lookup of data about a certain reference, providing the SIG and the ID of the reference. A SIGRef structure will be returned containing the SIG and ID, plus any other information Spothole could find about it.
description:>
Perform a lookup of data about a certain reference, providing the SIG and the ID of the
reference. A SIGRef structure will be returned containing the SIG and ID, plus any other
information Spothole could find about it.
operationId:sigref
parameters:
- $ref:'#/components/parameters/SigRefSig'
@@ -358,7 +393,11 @@ paths:
tags:
- Spots
summary:Add a spot
description:"Supply a spot submission object containing a `spot` sub-object (the spot data) and an optional `handling` sub-object (server-side instructions such as upstream submission). Check `spot_submit_providers` in the `/options` response to see which SIGs and providers support upstream submission. cURL example: `curl --request POST --header \"Content-Type: application/json\" --data '{\"spot\":{\"dx_call\":\"M0TRT\",\"time\":1760019539,\"freq\":14200000,\"comment\":\"Test spot please ignore\",\"de_call\":\"M0TRT\"}}' https://spothole.app/api/v2/spot`"
description:>
Supply a JSON object containing a `spot` sub-object (the spot data) and an optional `handling` sub-object
containing server-side instructions such as upstream submission). Check `spot_submit_providers` in the
`/options` response to see which SIGs and providers support upstream submission. cURL example:
description:Object containing a "spot" sub-object with the spot data, and an optional "handling" sub-object with server-side instructions of what to do with it.
@@ -402,117 +441,162 @@ components:
QrzUsername:
name:X-QRZ-Username
in:header
description:"QRZ.com username for online callsign lookup, which will enrich the returned spots and alerts with extra data. Requires a QRZ.com XML Subscriber (paid) account. Supply together with `X-QRZ-Password`, or supply `X-QRZ-Session-Key` instead."
description:>
QRZ.com username for online callsign lookup, which will enrich the returned spots and alerts
with extra data. Requires a QRZ.com XML Subscriber (paid) account. Supply together with
`qrz_password`, or supply `qrz_session_key` instead.
schema:
type:string
QrzPassword:
name:X-QRZ-Password
in:header
description:"QRZ.com password. Supply together with `X-QRZ-Username`."
description:QRZ.com password. Supply together with `qrz_username`.
schema:
type:string
QrzSessionKey:
name:X-QRZ-Session-Key
in:header
description:"A pre-obtained QRZ.com XML session key, as an alternative to supplying `X-QRZ-Username` and `X-QRZ-Password`. See https://www.qrz.com/docs/xml/current_spec.html for details on how to obtain one for the user."
description:>
A pre-obtained QRZ.com XML session key, as an alternative to supplying `qrz_username` and
`qrz_password`. See https://www.qrz.com/docs/xml/current_spec.html for details on how to
obtain one for the user.
schema:
type:string
HamqthUsername:
name:X-HamQTH-Username
in:header
description:"HamQTH username for online callsign lookup, which will enrich the returned spots and alerts with extra data. Supply together with `X-HamQTH-Password`, or supply `X-HamQTH-Session-ID` instead."
description:>
HamQTH username for online callsign lookup, which will enrich the returned spots and alerts
with extra data. Supply together with `hamqth_password`, or supply `hamqth_session_id` instead.
schema:
type:string
HamqthPassword:
name:X-HamQTH-Password
in:header
description:"HamQTH password. Supply together with `X-HamQTH-Username`."
description:HamQTH password. Supply together with `hamqth_username`.
schema:
type:string
HamqthSessionId:
name:X-HamQTH-Session-ID
in:header
description:"A pre-obtained HamQTH session ID, as an alternative to supplying `X-HamQTH-Username` and `X-HamQTH-Password`. See https://www.hamqth.com/developers.php for details on how to retrieve one for a user."
description:>
A pre-obtained HamQTH session ID, as an alternative to supplying `hamqth_username` and
`hamqth_password`. See https://www.hamqth.com/developers.php for details on how to retrieve
one for a user.
schema:
type:string
SpotSource:
name:source
in:query
description:"Limit the spots to only ones from one or more sources. To select more than one source, supply a comma-separated list."
description:>
Limit the spots to only ones from one or more sources. To select more than one source, supply a
comma-separated list.
schema:
$ref:"#/components/schemas/Source"
SpotSig:
name:sig
in:query
description:"Limit the spots to only ones from one or more Special Interest Groups provided as an argument. To select more than one SIG, supply a comma-separated list. The special `sig` name `NO_SIG` matches spots with no sig set. You can use `sig=NO_SIG` to specifically only return generic spots with no associated SIG. You can also use combinations to request for example POTA + no SIG, but reject other SIGs. If you want to request 'every SIG and not No SIG', see the `needs_sig` query parameter for a shortcut."
description:>
Limit the spots to only ones from one or more Special Interest Groups provided as an argument.
To select more than one SIG, supply a comma-separated list. The special `sig` name `NO_SIG`
matches spots with no sig set. You can use `sig=NO_SIG` to specifically only return generic
spots with no associated SIG. You can also use combinations to request for example POTA + no
SIG, but reject other SIGs. If you want to request 'every SIG and not No SIG', see the
`needs_sig` query parameter for a shortcut.
schema:
$ref:"#/components/schemas/SIGNameIncludingNoSIG"
SpotNeedsSig:
name:needs_sig
in:query
description:"Limit the spots to only ones with a Special Interest Group such as POTA. Because supplying all known SIGs as a `sigs` parameter is unwieldy, and leaving `sigs` blank will also return spots with *no* SIG, this parameter can be set true to return only spots with a SIG, regardless of what it is, so long as it's not blank. This is the equivalent of supplying the `sig` query param with a list of every known SIG apart from the special `NO_SIG` value. This is what Field Spotter uses to exclude generic cluster spots and only retrieve xOTA things."
description:>
Limit the spots to only ones with a Special Interest Group such as POTA. Because supplying all
known SIGs as a `sigs` parameter is unwieldy, and leaving `sigs` blank will also return spots
with *no* SIG, this parameter can be set true to return only spots with a SIG, regardless of
what it is, so long as it's not blank. This is the equivalent of supplying the `sig` query
param with a list of every known SIG apart from the special `NO_SIG` value. This is what Field
Spotter uses to exclude generic cluster spots and only retrieve xOTA things.
schema:
type:boolean
default:false
SpotNeedsSigRef:
name:needs_sig_ref
in:query
description:"Limit the spots to only ones which have at least one reference (e.g. a park reference) for Special Interest Groups such as POTA."
description:>
Limit the spots to only ones which have at least one reference (e.g. a park reference) for
Special Interest Groups such as POTA.
schema:
type:boolean
default:false
SpotBand:
name:band
in:query
description:"Limit the spots to only ones from one or more bands. To select more than one band, supply a comma-separated list."
description:>
Limit the spots to only ones from one or more bands. To select more than one band, supply a
comma-separated list.
schema:
$ref:"#/components/schemas/BandName"
SpotMode:
name:mode
in:query
description:"Limit the spots to only ones from one or more modes. To select more than one mode, supply a comma-separated list."
description:>
Limit the spots to only ones from one or more modes. To select more than one mode, supply a
comma-separated list.
schema:
$ref:"#/components/schemas/Mode"
SpotModeType:
name:mode_type
in:query
description:"Limit the spots to only ones from one or more mode families. To select more than one mode family, supply a comma-separated list."
description:>
Limit the spots to only ones from one or more mode families. To select more than one mode
family, supply a comma-separated list.
schema:
$ref:"#/components/schemas/ModeType"
SpotDxContinent:
name:dx_continent
in:query
description:"Limit the spots to only ones where the DX (the operator being spotted) is on the given continent(s). To select more than one continent, supply a comma-separated list."
description:>
Limit the spots to only ones where the DX (the operator being spotted) is on the given
continent(s). To select more than one continent, supply a comma-separated list.
schema:
$ref:"#/components/schemas/Continent"
SpotDeContinent:
name:de_continent
in:query
description:"Limit the spots to only ones where the spotter is on the given continent(s). To select more than one continent, supply a comma-separated list."
description:>
Limit the spots to only ones where the spotter is on the given continent(s). To select more
than one continent, supply a comma-separated list.
schema:
$ref:"#/components/schemas/Continent"
SpotDxCallIncludes:
name:dx_call_includes
in:query
description:"Limit the spots to only ones where the DX callsign includes the supplied string (case-insensitive). Generally a complete callsign, but you can supply a shorter string for partial matches."
description:>
Limit the spots to only ones where the DX callsign includes the supplied string
(case-insensitive). Generally a complete callsign, but you can supply a shorter string for
partial matches.
schema:
type:string
SpotCommentIncludes:
name:comment_includes
in:query
description:"Return only spots where the comment includes the provided string (case-insensitive)."
description:Return only spots where the comment includes the provided string (case-insensitive).
schema:
type:string
SpotTextIncludes:
name:text_includes
in:query
description:"Limit the spots to only ones where some significant text (DX callsign or comment) includes the supplied string (case-insensitive)."
description:>
Limit the spots to only ones where some significant text (DX callsign or comment) includes the
supplied string (case-insensitive).
schema:
type:string
SpotNeedsGoodLocation:
name:needs_good_location
in:query
description:"Return only spots with a 'good' location. (See the spot `dx_location_good` parameter for details. Useful for map-based clients, to avoid spots with 'bad' locations e.g. loads of cluster spots ending up in the centre of the DXCC entitity.)"
description:>
Return only spots with a 'good' location. (See the spot `dx_location_good` parameter for
details. Useful for map-based clients, to avoid spots with 'bad' locations e.g. loads of
cluster spots ending up in the centre of the DXCC entitity.)
schema:
type:boolean
default:false
@@ -526,43 +610,65 @@ components:
AlertMaxDuration:
name:max_duration
in:query
description:Limit the alerts to only ones with a duration of this many seconds or less. Duration is end time minus start time, if end time is set, otherwise the activation is assumed to be short and therefore to always pass this check. This is useful to filter out people who alert POTA activations lasting months or even years, but note it will also include multi-day or multi-week DXpeditions that you might otherwise be interested in. See the dxpeditions_skip_max_duration_check parameter for the workaround.
description:>
Limit the alerts to only ones with a duration of this many seconds or less. Duration is end
time minus start time, if end time is set, otherwise the activation is assumed to be short and
therefore to always pass this check. This is useful to filter out people who alert POTA
activations lasting months or even years, but note it will also include multi-day or multi-week
DXpeditions that you might otherwise be interested in. See the
dxpeditions_skip_max_duration_check parameter for the workaround.
schema:
type:integer
AlertDxpeditionsSkipMaxDurationCheck:
name:dxpeditions_skip_max_duration_check
in:query
description:Return DXpedition alerts even if they last longer than max_duration. This allows the user to filter out multi-day/multi-week POTA alerts where the operator likely won't be on the air most of the time, but keep multi-day/multi-week DXpeditions where the operator(s) likely *will* be on the air most of the time.
description:>
Return DXpedition alerts even if they last longer than max_duration. This allows the user to
filter out multi-day/multi-week POTA alerts where the operator likely won't be on the air most
of the time, but keep multi-day/multi-week DXpeditions where the operator(s) likely *will* be
on the air most of the time.
schema:
type:boolean
AlertSource:
name:source
in:query
description:"Limit the alerts to only ones from one or more sources. To select more than one source, supply a comma-separated list."
description:>
Limit the alerts to only ones from one or more sources. To select more than one source, supply a
comma-separated list.
schema:
$ref:"#/components/schemas/Source"
AlertSig:
name:sig
in:query
description:"Limit the alerts to only ones from one or more Special Interest Groups. To select more than one SIG, supply a comma-separated list. The special value 'NO_SIG' can be included to return alerts specifically without an associated SIG (i.e. general DXpeditions)."
description:>
Limit the alerts to only ones from one or more Special Interest Groups. To select more than one
SIG, supply a comma-separated list. The special value 'NO_SIG' can be included to return alerts
specifically without an associated SIG (i.e. general DXpeditions).
schema:
$ref:"#/components/schemas/SIGNameIncludingNoSIG"
AlertDxContinent:
name:dx_continent
in:query
description:"Limit the alerts to only ones where the DX operator is on the given continent(s). To select more than one continent, supply a comma-separated list."
description:>
Limit the alerts to only ones where the DX operator is on the given continent(s). To select
more than one continent, supply a comma-separated list.
schema:
$ref:"#/components/schemas/Continent"
AlertDxCallIncludes:
name:dx_call_includes
in:query
description:"Limit the alerts to only ones where the DX callsign includes the supplied string (case-insensitive). Generally a complete callsign, but you can supply a shorter string for partial matches."
description:>
Limit the alerts to only ones where the DX callsign includes the supplied string
(case-insensitive). Generally a complete callsign, but you can supply a shorter string for
partial matches.
schema:
type:string
AlertTextIncludes:
name:text_includes
in:query
description:"Limit the alerts to only ones where some significant text (DX callsign, freqs/modes, or comment) includes the supplied string (case-insensitive)."
description:>
Limit the alerts to only ones where some significant text (DX callsign, freqs/modes, or
comment) includes the supplied string (case-insensitive).
schema:
type:string
SpotLimit:
@@ -574,25 +680,40 @@ components:
SpotSince:
name:since
in:query
description:Limit the spots to only ones at this time or later. Time in UTC seconds since UNIX epoch. Equivalent to "max_age" but saves the client having to work out how many seconds ago "midnight" was.
description:>
Limit the spots to only ones at this time or later. Time in UTC seconds since UNIX epoch.
Equivalent to "max_age" but saves the client having to work out how many seconds ago
"midnight" was.
schema:
type:number
SpotMaxAge:
name:max_age
in:query
description:Limit the spots to only ones received in the last 'n' seconds. Equivalent to "since" but saves the client having to work out what time was 'n' seconds ago on every call. Refer to the "max_spot_age" in the /options call to figure out what the maximum useful value you can provide is. Larger values will still be accepted, there just won't be any spots in the system older than max_spot_age.
description:>
Limit the spots to only ones received in the last 'n' seconds. Equivalent to "since" but saves
the client having to work out what time was 'n' seconds ago on every call. Refer to the
"max_spot_age" in the /options call to figure out what the maximum useful value you can provide
is. Larger values will still be accepted, there just won't be any spots in the system older
than max_spot_age.
schema:
type:number
SpotReceivedSince:
name:received_since
in:query
description:Limit the spots to only ones that the system found out about at this time or later. Time in UTC seconds since UNIX epoch. If you are using a front-end that tracks the last time it queried the API and requests spots since then, you want *this* version of the query parameter, not "since", because otherwise it may miss things. The logic is "greater than" rather than "greater than or equal to", so you can submit the time of the last received item back to this call and you will get all the more recent spots back, without duplicating the previous latest spot.
description:>
Limit the spots to only ones that the system found out about at this time or later. Time in UTC
seconds since UNIX epoch. If you are using a front-end that tracks the last time it queried the
API and requests spots since then, you want *this* version of the query parameter, not "since",
because otherwise it may miss things. The logic is "greater than" rather than "greater than or
equal to", so you can submit the time of the last received item back to this call and you will
get all the more recent spots back, without duplicating the previous latest spot.
schema:
type:number
SpotDedupe:
name:dedupe
in:query
description:"\"De-duplicate\" the spots, returning only the latest spot for any given callsign."
description:>
"De-duplicate" the spots, returning only the latest spot for any given callsign.
schema:
type:boolean
default:false
@@ -605,7 +726,13 @@ components:
AlertReceivedSince:
name:received_since
in:query
description:Limit the alerts to only ones that the system found out about at this time or later. Time in UTC seconds since UNIX epoch. If you are using a front-end that tracks the last time it queried the API and requests alerts since then, you want *this* version of the query parameter, not "since", because otherwise it may miss things. The logic is "greater than" rather than "greater than or equal to", so you can submit the time of the last received item back to this call and you will get all the more recent alerts back, without duplicating the previous latest spot.
description:>
Limit the alerts to only ones that the system found out about at this time or later. Time in
UTC seconds since UNIX epoch. If you are using a front-end that tracks the last time it queried
the API and requests alerts since then, you want *this* version of the query parameter, not
"since", because otherwise it may miss things. The logic is "greater than" rather than "greater
than or equal to", so you can submit the time of the last received item back to this call and
you will get all the more recent alerts back, without duplicating the previous latest spot.
schema:
type:number
CallParam:
@@ -844,7 +971,8 @@ components:
properties:
id:
type:string
description:Unique identifier based on a hash of the spot to distinguish this one from any others.
description:>
Unique identifier based on a hash of the spot to distinguish this one from any others.
description:QTH of the operator that has been spotted. This could be from any SIG refs or could be from online lookup of their home QTH.
description:>
QTH of the operator that has been spotted. This could be from any SIG refs or could be
from online lookup of their home QTH.
example:Dorset
dx_country:
type:string
description:Country of the operator. Note that this is named "country" for commonality with other amateur radio tools, but in reality this is more of a "DXCC Name", as it includes many options which are not countries, just territories that DXCC uniquely identifies.
description:>
Country of the operator. Note that this is named "country" for commonality with other
amateur radio tools, but in reality this is more of a "DXCC Name", as it includes many
options which are not countries, just territories that DXCC uniquely identifies.
example:England
dx_flag:
type:string
description:Country flag of the DX operator. This is limited to the range of emoji flags. For some DXCCs there may not be an official emoji flag, e.g. Northern Ireland, so the appearance may vary depending on your browser and operating system. Some small islands may also have no flag. Many DXCCs may also share a flag, e.g. mainland Spain, Balearic Islands, etc.
description:>
Country flag of the DX operator. This is limited to the range of emoji flags. For some
DXCCs there may not be an official emoji flag, e.g. Northern Ireland, so the appearance
may vary depending on your browser and operating system. Some small islands may also have
no flag. Many DXCCs may also share a flag, e.g. mainland Spain, Balearic Islands, etc.
example:""
dx_continent:
description:Continent of the DX operator
@@ -887,22 +1024,36 @@ components:
example:"7"
dx_grid:
type:string
description:Maidenhead grid locator for the DX spot. This could be from a geographical reference e.g. POTA, or just from the country
description:>
Maidenhead grid locator for the DX spot. This could be from a geographical reference
e.g. POTA, or just from the country.
example:IO91aa
dx_latitude:
type:number
description:Latitude of the DX spot, in degrees. This could be from a geographical reference e.g. POTA, or from a QRZ lookup
description:>
Latitude of the DX spot, in degrees. This could be from a geographical reference e.g.
POTA, or from a QRZ lookup.
example:51.2345
dx_longitude:
type:number
description:Longitude of the DX spot, in degrees. This could be from a geographical reference e.g. POTA, or from a QRZ lookup
description:>
Longitude of the DX spot, in degrees. This could be from a geographical reference e.g.
POTA, or from a QRZ lookup.
example:-1.2345
dx_location_source:
description:Where we got the DX location (grid/latitude/longitude) from. If this was from the spot itself, or from a lookup of the SIG ref (e.g. park) it's likely quite accurate, but if we had to fall back to QRZ lookup, or even a location based on the DXCC itself, it will be a lot less accurate.
description:>
Where we got the DX location (grid/latitude/longitude) from. If this was from the spot
itself, or from a lookup of the SIG ref (e.g. park) it's likely quite accurate, but if
we had to fall back to QRZ lookup, or even a location based on the DXCC itself, it will
be a lot less accurate.
$ref:"#/components/schemas/LocationSourceForSpot"
dx_location_good:
type:boolean
description:Does the software think the location is good enough to put a marker on a map? This is true if the source is "SPOT", "SIG REF LOOKUP" or "WAB/WAI GRID", or alternatively if the source is "HOME QTH" and the callsign doesn't have a slash in it (i.e. operator likely at home).
description:>
Does the software think the location is good enough to put a marker on a map? This is
true if the source is "SPOT", "SIG REF LOOKUP" or "WAB/WAI GRID", or alternatively if
the source is "HOME QTH" and the callsign doesn't have a slash in it (i.e. operator
likely at home).
example:true
de_call:
type:string
@@ -910,11 +1061,18 @@ components:
example:M0TEST
de_country:
type:string
description:Country of the operator. Note that this is named "country" for commonality with other amateur radio tools, but in reality this is more of a "DXCC Name", as it includes many options which are not countries, just territories that DXCC uniquely identifies.
description:>
Country of the operator. Note that this is named "country" for commonality with other
amateur radio tools, but in reality this is more of a "DXCC Name", as it includes many
options which are not countries, just territories that DXCC uniquely identifies.
example:England
de_flag:
type:string
description:Country flag of the spotter. This is limited to the range of emoji flags. For some DXCCs there may not be an official emoji flag, e.g. Northern Ireland, so the appearance may vary depending on your browser and operating system. Some small islands may also have no flag. Many DXCCs may also share a flag, e.g. mainland Spain, Balearic Islands, etc.
description:>
Country flag of the spotter. This is limited to the range of emoji flags. For some DXCCs
there may not be an official emoji flag, e.g. Northern Ireland, so the appearance may
vary depending on your browser and operating system. Some small islands may also have no
flag. Many DXCCs may also share a flag, e.g. mainland Spain, Balearic Islands, etc.
example:""
de_continent:
description:Continent of the spotter
@@ -929,15 +1087,24 @@ components:
example:"9"
de_grid:
type:string
description:Maidenhead grid locator for the spotter. This is not going to be from a xOTA reference so it will likely just be a QRZ or DXCC lookup. If the spotter is also portable, this is probably wrong, but it's good enough for some simple mapping.
description:>
Maidenhead grid locator for the spotter. This is not going to be from a xOTA reference
so it will likely just be a QRZ or DXCC lookup. If the spotter is also portable, this is
probably wrong, but it's good enough for some simple mapping.
example:IO91aa
de_latitude:
type:number
description:Latitude of the spotter, in degrees. This is not going to be from a xOTA reference so it will likely just be a QRZ or DXCC lookup. If the spotter is also portable, this is probably wrong, but it's good enough for some simple mapping.
description:>
Latitude of the spotter, in degrees. This is not going to be from a xOTA reference so it
will likely just be a QRZ or DXCC lookup. If the spotter is also portable, this is
probably wrong, but it's good enough for some simple mapping.
example:51.2345
de_longitude:
type:number
description:Longitude of the DX spotspotter, in degrees. This is not going to be from a xOTA reference so it will likely just be a QRZ or DXCC lookup. If the spotter is also portable, this is probably wrong, but it's good enough for some simple mapping.
description:>
Longitude of the DX spotspotter, in degrees. This is not going to be from a xOTA
reference so it will likely just be a QRZ or DXCC lookup. If the spotter is also
portable, this is probably wrong, but it's good enough for some simple mapping.
example:-1.2345
mode:
description:Reported mode.
@@ -947,7 +1114,9 @@ components:
description:Inferred mode "family".
$ref:"#/components/schemas/ModeType"
mode_source:
description:Where we got the mode from. If this was from the spot itself, it's likely quite accurate, but if we had to fall back to the bandplan, it might not be correct.
description:>
Where we got the mode from. If this was from the spot itself, it's likely quite accurate,
but if we had to fall back to the bandplan, it might not be correct.
$ref:"#/components/schemas/ModeSource"
freq:
type:number
@@ -966,7 +1135,10 @@ components:
example:"2025-10-05T12:34:56.789Z"
received_time:
type:number
description:Time that this software received the spot, UTC seconds since UNIX epoch. This is used with the "since_received" call to our API to receive all data that is new to us, even if by a quirk of the API it might be older than the list time the client polled the API.
description:>
Time that this software received the spot, UTC seconds since UNIX epoch. This is used
with the "since_received" call to our API to receive all data that is new to us, even if
by a quirk of the API it might be older than the list time the client polled the API.
example:1759579508
received_time_iso:
type:string
@@ -1059,7 +1231,8 @@ components:
properties:
id:
type:string
description:Unique identifier based on a hash of the alert to distinguish this one from any others.
description:>
Unique identifier based on a hash of the alert to distinguish this one from any others.
description:Country of the DX operator. Country of the operator. Note that this is named "country" for commonality with other amateur radio tools, but in reality this is more of a "DXCC Name", as it includes many options which are not countries, just territories that DXCC uniquely identifies. This, and the subsequent fields, assume that all activators will be in the same country!
description:>
Country of the DX operator. Note that this is named "country" for commonality with other
amateur radio tools, but in reality this is more of a "DXCC Name", as it includes many
options which are not countries, just territories that DXCC uniquely identifies. This, and
the subsequent fields, assume that all activators will be in the same country!
example:England
dx_flag:
type:string
description:Country flag of the DX operator. This is limited to the range of emoji flags. For some DXCCs there may not be an official emoji flag, e.g. Northern Ireland, so the appearance may vary depending on your browser and operating system. Some small islands may also have no flag. Many DXCCs may also share a flag, e.g. mainland Spain, Balearic Islands, etc.
description:>
Country flag of the DX operator. This is limited to the range of emoji flags. For some
DXCCs there may not be an official emoji flag, e.g. Northern Ireland, so the appearance
may vary depending on your browser and operating system. Some small islands may also have
no flag. Many DXCCs may also share a flag, e.g. mainland Spain, Balearic Islands, etc.
example:""
dx_continent:
description:Continent of the DX operator
@@ -1118,7 +1299,10 @@ components:
example:"2025-10-05T12:34:56.789Z"
received_time:
type:number
description:Time that this software received the alert, UTC seconds since UNIX epoch. This is used with the "since_received" call to our API to receive all data that is new to us, even if by a quirk of the API it might be older than the list time the client polled the API.
description:>
Time that this software received the alert, UTC seconds since UNIX epoch. This is used
with the "since_received" call to our API to receive all data that is new to us, even if
by a quirk of the API it might be older than the list time the client polled the API.
example:1759579508
received_time_iso:
type:string
@@ -1171,11 +1355,15 @@ components:
example:OK
last_updated:
type:number
description:The last time at which this provider received data, UTC seconds since UNIX epoch. If this is zero, the spot provider has never updated.
description:>
The last time at which this provider received data, UTC seconds since UNIX epoch. If this
is zero, the spot provider has never updated.
example:1759579508
last_spot:
type:number
description:The time of the latest spot received by this provider, UTC seconds since UNIX epoch. If this is zero, the spot provider has never received a spot that was accepted by the system.
description:>
The time of the latest spot received by this provider, UTC seconds since UNIX epoch. If
this is zero, the spot provider has never received a spot that was accepted by the system.
example:1759579508
AlertProviderStatus:
@@ -1194,7 +1382,9 @@ components:
example:OK
last_updated:
type:number
description:The last time at which this provider received data, UTC seconds since UNIX epoch. If this is zero, the alert provider has never updated.
description:>
The last time at which this provider received data, UTC seconds since UNIX epoch. If this
is zero, the alert provider has never updated.
example:1759579508
Band:
@@ -1224,7 +1414,9 @@ components:
example:Parks on the Air
ref_regex:
type:string
description:Regex that matches this SIG's reference IDs. Generally for Spothole's own internal use, clients probably won't need this.
description:>
Regex that matches this SIG's reference IDs. Generally for Spothole's own internal use,
clients probably won't need this.
example:"[A-Z]{2}\\-\\d+"
SolarConditions:
@@ -1357,9 +1549,8 @@ components:
solar_storm_forecast:
type:object
description:>
NOAA Solar Radiation Storm forecast containing probability (%) of S1 or greater events per day.
Keys are UNIX timestamps (UTC seconds since epoch) for the start of each forecast day.
Values are integer percentages (0–100).
Forecast probability (%) of S1 or greater solar radiation storms per day, provided by NOAA. Keys are UNIX
timestamps (UTC seconds since epoch) for the start of each forecast day.
additionalProperties:
type:integer
minimum:0
@@ -1371,9 +1562,8 @@ components:
blackout_forecast_r1r2:
type:object
description:>
NOAA Radio Blackout forecast containing probability (%) of R1–R2 (Minor–Moderate) blackout events
per day. Keys are UNIX timestamps (UTC seconds since epoch) for the start of each
forecast day. Values are integer percentages (0–100).
Forecast probability (%) of R1-R2 or greater radio blackout events per day, provided by NOAA. Keys are UNIX
timestamps (UTC seconds since epoch) for the start of each forecast day.
additionalProperties:
type:integer
minimum:0
@@ -1385,9 +1575,8 @@ components:
blackout_forecast_r3_or_greater:
type:object
description:>
NOAA Radio Blackout forecast containing probability (%) of R3 or greater (Strong–Extreme) blackout
events per day. Keys are UNIX timestamps (UTC seconds since epoch) for the start of each
forecast day. Values are integer percentages (0–100).
Forecast probability (%) of R3 or greater radio blackout events per day, provided by NOAA. Keys are UNIX
timestamps (UTC seconds since epoch) for the start of each forecast day.
additionalProperties:
type:integer
minimum:0
@@ -1484,7 +1673,9 @@ components:
fof2:
type:object
nullable:true
description:F2 layer critical frequency (foF2) measurements in MHz, keyed by UNIX timestamp (UTC seconds since epoch) of each measurement. Can be null if there is no data.
description:>
F2 layer critical frequency (foF2) measurements in MHz, keyed by UNIX timestamp (UTC
seconds since epoch) of each measurement. Can be null if there is no data.
additionalProperties:
type:number
example:
@@ -1493,7 +1684,9 @@ components:
muf:
type:object
nullable:true
description:Maximum Usable Frequency (MUF) for a 3000 km path in MHz, keyed by UNIX timestamp (UTC seconds since epoch) of each measurement. Can be null if there is no data.
description:>
Maximum Usable Frequency (MUF) for a 3000 km path in MHz, keyed by UNIX timestamp (UTC
seconds since epoch) of each measurement. Can be null if there is no data.
additionalProperties:
type:number
example:
@@ -1502,7 +1695,9 @@ components:
luf:
type:object
nullable:true
description:Lowest Usable Frequency (LUF, reported as fmin) in MHz, keyed by UNIX timestamp (UTC seconds since epoch) of each measurement. Can be null if there is no data.
description:>
Lowest Usable Frequency (LUF, reported as fmin) in MHz, keyed by UNIX timestamp (UTC
seconds since epoch) of each measurement. Can be null if there is no data.
additionalProperties:
type:number
example:
@@ -1512,7 +1707,7 @@ components:
type:object
nullable:true
description:>
States of each HF amateur band, derived from the latest foF2, MUF and LUF values. Keyed by band name. Each
States of each HF amateur band, derived from the latest foF2, MUF and LUF values. Keyed by band name. Each
value is one of: "Closed" (band frequency is below LUF or above MUF), "Short" (band frequency is at or above
LUF and below foF2, so good for NVIS) or "Long" (band frequency is at or above foF2 and below MUF, so good
for DX). Null if foF2 or MUF data is not yet available.
@@ -1543,7 +1738,9 @@ components:
example:OK
last_updated:
type:number
description:The last time at which this provider received data, UTC seconds since UNIX epoch. If this is zero, the provider has never updated.
description:>
The last time at which this provider received data, UTC seconds since UNIX epoch. If this
is zero, the provider has never updated.
example:1759579508
SpotList:
@@ -1686,11 +1883,17 @@ components:
example:"EU"
max_spot_age:
type:integer
description:The maximum age, in seconds, of any spot before it will be deleted by the system. When querying the /api/v2/spots endpoint and providing a "max_age" or "since" parameter, there is no point providing a number larger than this, because the system drops all spots older than this.
description:>
The maximum age, in seconds, of any spot before it will be deleted by the system. When
querying the /api/v2/spots endpoint and providing a "max_age" or "since" parameter, there
is no point providing a number larger than this, because the system drops all spots older
than this.
example:3600
spot_allowed:
type:boolean
description:Whether the POST /spot call, to add spots to the server directly via its API, is permitted on this server.
description:>
Whether the POST /spot call, to add spots to the server directly via its API, is permitted
on this server.
example:true
spot_submit_providers:
type:object
@@ -1720,15 +1923,24 @@ components:
example:Ian
qth:
type:string
description:QTH of the operator. This could be from any SIG refs or could be from online lookup of their home QTH.
description:>
QTH of the operator. This could be from any SIG refs or could be from online lookup of
their home QTH.
example:Dorset
country:
type:string
description:Country of the operator. Note that this is named "country" for commonality with other amateur radio tools, but in reality this is more of a "DXCC Name", as it includes many options which are not countries, just territories that DXCC uniquely identifies.
description:>
Country of the operator. Note that this is named "country" for commonality with other
amateur radio tools, but in reality this is more of a "DXCC Name", as it includes many
options which are not countries, just territories that DXCC uniquely identifies.
example:England
flag:
type:string
description:Country flag of the operator. This is limited to the range of emoji flags. For some DXCCs there may not be an official emoji flag, e.g. Northern Ireland, so the appearance may vary depending on your browser and operating system. Some small islands may also have no flag. Many DXCCs may also share a flag, e.g. mainland Spain, Balearic Islands, etc.
description:>
Country flag of the operator. This is limited to the range of emoji flags. For some DXCCs
there may not be an official emoji flag, e.g. Northern Ireland, so the appearance may vary
depending on your browser and operating system. Some small islands may also have no flag.
Many DXCCs may also share a flag, e.g. mainland Spain, Balearic Islands, etc.
example:""
continent:
description:Continent of the operator
@@ -1747,18 +1959,27 @@ components:
example:14
grid:
type:string
description:Maidenhead grid locator for the operator's QTH. This could be from an online lookup service, or just based on the DXCC.
description:>
Maidenhead grid locator for the operator's QTH. This could be from an online lookup
service, or just based on the DXCC.
example:IO91aa
latitude:
type:number
description:Latitude of the operator's QTH, in degrees. This could be from an online lookup service, or just based on the DXCC.
description:>
Latitude of the operator's QTH, in degrees. This could be from an online lookup service,
or just based on the DXCC.
example:51.2345
longitude:
type:number
description:Longitude of the opertor's QTH, in degrees. This could be from an online lookup service, or just based on the DXCC.
description:>
Longitude of the opertor's QTH, in degrees. This could be from an online lookup service,
or just based on the DXCC.
example:-1.2345
location_source:
description:Where we got the location (grid/latitude/longitude) from. Unlike a spot where we might have a summit position or WAB square, here the only options are an online QTH lookup, or a location based purely on DXCC, or nothing.
description:>
Where we got the location (grid/latitude/longitude) from. Unlike a spot where we might
have a summit position or WAB square, here the only options are an online QTH lookup, or
description:Longitude of the north-east corner of the grid square.
example:0.0
example:0.0
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.