openapi: 3.0.4 info: title: Unnamed Spotting API description: |- 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. contact: email: ian@ianrenton.com license: name: The Unlicense url: https://unlicense.org/#the-unlicense version: 0.1 servers: - url: https://metaspot.m0trt.radio/api paths: /spots: get: tags: - spots summary: Retrieve a set of 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. operationId: spots parameters: - name: limit in: query description: Limit the number of spots in the response required: false schema: type: integer - name: since in: query description: Limit the spots to only ones at this time or later. Time in UTC seconds since UNIX epoch. required: false schema: type: integer - 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. required: false schema: type: integer - 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." required: false schema: type: string enum: - POTA - SOTA - WWFF - WWBOTA - GMA - HEMA - ParksNPeaks - Cluster - RBN - APRS-IS - name: sig in: query description: "Limit the spots to only ones from one or more Special Interest Groups. To select more than one SIG, supply a comma-separated list." required: false schema: type: string enum: - POTA - SOTA - WWFF - WWBOTA - GMA - HEMA - 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." required: false schema: type: string enum: - 160m - 80m - 60m - 40m - 30m - 20m - 17m - 15m - 12m - 10m - 6m - 4m - 2m - 70cm - 23cm - 13cm - 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." required: false schema: type: string enum: - CW - PHONE - SSB - USB - LSB - AM - FM - DV - DMR - DSTAR - C4FM - M17 - DIGI - DATA - FT8 - FT4 - RTTY - SSTV - JS8 - HELL - BPSK - PSK - BPSK31 - OLIVIA - name: mode_family 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." required: false schema: type: string enum: - CW - PHONE - DATA - 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." required: false schema: type: string enum: - EU - NA - SA - AS - AF - OC - AN - name: de_continent in: query description: "Limit the spots to only ones where the spotteris on the given continent(s). To select more than one continent, supply a comma-separated list." required: false schema: type: string enum: - EU - NA - SA - AS - AF - OC - AN responses: '200': description: Successfully retrieved spots. content: application/json: schema: type: array items: $ref: '#/components/schemas/Spot' /status: get: tags: - status summary: Retrieve the server status. description: Query information about the server for use in a diagnostics display operationId: status responses: '200': description: Successfully retrieved status. content: application/json: schema: type: object properties: "Web Server": type: object properties: status: type: string example: OK last_ran: type: string example: 2025-09-28T20:31:00+00:00 "Cleanup Timer": type: object properties: status: type: string example: OK last_page_access: type: string example: 2025-09-28T20:31:00+00:00 last_api_access: type: string example: 2025-09-28T20:31:00+00:00 "POTA...": type: object properties: status: type: string example: OK last_updated: type: string example: 2025-09-28T20:31:00+00:00 last_spot: type: string example: 2025-09-28T20:31:00+00:00 components: schemas: Spot: type: object properties: guid: type: string description: Globally unique identifier to distinguish this spot from any others. example: d8a3f1b6-cb73-464e-b717-54b7004aa04f dx_call: type: string description: Callsign of the operator that has been spotted example: M0TRT de_call: type: string description: Callsign of the operator that has spotted them example: M0TEST dx_name: type: string description: Name of the operator that has been spotted example: Ian dx_country: type: string description: Country of the DX operator example: United Kingdom de_country: type: string description: Country of the spotter example: United Kingdom dx_flag: type: string description: Country flag of the DX operator example: "" de_flag: type: string description: Country flag of the spotter example: "" dx_continent: type: string description: Continent of the DX operator enum: - EU - NA - SA - AS - AF - OC - AN example: EU de_continent: type: string enum: - EU - NA - SA - AS - AF - OC - AN description: Continent of the spotter example: EU dx_dxcc_id: type: integer description: DXCC ID of the DX operator example: 235 de_dxcc_id: type: integer description: DXCC ID of the spotter example: 235 dx_cq_zone: type: integer description: CQ zone of the DX operator example: 27 dx_itu_zone: type: integer description: ITU zone of the DX operator example: 14 dx_aprs_ssid: type: string description: If this is an APRS spot, what SSID was the DX operator using? example: "" mode: type: string description: Reported mode. enum: - CW - PHONE - SSB - USB - LSB - AM - FM - DV - DMR - DSTAR - C4FM - M17 - DIGI - DATA - FT8 - FT4 - RTTY - SSTV - JS8 - HELL - BPSK - PSK - BPSK31 - OLIVIA example: SSB mode_family: type: string description: Inferred mode "family". enum: - CW - PHONE - DATA example: PHONE freq: type: number description: Frequency, in kHz example: 7150.5 band: type: string description: Band, defined by the frequency. enum: - 160m - 80m - 60m - 40m - 30m - 20m - 17m - 15m - 12m - 10m - 6m - 4m - 2m - 70cm - 23cm - 13cm - Unknown example: 40m time: type: string description: Time of the spot, ISO 8601 format example: 2025-09-28T19:12:41Z received_time: type: string description: Time that this software received the spot, ISO 8601 format. 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: 2025-09-28T19:12:41Z comment: type: string description: Comment left by the spotter, if any example: "59 in NY 73" sig: type: string description: Special Interest Group (SIG), e.g. outdoor activity programme such as POTA enum: - POTA - SOTA - WWFF - WWBOTA - GMA - HEMA example: POTA sig_refs: type: array items: type: string description: SIG references. We allow multiple here for e.g. n-fer activations, unlike ADIF SIG_INFO example: GB-0001 sig_refs_names: type: array items: type: string description: SIG reference names example: Null Country Park activation_score: type: integer description: Activation score. SOTA only example: 0 grid: type: string description: Maidenhead grid locator for the spot. This could be from a geographical reference e.g. POTA, or just from the country example: IO91aa latitude: type: number description: Latitude, in degrees. This could be from a geographical reference e.g. POTA, or from a QRZ lookup example: 51.2345 longitude: type: number description: Latitude, in degrees. This could be from a geographical reference e.g. POTA, or from a QRZ lookup example: -1.2345 location_source: type: string description: Where we got the location (grid/latitude/longitude) from. If this was from the spot itself, 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. enum: - SPOT - QRZ - DXCC - NONE example: SPOT 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", or alternatively if the source is "QRZ" and the callsign doesn't have a slash in it (i.e. operator likely at home). example: true qrt: type: boolean description: QRT state. Some APIs return spots marked as QRT. Otherwise we can check the comments. example: false source: type: string description: Where we got the spot from. enum: - POTA - SOTA - WWFF - WWBOTA - GMA - HEMA - ParksNPeaks - Cluster - RBN - APRS-IS example: POTA source_id: type: string description: The ID the source gave it, if any. example: "GUID-123456"