afu.tools

Start › API

Offene API für Amateurfunkdaten

Alles, was diese Seite anzeigt, kommt aus einer Lese-API. Sie gibt JSON zurück und darf in eigenen Programmen verwendet werden, solange afu.tools als Quelle genannt wird. Für den Zugang braucht es einen Schlüssel, kostenlos, sofort und ohne Rückfrage.

Überblick

https://afu.tools/api/v1 liefert alles, was diese Seite anzeigt: Bandplan mit Klassenrechten, Relais mit Umkreissuche und CSV-Export, DOK-Verzeichnis, Prüfungstermine samt Feeds, Contestkalender, POTA- und SOTA-Referenzen, Ausbreitungsdaten und Rufzeichenabfragen.

Die Daten werden regelmäßig aus den amtlichen und verbandseigenen Quellen zusammengetragen und als fertige Schnappschüsse ausgeliefert. Welche Quelle wie oft nachgezogen wird, steht unten.

Zu jedem Bereich steht hier eine echte, gekürzte Beispielantwort zum Aufklappen, damit man die Feldnamen sieht, bevor man den ersten Abruf schreibt. Und jede Antwort sagt selbst, welche Quellen bei der Weitergabe genannt werden müssen: Quellenangabe.

Zugang

Jeder Abruf braucht einen Schlüssel. Er sorgt dafür, dass die Ratenbegrenzung auf dich zählt und nicht auf deine IP-Adresse, hinter der auch andere sitzen.

Der Schlüssel kommt sofort per Mail. Einer je Domain, beliebig viele je Mailadresse. Fragst du für dieselbe Domain erneut an, ersetzt der neue deinen alten, aber erst, sobald du ihn zum ersten Mal benutzt. Klemmt etwas: info@afu.tools.

Mitgeschickt als Kopfzeile oder als Bearer-Token:

$ curl -H "X-API-Key: afu_…" https://afu.tools/api/v1/bands
$ curl -H "Authorization: Bearer afu_…" https://afu.tools/api/v1/bands

Ohne Schlüssel: Status 401. Ausgenommen sind /api/v1/health und die Abo-Adressen, die auf feed.ics oder feed.rss enden. Ein Kalenderprogramm oder ein Feedleser kann keinen Schlüssel mitschicken, und ein Abo, das nur im Browser funktioniert, wäre keines. Die Seiten von afu.tools und die übrigen eigenen Anwendungen erkennt der Server an ihrer Herkunft, sie brauchen ebenfalls keinen.

Die Dateien unter /data/ gehören zur Seite und antworten von außen mit 403. Dieselben Daten gibt es über die Endpunkte unten, gefiltert und mit Umkreissuche.

Mitgezählt wird, welcher Zugang welchen Endpunkt wie oft abruft und von welcher Adresse. Die Abfrage selbst nicht: bei einer Rufzeichenabfrage steht dort, dass sie benutzt wurde, nicht nach wem gesucht wurde. Näheres im Datenschutz.

Grundregeln

  • Quelle nennenWer die Daten benutzt, nennt afu.tools und die ursprüngliche Quelle, sichtbar für den, der das Ergebnis sieht. Welche das sind, sagt jede Antwort selbst: Quellenangabe.
  • Nur GETAntworten sind JSON in UTF-8. Ausnahmen sind die CSV-Exporte und die Feeds.
  • Ratenbegrenzung120 Anfragen je Minute und Schlüssel, für Rufzeichenabfragen 30, für CSV-Exporte 10. Darüber kommt Status 429 mit Retry-After.
  • Cross-Origin erlaubtDie API lässt sich direkt aus einer Webseite heraus aufrufen.
  • Fehlerformat{"error": "…", "status": 404}
  • Maschinenlesbar/api/v1/openapi.json. Eine Swagger-Oberfläche gibt es bewusst nicht, sie lädt ihre Skripte von einem fremden CDN nach.

Quellenangabe in jeder Antwort

Wer Daten weitergibt, muss sagen, woher sie kommen, und dafür muss er wissen, wen. Das steht deshalb nicht nur auf einer Seite, die man aufrufen müsste: jede Antwort trägt die Angabe mit. Im JSON als Block quellenangabe, bei CSV-Exporten und Feeds, die kein JSON sind, als Kopfzeile X-Quellen. Die Zeile aus nennung ist die, die beim Ergebnis stehen muss.

{
  "nennung": "Quellen: afu.tools; Bundesnetzagentur",
  "hinweis": "Wer diese Daten weitergibt oder anzeigt, nennt die hier aufgeführten Quellen sichtbar für den, der das Ergebnis sieht: die ursprüngliche Quelle und afu.tools.",
  "doku": "https://afu.tools/api#quellenangabe",
  "zusammenstellung": {
    "name": "afu.tools",
    "url": "https://afu.tools",
    "lizenz": "Nennung von afu.tools"
  },
  "datensaetze": [
    {
      "id": "exams",
      "datensatz": "Prüfungstermine",
      "wofuer": "Termine mit Umkreissuche, Kalender- und RSS-Abo",
      "stand": "2026-09-01T01:25:00Z",
      "quellen": [
        {
          "name": "Bundesnetzagentur",
          "url": "https://www.bundesnetzagentur.de/DE/Fachthemen/Telekommunikation/Frequenzen/SpezielleAnwendungen/Amateurfunk/start.html",
          "lizenz": "amtliche Veröffentlichung"
        }
      ]
    }
  ]
}
  • nennungDie fertige Zeile zum Hinschreiben, Quellen mit Semikolon getrennt. In Quellennamen stecken selbst Kommas, deshalb kein Komma.
  • datensaetzeWoraus die Antwort besteht. Je Datensatz die Kennung, wofür er gebraucht wird, der Zeitpunkt des letzten Abrufs (stand, null bei allem, was live abgefragt wird) und die Quellen mit Name, Adresse und Bedingung.
  • zusammenstellungafu.tools selbst. Die Zusammenstellung ist Arbeit und wird mitgenannt, auch wenn eine Antwort einmal aus keiner fremden Quelle stammt.
  • lizenz nullKeine ausdrückliche Bedingung bekannt. Dann gilt die Grundregel: Quelle nennen.
  • KopfzeilenX-Quellen trägt dieselbe Zeile, X-Quellen-Doku zeigt hierher. Beide stehen an jeder Antwort, auch an CSV und Feeds.
  • FeedsIm Kalender steht die Angabe als X-WR-CALDESC, im RSS als <copyright>.

Vollständig, also alle Datensätze mit Bedingung und Stand samt der Zuordnung Endpunkt zu Datensatz, steht das unter /api/v1/quellen. Zum Lesen für Menschen gibt es dieselbe Aufstellung auf der Seite Quellen.

GET/api/v1/quellen
Beispielantwort GET /api/v1/quellen
{
  "quellenangabe": { … },
  "generated": "2026-09-01T08:01:15Z",
  "hinweis": "Wer diese Daten weitergibt oder anzeigt, nennt die hier aufgeführten Quellen sichtbar für den, der das Ergebnis sieht: die ursprüngliche Quelle und afu.tools.",
  "zusammenstellung": {
    "name": "afu.tools",
    "url": "https://afu.tools",
    "lizenz": "Nennung von afu.tools"
  },
  "doku": "https://afu.tools/api#quellenangabe",
  "count": 20,
  "datensaetze": [
    {
      "id": "anlaufstellen",
      "datensatz": "Anlaufstellen je Betriebsart",
      "wofuer": "Digimode- und Anruffrequenzen",
      "stand": "2026-09-01T04:07:01Z",
      "quellen": [
        {
          "name": "Vorgabefrequenzen von WSJT-X",
          "url": "https://wsjt.sourceforge.io/",
          "lizenz": null
        },
        {
          "name": "Vorgabefrequenzen von JS8Call",
          "url": "http://js8call.com/",
          "lizenz": null
        },
        {
          "name": "Bandplan der IARU Region 1",
          "url": "https://www.iaru-r1.org/reference/band-plans/",
          "lizenz": null
        },
        {
          "name": "Emergency Centres of Activity, IARU Region 1",
          "url": "https://www.iaru-r1.org/on-the-air/emergency-communications/",
          "lizenz": null
        },
        {
          "name": "NCDXF/IARU International Beacon Project",
          "url": "https://www.ncdxf.org/beacon/",
          "lizenz": null
        }
      ]
    },
    "... 19 weitere"
  ],
  "endpunkte": {
    "/": [],
    "/anlaufstellen": [
      "anlaufstellen"
    ],
    "/ausland": [
      "ausland"
    ],
    "...": "47 weitere"
  },
  "programme": [
    {
      "name": "Leaflet 1.9.4",
      "url": "https://leafletjs.com",
      "lizenz": "BSD-2-Clause"
    },
    "... 1 weitere"
  ]
}

In den Beispielen weiter unten ist dieser Block als "quellenangabe": { … } gekürzt und lange Listen sind auf ein oder zwei Einträge zusammengestrichen; der Rest steht als "… N weitere" da. Sonst stünde in jedem Beispiel dreimal dasselbe.

Bandplan

GET/api/v1/bands
GET/api/v1/bands/20m
GET/api/v1/frequency/145.500
GET/api/v1/frequency/14070kHz

Liefert je Band die Zuweisungen nach Anlage 1 der Amateurfunkverordnung mit Status, zulässiger Leistung je Klasse und den Zusatzbestimmungen, dazu die Segmente des IARU-Bandplans. /frequency beantwortet die Frage, was an einer bestimmten Frequenz gilt.

Beispielantwort GET /api/v1/bands/20m
{
  "quellenangabe": { … },
  "key": "20m",
  "label": "20 m",
  "from_hz": 14000000,
  "to_hz": 14350000,
  "allocations": [
    {
      "from_hz": 14000000,
      "to_hz": 14350000,
      "status": "P",
      "classes": {
        "A": {
          "value": 750,
          "unit": "PEP"
        },
        "E": null,
        "N": null
      },
      "notes": [
        3,
        13
      ]
    }
  ],
  "segments": [
    {
      "from_hz": 14000000,
      "to_hz": 14060000,
      "max_bandwidth_hz": 200,
      "mode": "CW",
      "usage": null
    },
    {
      "from_hz": 14060000,
      "to_hz": 14350000,
      "max_bandwidth_hz": 2700,
      "mode": "All modes",
      "usage": null
    }
  ],
  "activities": [
    {
      "freq_hz": 14060000,
      "description": "CW QRP Centre of Activity"
    },
    {
      "freq_hz": 14070000,
      "description": "PSK Centre of Activity"
    },
    {
      "freq_hz": 14074000,
      "description": "FT8 Centre of Activity"
    },
    {
      "freq_hz": 14100000,
      "description": "International Beacon Project"
    },
    {
      "freq_hz": 14300000,
      "description": "Global Emergency Centre of Activity"
    }
  ]
}
Beispielantwort GET /api/v1/frequency/145.500
{
  "quellenangabe": { … },
  "freq_hz": 145500000.0,
  "band": "2m",
  "label": "2 m",
  "allocation": {
    "from_hz": 144000000,
    "to_hz": 146000000,
    "status": "P",
    "classes": {
      "A": {
        "value": 750,
        "unit": "PEP"
      },
      "E": {
        "value": 75,
        "unit": "PEP"
      },
      "N": {
        "value": 6.1,
        "unit": "ERP"
      }
    },
    "notes": [
      6,
      13
    ]
  },
  "segments": [
    {
      "from_hz": 144100000,
      "to_hz": 146000000,
      "max_bandwidth_hz": 2700,
      "mode": "All modes",
      "usage": null
    }
  ],
  "notes": {
    "6": "Belegte Bandbreite höchstens 40 kHz.",
    "13": "Teile des Bereichs sind auch dem Amateurfunkdienst über Satelliten zugewiesen."
  },
  "source": {
    "name": "Anlage 1 AFuV (Nutzungsbedingungen Amateurfunkdienst)",
    "url": "https://www.gesetze-im-internet.de/afuv_2005/anlage_1.html",
    "retrieved": "2026-08-23"
  }
}

Relais

GET/api/v1/repeaters?band=2m&mode=FM&near=JO50HB&km=50
GET/api/v1/repeaters?q=DB0
GET/api/v1/repeaters?source=fm-funknetz.de
GET/api/v1/repeaters?mode=FM-Funknetz&near=JO50HB&km=100
GET/api/v1/repeaters/export.csv?format=chirp&near=JO50HB&km=50
GET/api/v1/repeaters/export.csv?format=rigstudio&band=70cm

Gefiltert wird nach band, mode, source und mit q über Rufzeichen, Ort, Locator, Netz und Bemerkung. Steht eine Station in mehreren Quellen, ist sie ein Eintrag mit einer Liste unter sources. near nimmt einen Locator oder lat,lon, mit Umkreis kommen Entfernung und Richtung mit zurück. Die CSV-Exporte haben das Format der gängigen Programmiersoftware für Funkgeräte, oder sie gehen direkt in den Rigstudio.

FeldBedeutung
tone_hzCTCSS-Frequenz in Hertz
tone_mode tone nur senden, tsql auch auswerten, dcs, 1750
dcsDCS-Code, dreistellig
call_1750Relais öffnet mit dem 1750-Hz-Rufton
tone_rawursprünglicher Text der Quelle, für unklare Angaben

Die Tonangaben pflegen die Betreiber selbst und sind entsprechend lückenhaft.

Beispielantwort GET /api/v1/repeaters?band=2m&near=JO50HB&km=25&limit=2
{
  "quellenangabe": { … },
  "generated": "2026-09-01T04:07:00Z",
  "sources": [
    "fm-funknetz.de",
    "repeatermap.de"
  ],
  "tone_note": "Tonangaben stammen aus den Freitextfeldern der Quellen und sind von den Betreibern gepflegt. Nicht jeder Eintrag ist aktuell.",
  "count": 2,
  "repeaters": [
    {
      "callsign": "DB0NH",
      "rx_mhz": 145.3375,
      "tx_mhz": 145.3375,
      "offset_mhz": 0.0,
      "tone_hz": 88.5,
      "tone_mode": "tone",
      "dcs": null,
      "call_1750": false,
      "tone_raw": "88.5 Hz",
      "mode": "FM",
      "netz": "FM-Funknetz",
      "band": "2m",
      "qth": "Bühl, Ufr., BY",
      "locator": "JO50HB",
      "keeper": "DL1XXX",
      "talkgroups": "96126",
      "remarks": null,
      "lat": 50.075,
      "lon": 10.6663,
      "source": "fm-funknetz.de",
      "last_seen": "2026-09-01",
      "sources": [
        "fm-funknetz.de"
      ],
      "distance_km": 3.3,
      "bearing_deg": 65
    },
    "... 1 weitere"
  ]
}
Beispielantwort GET /api/v1/repeaters/export.csv?format=chirp&band=2m&near=JO50HB&km=25
Location,Name,Frequency,Duplex,Offset,Tone,rToneFreq,cToneFreq,DtcsCode,DtcsPolarity,Mode,TStep,Skip,Comment
1,DB0NH,145.337500,,0.000000,Tone,88.5,88.5,023,NN,FM,5.00,,"Bühl, Ufr., BY FM-Funknetz JO50HB"
2,DB0GH,144.850000,,0.000000,Tone,88.5,88.5,023,NN,FM,5.00,,"Gaedheim, BY FM-Funknetz JO50EA"

DOK und Ortsverbände

GET/api/v1/dok/B37
GET/api/v1/dok/B
GET/api/v1/dok?q=Hassberge
GET/api/v1/sdok?q=Aktivit
Beispielantwort GET /api/v1/dok/B37
{
  "quellenangabe": { … },
  "type": "ov",
  "ov": {
    "id": "B37",
    "name": "Hassberge",
    "link": "https://www.darc.de/der-club/distrikte/b/ortsverbaende/37/",
    "chairman_call": "DK5DEN",
    "district_id": "B"
  },
  "district": {
    "id": "B",
    "name": "Franken",
    "link": "https://www.darc.de/der-club/distrikte/b/",
    "chairman_call": "DG4NBI"
  }
}
Beispielantwort GET /api/v1/sdok?q=Aktivit&limit=2
{
  "quellenangabe": { … },
  "generated": "2026-09-01T01:25:00Z",
  "count": 417,
  "sdok": [
    {
      "sdok": "DLFF26",
      "reason": "WWFF Aktivitäten",
      "callsign": "DP44WCA",
      "start": "2026-04-28",
      "end": "2026-12-31",
      "dok": "U23"
    },
    {
      "sdok": "SOP26",
      "reason": "Aktivitätsmonat für Diplom Sea Of Peace",
      "callsign": "DL0SOP",
      "start": "2026-07-01",
      "end": "2026-07-31",
      "dok": "V04"
    }
  ]
}

Prüfungstermine

GET/api/v1/exams?status=verfuegbar
GET/api/v1/exams?near=JO50HB&km=200&klasse=Klasse%20N
GET/api/v1/exams/history
GET/api/v1/exams/feed.rss?near=JO50HB&km=200
GET/api/v1/exams/feed.ics?status=alle

Die Feeds tragen dieselben Filter wie die Liste. status=alle nimmt auch ausgebuchte Termine mit, sonst kommen nur freie Plätze.

Beispielantwort GET /api/v1/exams?near=JO50HB&km=200
{
  "quellenangabe": { … },
  "generated": "2026-09-01T01:25:00Z",
  "source": {
    "name": "Bundesnetzagentur, Prüfungstermine Amateurfunk",
    "url": "https://www.bundesnetzagentur.de/DE/Fachthemen/Telekommunikation/Frequenzen/SpezielleAnwendungen/Amateurfunk/start.html"
  },
  "count": 15,
  "exams": [
    {
      "id": 20,
      "date": "2026-09-08",
      "ort": "Eschborn",
      "standort": "Eschborn",
      "tageszeit": null,
      "pruefung": "Alle Prüfungen",
      "code": null,
      "status": "ausgebucht",
      "first_seen": "2026-06-21 20:57:47",
      "available_since": null,
      "booked_since": "2026-06-21 20:57:47",
      "stand": "28. August 2026",
      "lat": 50.1433,
      "lon": 8.5706,
      "distance_km": 147
    },
    {
      "id": 84,
      "date": "2026-09-08",
      "ort": "Nürnberg",
      "standort": "Nürnberg",
      "tageszeit": null,
      "pruefung": "Alle Prüfungen",
      "code": null,
      "status": "ausgebucht",
      "first_seen": "2026-08-19 06:00:00",
      "available_since": null,
      "booked_since": "2026-08-19 06:00:00",
      "stand": "28. August 2026",
      "lat": 49.4521,
      "lon": 11.0767,
      "distance_km": 75
    },
    "... 13 weitere"
  ]
}

Contestkalender

GET/api/v1/contests?days=365&klasse=N
GET/api/v1/contests/feed.ics?klasse=N

Die Termine sind aus den veröffentlichten Ausschreibungsregeln berechnet, jeder Eintrag nennt die Regel und verlinkt die Ausschreibung. bands sind die Bänder der Ausschreibung, klassen sagt je Lizenzklasse (N, E, A), welche davon sie nach Bandplan nutzen darf. Eine Klasse ohne Band fehlt dort. Mit klasse=N (oder E, A) bleiben in Liste und Kalender-Abo nur die Conteste, bei denen diese Klasse mindestens ein Band hat. Termine, die nur der DARC-Contestkalender führt, tragen "quelle": "darc"; die regelmäßigen Aktivitätsabende davon ("art": "aktivitaet", etwa CWT, NRAU- oder RSGB-Aktivität) kommen nur mit aktivitaeten=1 mit, in der Liste wie im Abo.

Beispielantwort GET /api/v1/contests?days=30
{
  "quellenangabe": { … },
  "generated": "2026-09-01T04:07:01Z",
  "note": "Die Termine sind aus den Wiederholungsregeln der Ausschreibungen berechnet und gegen die Termine des Jahres 2026 gegengeprüft. Einzelne Ausgaben werden gelegentlich verschoben, verbindlich ist die Ausschreibung des Veranstalters. Wo keine Uhrzeit steht, war sie nicht gesichert, sie steht dann in der Ausschreibung.",
  "count": 7,
  "contests": [
    {
      "key": "aa-ssb",
      "name": "All Asian DX Contest, SSB",
      "mode": "SSB",
      "rule": "erstes volles September-Wochenende",
      "url": "https://www.jarl.org/English/4_Library/A-4-3_Contests/2023AADX_rule.htm",
      "date": "2026-09-05",
      "start": "2026-09-05T00:00:00Z",
      "end": "2026-09-07T00:00:00Z",
      "allday": false
    },
    {
      "key": "iaru-fd-ssb",
      "name": "IARU Region 1 Fieldday, SSB",
      "mode": "SSB",
      "rule": "erstes volles September-Wochenende",
      "url": "https://www.darc.de/der-club/referate/conteste/",
      "date": "2026-09-05",
      "start": "2026-09-05T13:00:00Z",
      "end": "2026-09-06T12:59:00Z",
      "allday": false
    },
    "... 5 weitere"
  ]
}

DX-Kalender

GET/api/v1/dx?days=90&art=aktivitaet
GET/api/v1/dx?cont=OC,AS&dxcc=3B7,VP8
GET/api/v1/dx?iota=OC-008&belegt=2
GET/api/v1/dx/feed.ics?cont=OC&alarm=3
GET/api/v1/dx/feed.rss?dxcc=3Y

Angekündigte DX-Aktivitäten, aus drei öffentlichen Kalendern zusammengelegt. Übernommen ist nur der Termin; Land, Kontinent, CQ- und ITU-Zone leitet die Seite aus dem Rufzeichen ab. Die Beschreibung der Aktivität steht bei der Quelle, jeder Eintrag verlinkt dorthin.

Filter: cont (Kontinent, zweistellig), dxcc (Präfix der Entität), iota, call, entity, cq, itu, art (aktivitaet bis 90 Tage oder dauer), days, q, belegt (verlangt eine Mindestzahl an Quellen, die den Termin nennen), beleg (siehe unten), stufe (Seltenheit des Gebiets: sehr_selten, selten, ungewoehnlich, haeufig) und typ (dxpedition, sonder für Sonderrufzeichen oder sonstige). Mehrere Werte je Filter mit Komma. alarm setzt im Kalender-Abo eine Erinnerung so viele Tage vor Beginn.

Kalender- und Feed-Adressen brauchen keinen Zugang: ein Kalenderprogramm kann keinen Schlüssel mitschicken. Für alles andere gelten die Grundregeln oben.

Auswertungen über den Bestand

GET/api/v1/dx/bestand
GET/api/v1/dx/statistik?sortierung=selten&bis=2025
GET/api/v1/dx/verlauf?cont=OC&von=2015
GET/api/v1/dx/entitaet/3B6

Angekündigte Aktivitäten werden mitgeschrieben, dazu ist das Jahrgangsarchiv von NG3K bis 1996 zurück eingelesen. Damit lässt sich beantworten, was aus der laufenden Liste allein nicht geht: wie oft eine Entität überhaupt angekündigt war, wann zuletzt und in welchem Abstand.

statistik gruppiert je DXCC-Entität und nennt Anzahl, Jahre, erste und letzte Ankündigung, Gesamt- und Durchschnittsdauer sowie luecke_tage, den mittleren Abstand zwischen zwei Ankündigungen. Sortieren mit sortierung (anzahl, selten, zuletzt, laenge, name), filtern wie oben mit cont, dxcc, iota, art sowie von und bis als Jahreszahl. verlauf liefert dieselbe Auswahl je Jahr, entitaet alle Einzeltermine einer Entität.

Hat das wirklich stattgefunden?

Keine Ankündigungsquelle weiß das. Jede Aktivität bekommt deshalb einen Beleggrad im Feld beleg, gebildet aus drei freien Quellen: der Nutzerliste von Club Log (erstes und letztes QSO je Log), der Aktivitätsliste von LoTW und den Tagesarchiven des Reverse Beacon Network. Filtern lässt er sich überall dort, wo auch die anderen Filter greifen, Feeds und Kalender eingeschlossen.

WertBedeutung
logLog bei Club Log hochgeladen, der QSO-Zeitraum passt zur Ankündigung. Stärkster Beleg.
gehoertIm angekündigten Zeitraum nachweislich gehört. Taggenau, deckt aber nur Telegrafie und RTTY ab, solange der Beleg aus dem RBN-Archiv stammt.
ruf_bekanntDas Rufzeichen ist bei Club Log oder LoTW bekannt, für diesen Zeitraum gibt es aber kein Log. Das ist kein Beleg für diese Aktivität, sondern nur die Auskunft, dass unter dem Rufzeichen schon einmal gefunkt wurde. Typisch bei Dauerstationen, deren Sammellog über Jahre läuft.
keine_spurNichts gefunden. Das ist kein Gegenbeweis: wer nur direkt QSLt und nirgends hochlädt, hinterlässt keine dieser Spuren.
offenNoch nicht beurteilbar: liegt in der Zukunft, läuft noch, oder ist weniger als 60 Tage vorbei. Was noch nicht stattgefunden hat, kann kein Log haben. Ein positiver Beleg zählt trotzdem sofort, eine laufende Aktivität kann also schon gehoert sein.
unpruefbarDie Ankündigung nennt kein echtes Rufzeichen, sondern einen Platzhalter. Ohne Rufzeichen gibt es nichts nachzuschlagen.

Was die Zahlen sind und was nicht: gezählt sind Ankündigungen, keine bestätigten Aktivitäten. Ob eine Expedition wirklich stattgefunden hat, schreibt keine der Quellen auf. Aufgeführt wird außerdem, was für DXer interessant ist: dass Estland nur einmal auftaucht, heißt nicht, dass dort niemand funkt, sondern dass es selten Reiseziel einer angekündigten Aktivität war. Der Jahrgang 2022 fehlt bei der Quelle; /dx/bestand nennt solche Lücken ausdrücklich.

Beispielantwort GET /api/v1/dx?cont=OC&limit=2
{
  "quellenangabe": { … },
  "generated": "2026-09-01T03:40:05Z",
  "note": "Angekündigt ist nicht zugesagt: Termine verschieben sich, maßgeblich ist die Ankündigung der Expedition selbst.",
  "quellen": [
    {
      "name": "ADXO (NG3K, Bill Feidt)",
      "url": "https://www.ng3k.com/Misc/adxo.html",
      "abruf": "https://www.ng3k.com/Misc/adxo.html",
      "key": "ng3k"
    },
    {
      "name": "DX Calendar (VA3RJ)",
      "url": "https://www.qsl.net/va3rj/dx_cal.html",
      "abruf": "https://www.qsl.net/va3rj/dx_cal.html",
      "key": "va3rj"
    },
    "... 1 weitere"
  ],
  "dxcc_quelle": {
    "name": "BIG CTY (AD1C, Jim Reisert)",
    "url": "https://www.country-files.com/big-cty/",
    "lizenz": "MIT"
  },
  "kontinente": {
    "AF": "Afrika",
    "AN": "Antarktis",
    "...": "5 weitere"
  },
  "count": 31,
  "dxpeditions": [
    {
      "call": "V73HW",
      "start": "2025-03-15",
      "end": "2027-03-15",
      "tage": 731,
      "iota": "OC-028",
      "qsl": null,
      "unsicher": true,
      "quellen": [
        {
          "key": "va3rj",
          "name": "DX Calendar (VA3RJ)",
          "url": "https://www.qsl.net/va3rj/dx_cal.html"
        }
      ],
      "art": "dauer",
      "entity": "Marshall Islands",
      "dxcc": "V7",
      "cont": "OC",
      "cq": 31,
      "itu": 65,
      "lat": 9.08,
      "lon": 167.33,
      "beleg": "offen",
      "beleg_detail": "läuft noch",
      "stufe": "ungewoehnlich",
      "stufe_grund": "GDXF Most Wanted Platz 53, 62.7 % der Teilnehmer fehlt das Gebiet noch",
      "aktive_rufzeichen": 54,
      "tage_pro_jahr": 17.28,
      "gehoert_tage": 0,
      "beobachtet_tage": 2,
      "gdxf_rang": 53,
      "gdxf_prozent": 62.7,
      "zuletzt_angekuendigt": "2026-05-23",
      "typ": "dxpedition"
    },
    "... 1 weitere"
  ]
}
Beispielantwort GET /api/v1/dx/statistik?sortierung=selten&limit=2
{
  "quellenangabe": { … },
  "hinweis": "Gezählt sind Ankündigungen, keine bestätigten Aktivitäten. Die Quellen führen auf, was für DX-Betrieb angekündigt wurde; ein Land, das selten auftaucht, ist deshalb selten Reiseziel und nicht unbedingt selten in der Luft.",
  "gesamt": {
    "n": 12860,
    "entitaeten": 343,
    "von": 1996,
    "bis": 2027,
    "belegt": 3663
  },
  "count": 2,
  "entitaeten": [
    {
      "dxcc": "ES",
      "entitaet": "Estonia",
      "kontinent": "EU",
      "n": 1,
      "jahre": 1,
      "erst": "1997-06-26",
      "letzt": "1997-06-26",
      "tage_gesamt": 5,
      "tage_schnitt": 5.0,
      "belegt": 0,
      "luecke_tage": null
    },
    {
      "dxcc": "CX",
      "entitaet": "Uruguay",
      "kontinent": "SA",
      "n": 1,
      "jahre": 1,
      "erst": "1999-11-14",
      "letzt": "1999-11-14",
      "tage_gesamt": 10,
      "tage_schnitt": 10.0,
      "belegt": 0,
      "luecke_tage": null
    }
  ]
}
Beispielantwort GET /api/v1/dx/bestand
{
  "quellenangabe": { … },
  "hinweis": "Gezählt sind Ankündigungen, keine bestätigten Aktivitäten. Die Quellen führen auf, was für DX-Betrieb angekündigt wurde; ein Land, das selten auftaucht, ist deshalb selten Reiseziel und nicht unbedingt selten in der Luft.",
  "aktivitaeten": 12883,
  "von": "1996-06-16",
  "bis": "2028-01-01",
  "entitaeten": 343,
  "jahre": 31,
  "fehlende_jahrgaenge": [
    2022
  ],
  "quellen": [
    {
      "quellen": "ng3k-archiv",
      "n": 12555
    },
    {
      "quellen": "va3rj",
      "n": 223
    },
    "... 6 weitere"
  ],
  "belege": {
    "unbewertet": 2,
    "gehoert": 1856,
    "keine_spur": 5172,
    "log": 1807,
    "offen": 272,
    "ruf_bekannt": 1769,
    "unpruefbar": 2005
  },
  "hoerbelege": [
    {
      "quelle": "cluster",
      "tage": 43,
      "rufzeichen": 36
    },
    {
      "quelle": "dxcache",
      "tage": 43,
      "rufzeichen": 36
    },
    "... 1 weitere"
  ],
  "beleg_stufen": {
    "log": "Log bei Club Log hochgeladen, QSO-Zeitraum überlappt die Ankündigung",
    "gehoert": "im angekündigten Zeitraum nachweislich gehört (RBN oder Cluster)",
    "...": "4 weitere"
  }
}

/dx/spots filtert zusätzlich mit quelle (cluster, dxcache, rbn, kommagetrennt kombinierbar). Ein RBN-Spot trägt zusätzlich snr_db (Signal-Rausch-Abstand) und wpm (Tempo, bei RTTY/PSK das BPS-Äquivalent) - bei einem Clusterspot sind beide null. Anzeige mit Filtern, Entfernung und Peilung unter /rbn, wie beim DX-Cluster.

Beispielantwort GET /api/v1/dx/spots?minuten=240&limit=2
{
  "quellenangabe": { … },
  "count": 2,
  "fenster_minuten": 240,
  "bestand": {
    "n": 14944,
    "von": "2026-08-31T07:41:33Z",
    "bis": "2026-09-01T08:02:12Z"
  },
  "stufen": {
    "sehr_selten": "sehr selten, kaum eine Funkstelle vor Ort",
    "selten": "selten, nur wenige Funkstellen vor Ort",
    "ungewoehnlich": "ungewöhnlich, überschaubar viele Funkstellen",
    "haeufig": "häufig"
  },
  "hinweis_modus": "`modus` steht so im Spot. `modus_vermutet` ist aus der Frequenz abgeleitet und nur eine Schätzung.",
  "spots": [
    {
      "zeit": "2026-09-01T08:02:12Z",
      "call": "HB9XXX",
      "freq_khz": 7075.0,
      "band": "40m",
      "modus": null,
      "spotter": "DL1XXX",
      "bemerkung": "POTA CH-0219 tnx p2p DE-0531",
      "quelle": "cluster",
      "dxcc": "HB",
      "entitaet": "Switzerland",
      "kontinent": "EU",
      "cq": 14,
      "itu": 28,
      "lat": 46.87,
      "lon": 8.12,
      "snr_db": null,
      "wpm": null,
      "stufe": "haeufig",
      "stufe_grund": "nicht in den GDXF-Top-150; Betrieb vor Ort; Mitschnitt läuft erst 2 Tage und zählt noch nicht mit",
      "gdxf_rang": null,
      "gdxf_prozent": null,
      "aktive_rufzeichen": 1741,
      "tage_pro_jahr": 0.55,
      "gehoert_tage": 1,
      "beobachtet_tage": 2,
      "zuletzt_angekuendigt": "2001-04-24",
      "ank_start": null,
      "ank_ende": null,
      "ank_iota": null,
      "beleg": null,
      "modus_vermutet": "FT8"
    },
    "... 1 weitere"
  ]
}

Wer hört mich: Reverse Beacon Network und PSK Reporter

GET/api/v1/dx/gehoert/DL1ABC?minuten=1440
GET/api/v1/dx/gehoert/DL1ABC?quelle=psk&modus=FT8&band=20m
GET/api/v1/dx/rbn/DL1ABC
GET/api/v1/dx/rbn/DL1ABC?minuten=1440&band=20m,40m&modus=CW

Alle RBN-Meldungen zu einem Rufzeichen im Zeitraum (minuten, 5 bis 2880, Vorgabe 60), auch mit Zusatz dahinter wie /P. skimmer fasst je Skimmer zusammen: Zahl der Meldungen, bestes und mittleres Signal, Bänder, erste und letzte Meldung, dazu der Standort aus der Skimmerliste des RBN (locator, lat, lon). Steht ein Skimmer nicht in der Liste, ist genau false und der Standort die Mitte seines Landes. je_band zählt ohne den Bandfilter, spots sind die letzten Einzelmeldungen (limit, höchstens 1000). Aufgehoben werden die Meldungen zwei Tage. Anzeige mit Karte unter /rbn.

/dx/gehoert führt drei Quellen zusammen (quelle, kommagetrennt, Vorgabe alle): rbn (RBN, CW und RTTY), rbndigi (RBN, FT8 und FT4) und psk (PSK Reporter). Statt skimmer heißt die Liste empfaenger, je Empfänger mit quellen, modi und Standort (beim PSK Reporter aus dem Locator des Empfängers). psk sagt, woher der PSK-Anteil kommt: mitschnitt für Rufzeichen aus DE, AT, CH, LI und LU (eigener Mitschnitt, 48 Stunden), abfrage für alle anderen (beim PSK Reporter nachgefragt, 24 Stunden, bis fünf Minuten alt). Die dB-Werte von CW und FT8 sind nicht vergleichbar, sie beziehen sich auf verschiedene Bandbreiten. wolke fasst je Empfänger, Band und Betriebsart zusammen, als Liste [Empfänger, Band, Betriebsart, bestes dB, mittleres dB, Meldungen], höchstens 5000 Zeilen; daraus zeichnet /rbn das Signal über der Entfernung. Mit stumm=1 kommt nicht_gehoert dazu: die Empfänger, die im Zeitraum auf denselben Bändern und Betriebsarten andere gemeldet haben, dieses Rufzeichen aber nicht, auf 0,2 Grad zusammengefasst als [lat, lon, Zahl, genau, digital] (digital 0: CW und RTTY). Gezählt wird auf die Stunde genau; beim PSK Reporter kennt der eigene Mitschnitt nur Empfänger, die Sender aus DACH hören.

Funkbetrieb im Ausland

GET/api/v1/ausland
GET/api/v1/ausland?klasse=e&moeglich=true
GET/api/v1/ausland?land=spanien
GET/api/v1/ausland?region=2
GET/api/v1/ausland?rufzeichen=HB9XYZ

rufzeichen löst ein gehörtes Rufzeichen über die Rufzeichenserien der ITU zu genau einem Land auf und gibt die Serie mit zurück. Ein festes Paar schlägt dabei ein einzelnes Zeichen, sonst landete K3… bei jedem K-Land statt bei den USA. Findet sich keine Serie, kommt 404.

Alle Länder der Welt mit der Frage, ob eine deutsche Klasse A, E oder N dort Betrieb erlaubt. Eine Gastlizenz zählt bei moeglich=true als möglich, sie muss nur vorher beantragt werden. Jeder Eintrag führt außerdem die ITU-Region, die Rufzeichenserie der ITU, die Zeitzonen und den Mittelpunkt des Landes, dazu die Adressen des Landesverbands und der zuständigen Verwaltung. Woher jede dieser Angaben stammt, steht in quellen und sachquellen der Antwort.

Beispielantwort GET /api/v1/ausland?rufzeichen=HB9XYZ
{
  "quellenangabe": { … },
  "generated": "2026-09-01T04:07:01Z",
  "rufzeichen": "HB9XYZ",
  "serie": "HB",
  "quellen": {
    "cept": {
      "name": "CEPT-Empfehlung T/R 61-01",
      "ausgabe": "Ausgabe 18. Oktober 2024",
      "url": "https://docdb.cept.org/Docs/doc98/official/pdf/TR6101.PDF"
    },
    "umsetzung_a": {
      "name": "ECO, Umsetzungsstand T/R 61-01",
      "ausgabe": "abgerufen am 24.08.2026",
      "url": "https://docdb.cept.org/implementation/925"
    },
    "...": "3 weitere"
  },
  "sachquellen": [
    {
      "feld": "Mittelpunkt, Entfernung, Peilung",
      "name": "Google Public Data, countries.csv (dspl)",
      "url": "https://github.com/google/dspl/blob/master/samples/google/canonical/countries.csv"
    },
    {
      "feld": "Rufzeichenserie",
      "name": "ITU, Anhang 42 der Vollzugsordnung für den Funkdienst, über die Wikipedia-Aufstellung „ITU prefix“",
      "url": "https://en.wikipedia.org/wiki/ITU_prefix"
    },
    "... 2 weitere"
  ],
  "count": 1,
  "laender": [
    {
      "code": "CH",
      "land": "Schweiz",
      "a": "cept",
      "e": "ja",
      "n": "nein",
      "praefix_cept": "HB9",
      "hinweis": "Klasse A laut CEPT-Datenbank umgesetzt, Stand 01.09.2009. Klasse E laut CEPT-Datenbank umgesetzt, Stand 01.09.2009.",
      "links": [
        {
          "titel": "Union Schweizerischer Kurzwellen-Amateure [USKA]",
          "url": "http://www.uska.ch"
        }
      ],
      "koord": [
        46.8182,
        8.2275
      ],
      "itu_region": 1,
      "praefixe": [
        "HB",
        "HE"
      ],
      "zonen": [
        "Europe/Zurich"
      ]
    }
  ]
}

Funkwetter

GET/api/v1/funkwetter
GET/api/v1/funkwetter?kurz=1
GET/api/v1/funkwetter/offen?von=dl
GET/api/v1/funkwetter/sonde/JR055

Was die Seite /funkwetter zeigt, alle 15 Minuten neu gerechnet: kopf mit SFI, Flecken, A, Kp, Röntgenklasse, Sonnenwind, Bz, MUF und foEs über DL; lage als ein Satz; baender je KW-Band mit tag, nacht und jetzt (gut, mittel, schlecht, zu); vhf mit Sporadic-E je Band und Aurora; karte mit dem MUF-Gitter (4°, MHz × 10, Mitte der ersten Zelle in lat0/lon0), der Messdichte je Zelle (0 bis 9) und den Isolinien als GeoJSON; sonden mit dem letzten sicheren Wert jeder Ionosonde und ihrem Betreiber; dazu die Reihen von Kp, Röntgen, Sonnenwind, D-RAP und Polarlicht. verlauf ist der stündliche Stand der letzten tage (Vorgabe 30). Mit kurz=1 nur Kopf, Lage und Bänder.

/funkwetter/offen zählt, wie viele Empfänger von RBN und PSK Reporter in den letzten 30 Minuten Sender aus DL (von=dl) oder Europa (von=eu) gehört haben, je Band und Kontinent. /funkwetter/sonde/{URSI} liefert die Werte einer Ionosonde über 48 Stunden als [t, CS, foF2, foEs, MUF(3000)].

Wer die Ionosondenwerte weitergibt, nennt GIRO (Reinisch und Galkin 2011) und den Betreiber der Sonde; die Werte stehen unter CC BY-NC-SA 4.0, also nicht für kommerzielle Zwecke. Die Bilder zum Einbauen (/funkwetter/bild/baender.png, muf.png, banner.png, auch als .svg, mit ?thema=dunkel) brauchen keinen Zugang.

Beispielantwort GET /api/v1/funkwetter/offen?von=dl (gekürzt)
{
  "quellenangabe": { … },
  "baender": ["160m", "80m", "…", "2m"],
  "kontinente": ["EU", "NA", "SA", "AS", "AF", "OC"],
  "matrix": {
    "20m": {
      "NA": { "empf": 41, "meldungen": 512, "snr": 31 },
      "AS": { "empf": 12, "meldungen": 64, "snr": 22 }
    }
  },
  "sender": 119,
  "minuten": 30,
  "von": "dl",
  "stand": "2026-10-07T11:00:00Z"
}

Portabel

GET/api/v1/spots?near=JO50HB&km=25
GET/api/v1/spots?near=50.07,10.67&km=50&type=sota
GET/api/v1/solar
Beispielantwort GET /api/v1/spots?near=JO50HB&km=25&limit=2
{
  "quellenangabe": { … },
  "generated": "2026-09-01T04:07:01Z",
  "count": 10,
  "spots": [
    {
      "type": "pota",
      "ref": "DE-0581",
      "name": "Hohe Wann Nature Reserve",
      "lat": 50.0366,
      "lon": 10.5747,
      "distance_km": 4.6,
      "bearing_deg": 231
    },
    "... 1 weitere"
  ]
}
Beispielantwort GET /api/v1/solar
{
  "quellenangabe": { … },
  "generated": "2026-10-07T11:00:00Z",
  "source": {
    "name": "afu.tools Funkwetter (NOAA SWPC, GFZ Potsdam, GIRO)",
    "url": "https://afu.tools/funkwetter"
  },
  "data": {
    "source": "afu.tools",
    "updated": "07 Oct 2026 1100 GMT",
    "solarflux": "113",
    "aindex": "6",
    "kindex": "0",
    "kindexnt": "",
    "xray": "B8.6",
    "sunspots": "77",
    "aurora": "30",
    "solarwind": "357.0",
    "magneticfield": "0.6",
    "geomagfield": "sehr ruhig",
    "signalnoise": "S0-S1",
    "fof2": "7.075",
    "muffactor": "",
    "muf": "25.4"
  },
  "hf": [
    {
      "band": "80m-40m",
      "time": "day",
      "condition": "Fair"
    },
    {
      "band": "30m-20m",
      "time": "day",
      "condition": "Good"
    },
    {
      "band": "17m-15m",
      "time": "day",
      "condition": "Fair"
    },
    {
      "band": "12m-10m",
      "time": "day",
      "condition": "Poor"
    },
    {
      "band": "80m-40m",
      "time": "night",
      "condition": "Good"
    },
    {
      "band": "30m-20m",
      "time": "night",
      "condition": "Poor"
    },
    {
      "band": "17m-15m",
      "time": "night",
      "condition": "Poor"
    },
    {
      "band": "12m-10m",
      "time": "night",
      "condition": "Poor"
    }
  ],
  "vhf": [
    {
      "name": "vhf-aurora",
      "location": "northern_hemi",
      "value": "High LAT AUR"
    },
    {
      "name": "E-Skip",
      "location": "europe",
      "value": "Band Closed"
    },
    {
      "name": "E-Skip",
      "location": "north_america",
      "value": "Band Closed"
    },
    {
      "name": "E-Skip",
      "location": "europe_6m",
      "value": "Band Closed"
    },
    {
      "name": "E-Skip",
      "location": "europe_4m",
      "value": "Band Closed"
    }
  ]
}

Anlaufstellen

GET/api/v1/anlaufstellen
GET/api/v1/anlaufstellen?band=20m
GET/api/v1/anlaufstellen?art=digital

Die eingebürgerten Treffpunkte je Betriebsart: FT8, FT4, JS8, WSPR, PSK31, RTTY, SSTV, die Anruffrequenzen, APRS, DAPNET, die Notfunk-Sammelfrequenzen und die IBP-Baken. Angegeben ist die Einstellfrequenz in oberem Seitenband. Mit band kommt die Sicht eines Bandes zurück, nach Frequenz sortiert. Aufgenommen ist nur, was in Deutschland auch im Band liegt.

Beispielantwort GET /api/v1/anlaufstellen?band=20m
{
  "quellenangabe": { … },
  "generated": "2026-09-01T04:07:01Z",
  "band": "20m",
  "hinweis": "Einstellfrequenz (Dial) in oberem Seitenband. Eingebürgerte Treffpunkte, keine Vorschrift, verbindlich ist der Bandplan.",
  "quellen": [
    {
      "feld": "FT8, FT4, WSPR",
      "name": "Vorgabefrequenzen von WSJT-X",
      "url": "https://wsjt.sourceforge.io/"
    },
    {
      "feld": "JS8",
      "name": "Vorgabefrequenzen von JS8Call",
      "url": "http://js8call.com/"
    },
    "... 3 weitere"
  ],
  "anlaufstellen": [
    {
      "key": "cw",
      "name": "CW-QRP",
      "art": "telegrafie",
      "wert": 14.06
    },
    {
      "key": "psk",
      "name": "PSK31",
      "art": "digital",
      "wert": 14.07
    },
    {
      "key": "ft8",
      "name": "FT8",
      "art": "digital",
      "wert": 14.074
    },
    "... 7 weitere"
  ]
}

Präfix und DXCC

GET/api/v1/dxcc/VK6
GET/api/v1/dxcc/9M6%2FLA6VM
GET/api/v1/dxcc?cont=OC
GET/api/v1/dxcc?q=island

Gebiet, Kontinent, CQ- und ITU-Zone sowie der Mittelpunkt zu einem Rufzeichen oder Präfix. rule sagt, wie zugeordnet wurde: ausnahme für einen Eintrag in der Ausnahmeliste, praefix für die Präfixregel. Grundlage ist die Länderdatei BIG CTY (MIT-Lizenz), dieselbe, mit der DX-Kalender und Cluster arbeiten.

Beispielantwort GET /api/v1/dxcc/VK6
{
  "quellenangabe": { … },
  "query": "VK6",
  "match": "VK6",
  "rule": "praefix",
  "entity": {
    "name": "Australia",
    "praefix": "VK",
    "kontinent": "OC",
    "cq": 30,
    "itu": 59,
    "lat": -23.7,
    "lon": 132.33
  },
  "continent": "Ozeanien",
  "prefixes": [
    "AX",
    "AX4",
    "AX6",
    "AX8",
    "... 16 weitere"
  ],
  "source": {
    "name": "BIG CTY (AD1C, Jim Reisert)",
    "url": "https://www.country-files.com/big-cty/",
    "lizenz": "MIT"
  }
}

Satelliten

GET/api/v1/tle
GET/api/v1/tle?funk=true

Bahndaten der Amateurfunksatelliten, wie CelesTrak sie führt, dazu bei den bekannten Satelliten die Frequenzen und Betriebsarten. epoche nennt den Zeitpunkt der Bahnelemente, daran hängt die Genauigkeit jeder Vorhersage. Die Überflüge selbst rechnet die Satellitenseite im Browser; der Standort geht dafür nicht über die Leitung.

Beispielantwort GET /api/v1/tle?funk=true
{
  "quellenangabe": { … },
  "generated": "2026-09-01T02:15:02Z",
  "quelle": {
    "name": "CelesTrak",
    "url": "https://celestrak.org/",
    "lizenz": "frei nutzbar, Nennung erbeten"
  },
  "status_quelle": {
    "name": "AMSAT-NA, Satellitenstatus",
    "url": "https://www.amsat.org/status/"
  },
  "hinweis": "Bahndaten altern: nach einer Woche liegt die Vorhersage schon Minuten daneben. Betriebszustand der Satelliten steht bei AMSAT.",
  "count": 8,
  "satelliten": [
    {
      "norad": 7530,
      "name": "OSCAR 7",
      "kuerzel": "AO-7",
      "epoche": "2026-08-31T13:34:27Z",
      "tle1": "1 07530U 74089B   26243.56559926 -.00000046  00000+0  60356-6 0  9993",
      "tle2": "2 07530 101.9921 257.6005 0012190 349.2633 134.3126 12.53699388369965",
      "funk": [
        {
          "art": "Mode A, linear",
          "up_von": 145.85,
          "up_bis": 145.95,
          "down_von": 29.4,
          "down_bis": 29.5
        },
        {
          "art": "Mode B, linear invertierend",
          "up_von": 432.125,
          "up_bis": 432.175,
          "down_von": 145.925,
          "down_bis": 145.975
        }
      ],
      "hinweis": "Ältester noch benutzter Amateurfunksatellit. Er läuft ohne Akku allein am Sonnenlicht und wechselt die Betriebsart selbsttätig.",
      "geostationaer": false
    },
    "... 7 weitere"
  ]
}

Sichtlinie

GET/api/v1/sichtlinie?von=JO50HB&nach=JO50WB
GET/api/v1/sichtlinie?von=50.07,10.67&nach=JO60&hoehe_von=12&hoehe_nach=40&mhz=439

Geländeschnitt zwischen zwei Punkten mit Urteil: frei, knapp oder verdeckt. Gerechnet wird mit dem Höhenmodell des Bundes (DGM200, Gitterweite 200 m), dem wirksamen Erdradius (Faktor 4/3) und der ersten Fresnelzone; anteil_fresnel nennt, wie viel davon frei bleibt, zusaetzliche_hoehe_m, wie viel Höhe am Startpunkt fehlt. Deckt Deutschland ab, höchstens 400 km.

Beispielantwort GET /api/v1/sichtlinie?von=JO50HB&nach=JO50WB&hoehe_von=10&hoehe_nach=30
{
  "quellenangabe": { … },
  "von": {
    "lat": 50.0625,
    "lon": 10.625,
    "locator": "JO50hb"
  },
  "nach": {
    "lat": 50.0625,
    "lon": 11.875,
    "locator": "JO50wb"
  },
  "moeglich": true,
  "urteil": "verdeckt",
  "text": "Das Gelände steht in der Sichtlinie. Ohne Umweg über ein Relais oder mehr Höhe geht da nichts.",
  "strecke_km": 89.23,
  "anteil_fresnel": -1.0,
  "engster_punkt": {
    "km": 88.529,
    "hoehe": 890.6,
    "sicht": 782.1,
    "luft": -108.5,
    "fresnel": 37.8
  },
  "hoehe_start_m": 412.2,
  "hoehe_ziel_m": 758.6,
  "antenne_start_m": 10.0,
  "antenne_ziel_m": 30.0,
  "mhz": 145.0,
  "zusaetzliche_hoehe_m": 13181.4,
  "ohne_daten_punkte": 0,
  "k_faktor": 1.3333333333333333,
  "profil": [
    {
      "km": 0.0,
      "hoehe": 412.2,
      "sicht": 422.2,
      "luft": 10.0,
      "fresnel": 0.0
    },
    {
      "km": 0.349,
      "hoehe": 395.1,
      "sicht": 421.8,
      "luft": 26.7,
      "fresnel": 26.8
    },
    "... 255 weitere"
  ],
  "quelle": {
    "name": "DGM200, Bundesamt für Kartographie und Geodäsie",
    "url": "https://gdz.bkg.bund.de/index.php/default/digitale-geodaten/digitale-gelandemodelle/digitales-gelandemodell-gitterweite-200-m-dgm200.html",
    "lizenz": "GeoNutzV, Quellenvermerk © GeoBasis-DE / BKG",
    "vermerk": "© GeoBasis-DE / BKG",
    "stand": "Stand 31.12.2019"
  }
}

Rufzeichen

GET/api/v1/callsign/DL1XXX
GET/api/v1/callsigns?prefix=DL1
GET/api/v1/callsign/frei?muster=DL1A??
GET/api/v1/callsign/frei/plan?suffix=MH&zweck=PZ&klasse=E
GET/api/v1/rufzeichenplan
GET/api/v1/rufzeichenplan/einordnen?call=DO0ABC
GET/api/v1/qth?rufe=DL1ABC,K1ABC

Ausgegeben werden Rufzeichen, Inhaber, Klasse, der in der amtlichen Liste genannte Ort und die Quellen. Anschriften, Koordinaten und Locator gibt die API aus der Rufzeichenliste nicht heraus. Eine Suche nach Namen und einen vollständigen Abzug gibt es nicht.

qth nennt zu bis zu 100 Rufzeichen den Locator, den die Station selbst an PSK Reporter gemeldet hat oder mit dem sie in der Skimmerliste des RBN steht, mit Quelle (psk, rbn) und Alter in Tagen; angemeldet zusätzlich den aus deinem letzten QSO mit ihr (log, wavelog). Die FT8-, FT4- und JS8-Seiten nutzen das für Entfernung und die Farbe „New Grid“.

callsign/frei beantwortet die Frage vor dem Antrag auf ein Wunschrufzeichen: Welche eines Musters stehen nicht in der Liste? ? steht für einen Buchstaben oder eine Ziffer, # nur für eine Ziffer. Geprüft werden nur deutsche Rufzeichen (DA bis DR, eine Ziffer, ein bis drei Buchstaben): D??MH bringt DA0MH bis DR9MH. Der Anfang muss feststehen, höchstens 1296 Möglichkeiten. Zurück kommen nur die nicht gelisteten Rufzeichen und ein paar Zahlen, wer vergeben ist, wird nicht aufgezählt. Und nicht gelistet heißt nicht zu haben: Zurückgegebene Rufzeichen bleiben eine Weile gesperrt, zugeteilt wird auf Antrag.

rufzeichenplan liefert den Rufzeichenplan der Bundesnetzagentur (Auszug aus Vfg. 15/2025, gültig ab 01.04.2025) als JSON: je Reihe (DA0 bis DR9 ohne DE und DI) und Suffixart (lang: 2 oder 3 Buchstaben, ein: 1 Buchstabe, sonder: 4 bis 7 Zeichen) die Zwecke (PZ, KS, RL, FB, SZ, AB, KSB, KSO), die auslaufenden Zwecke, die Klasse und ob die Reihe heute noch neu vergeben wird (neu), dazu Anlässe, Befristungen, Zusätze, unzulässige Suffixe und unter bestand die Zahl der Rufzeichen je Reihe, Suffixlänge und Liste aus der neuesten Rufzeichenliste. rufzeichenplan/einordnen rechnet ein Rufzeichen ein, ohne Inhaber: Reihe, Zweck, Klasse, Hinweise, Fehler (nicht im Plan, unzulässiges Suffix, falsche Reihenfolge der Zusätze wie /pT), auch Kurzzeitzulassungen (DL/PA3XYZ) und Peilsender-Kennungen.

callsign/frei/plan prüft ein Wunsch-Suffix in allen Reihen, die zu zweck (PZ, KS, SONDER, RL, SZ, KSB, KSO), klasse (A, E, N) und optional laenge (1, 2, 3, 4-7) passen; mit auslaufend=true und exterritorial=true auch diese Reihen. Zurück kommen wie bei callsign/frei nur die nicht gelisteten Rufzeichen und Zahlen; Suffixe mit Not- oder Q-Gruppen (Nr. 7 des Plans) werden gar nicht erst geprüft.

Beispielantwort GET /api/v1/callsign/DL1XXX
{
  "quellenangabe": { … },
  "callsign": "DL1XXX",
  "scope": "public",
  "operator": {
    "callsign": "DL1XXX",
    "personalCallSign": null,
    "license": "A",
    "owner": "Vorname Nachname",
    "residence": "Musterstadt",
    "sources": [
      "bnetza-pdf"
    ],
    "lastFetched": "2026-08-27T04:00:46",
    "bnetzaListNumber": 12345
  },
  "sdok": null,
  "source": {
    "name": "Bundesnetzagentur, Amateurfunk-Rufzeichenliste",
    "note": "Anschrift, Koordinaten und Locator sind nicht oeffentlich."
  }
}
Beispielantwort GET /api/v1/callsign/frei?muster=D??MH
{
  "quellenangabe": { … },
  "muster": "D??MH",
  "geprueft": 180,
  "vergeben": 93,
  "frueher_vergeben": 14,
  "frei": [
    "DA0MH",
    "DA2MH",
    "DA3MH",
    "DA4MH",
    "... 69 weitere"
  ],
  "count": 73,
  "hinweis": "Nicht gelistet heißt nicht zu haben: Zurückgegebene Rufzeichen bleiben eine Zeit lang gesperrt, und über die Zuteilung entscheidet allein die Bundesnetzagentur.",
  "source": {
    "name": "Amateurfunk-Rufzeichenliste der Bundesnetzagentur",
    "url": "https://www.bundesnetzagentur.de/DE/Fachthemen/Telekommunikation/Frequenzen/SpezielleAnwendungen/Amateurfunk/start.html"
  }
}

Orte und Ortsverbände

GET/api/v1/ort?q=Haßfurt
GET/api/v1/ort?q=97437
GET/api/v1/ort?q=DM/BM-002
GET/api/v1/ort?q=B/DL-0001
GET/api/v1/ov?near=JO50hb

ort übersetzt einen Ortsnamen oder eine Postleitzahl in Koordinaten und Locator, immer genau ein Ergebnis. Gibt es den Namen mehrfach, gewinnt der größere Ort, und die Antwort nennt mit label, welcher es war. Eine Referenz eines Programms, das einen Punkt im Gelände meint, gibt diesen Punkt zurück: SOTA-Gipfel (DM/BM-002), Bunker (BOTA, B/DL-0001) und Burgen (WCA DL-00001 oder COTA BBN-001), mit programm und referenz in Normalform. Gipfel außerhalb des deutschsprachigen Raums und der Nachbarländer fragt der Server bei SOTA nach; Bunker und Burgen gibt es nur, soweit die xOTA-Karte sie führt. Parks (POTA, WWFF) sind Flächen und deshalb kein Standort. Dasselbe gilt überall, wo ein Parameter einen Standort nimmt (near und Co.).

ov nennt den nächstgelegenen Ortsverband zu einem Standort. near nimmt Locator, Koordinaten oder einen Ortsnamen. Das ist keine amtliche Zuständigkeit: Ortsverbände haben keine Grenzen, ein DOK ist eine Kennung und kein Gebiet.

Beispielantwort GET /api/v1/ort?q=Haßfurt
{
  "quellenangabe": { … },
  "name": "Haßfurt",
  "land": "Bayern",
  "label": "Haßfurt (Bayern)",
  "lat": 50.0352,
  "lon": 10.5156,
  "locator": "JO50ga",
  "einwohner": 13562,
  "quelle": {
    "name": "GeoNames, Ortsverzeichnis und Postleitzahlen Deutschland",
    "url": "https://www.geonames.org/",
    "lizenz": "CC BY 4.0"
  }
}
Beispielantwort GET /api/v1/ov?near=JO50hb
{
  "quellenangabe": { … },
  "dok": "B37",
  "name": "Hassberge",
  "ort": "Hassberge",
  "plz": "96126",
  "distanz_km": 15.0,
  "distrikt": "B",
  "link": "https://www.darc.de/der-club/distrikte/b/ortsverbaende/37/",
  "hinweis": "Der nächstgelegene Ortsverband, keine amtliche Zuständigkeit. Ortsverbände haben keine Grenzen.",
  "quelle": {
    "name": "DARC, Ortsverbandssuche auf darc.de",
    "url": "https://www.darc.de/home/",
    "hinweis": "Postleitzahl je Ortsverband aus der Suche, Koordinaten daraus über GeoNames"
  }
}

Rechnen und Zustand

GET/api/v1/locator?lat=50.07&lon=10.67
GET/api/v1/locator?locator=JO50HB
GET/api/v1/distance?from=JO50HB&to=JN47
GET/api/v1/health
GET/api/v1/stats
Beispielantwort GET /api/v1/locator?lat=50.07&lon=10.67
{
  "quellenangabe": { … },
  "lat": 50.07,
  "lon": 10.67,
  "locator": "JO50ib",
  "locator4": "JO50"
}
Beispielantwort GET /api/v1/distance?from=JO50HB&to=JN47
{
  "quellenangabe": { … },
  "from": {
    "lat": 50.0625,
    "lon": 10.625,
    "locator": "JO50hb"
  },
  "to": {
    "lat": 47.5,
    "lon": 9.0,
    "locator": "JN47mm"
  },
  "distance_km": 308.8,
  "bearing_deg": 203.3,
  "bearing_back_deg": 22.1
}
Beispielantwort GET /api/v1/health
{
  "quellenangabe": { … },
  "ok": true,
  "snapshots": "2026-09-01T08:01:15Z",
  "last_run": [
    "quellen"
  ],
  "tasks": {
    "bands": "2026-09-01T04:07:01Z",
    "repeaters": "2026-09-01T04:07:01Z",
    "stats": "2026-09-01T04:07:01Z",
    "...": "18 weitere"
  }
}
Beispielantwort GET /api/v1/stats
{
  "quellenangabe": { … },
  "generated": "2026-09-01T04:07:01Z",
  "counts": {
    "operators": 70098,
    "ovs": 1019,
    "sdok": 6243,
    "exams_upcoming": 49,
    "exams_free": 26,
    "repeaters": 2626
  },
  "licences": {
    "A": 58684,
    "E": 10219,
    "N": 1130
  },
  "sync": [
    {
      "key": "bnetza-pdf:lastImportedAt",
      "value": "2026-08-27T04:00:53.987Z",
      "updatedAt": "2026-08-27 04:00:53.989532"
    },
    {
      "key": "bnetza-pdf:lastModified",
      "value": "Wed, 26 Aug 2026 13:56:09 GMT",
      "updatedAt": "2026-08-27 04:00:53.977718"
    },
    "... 6 weitere"
  ]
}

Beispiel

$ curl -s 'https://afu.tools/api/v1/frequency/145.500' | jq '.band, .allocation.classes'
"2m"
{
  "A": { "value": 750, "unit": "PEP" },
  "E": { "value": 75,  "unit": "PEP" },
  "N": { "value": 6.1, "unit": "ERP" }
}

Woher die Daten kommen

Vollständig, mit Nutzungsbedingung und dem Zeitpunkt des letzten Abrufs, steht das auf der Seite Quellen. Hier die Kurzfassung.

BereichQuelleAuffrischung
Frequenzen und Leistung Anlage 1 der Amateurfunkverordnungbei Änderung
BandsegmenteIARU Region 1selten
Relaisfm-funknetz.de, repeatermap.de alle sechs Stunden
RufzeichenplanBundesnetzagentur, Vfg. 15/2025 (amtliches Werk) von Hand, Änderung wird wöchentlich geprüft
Rufzeichen Rufzeichenliste der Bundesnetzagentur, ergänzt um QRZ.com nächtlich
DOK und OrtsverbändeDARCnächtlich
PrüfungstermineBundesnetzagenturnächtlich
POTA und SOTA POTA, SOTA, Flächen aus OSM, BfN und EEAtäglich
Funkwetter und Ausbreitung NOAA SWPC (gemeinfrei), GFZ Potsdam (Kp, CC BY 4.0), Ionosonden bei GIRO (CC BY-NC-SA 4.0), Bewertung von afu.toolsalle 15 Minuten
Anlaufstellen Vorgaben von WSJT-X und JS8Call, Bandplan der IARU Region 1 bei Änderung
DXCC-ZuordnungBIG CTY (AD1C), MIT-Lizenz monatlich
Bahndaten der SatellitenCelesTrak zweimal täglich
Höhenmodell DGM200, © GeoBasis-DE / BKGvierteljährlich geprüft
Orte, Postleitzahlen, Locator GeoNames (CC BY 4.0) von Hand
Kartenkacheln © OpenStreetMap-Mitwirkende (ODbL), über den Server dieser Seite geladenlaufend
ContestkalenderAusschreibungen der Veranstalter berechnet
DX-Ankündigungen ADXO (NG3K), DX Calendar (VA3RJ), 425 DX News. Übernommen sind nur die Termine, die Texte bleiben bei der Quelle. zweimal täglich
DX-Archiv seit 1996 ADXO-Jahrgänge (NG3K). Nur Termine; 2022 fehlt bei der Quelle. einmalig eingelesen
Belege, ob eine Aktivität stattfand Club Log und ARRL LoTW (öffentliche Nutzerlisten), Reverse Beacon Network (Tagesarchive ab 2009, nur CW und RTTY) nächtlich
Seltenheit eines Gebiets Most Wanted der German DX Foundation, aus dem DARC-DXCC-Scoreboard (erste 150 Gebiete). Darunter eigene Schätzung. nächtlich
DXCC-Entität, Kontinent, Zonen BIG CTY (AD1C, Jim Reisert), MIT-Lizenzmonatlich

Die API ist ein Nebenprodukt dieser Seite und keine zugesicherte Leistung. Wer sie in etwas einbaut, das laufen muss, sollte Antworten zwischenspeichern und mit Ausfällen rechnen. Bei Fragen oder wenn eine Datenquelle fehlt: Kontakt.