API REST CloudTAK przekształca serwer TAK z pasywnego przekaźnika w aktywne centrum integracji. Zamiast wymagać, aby każde źródło danych obsługiwało natywny CoT przez TCP/TLS — jedyną ścieżkę do starszego TAK Server — CloudTAK udostępnia pełną powierzchnię HTTP i WebSocket, którą może wywołać każdy nowoczesny system: tablice sensorów, platformy logistyczne, potoki wnioskowania AI, kanały SIGINT i niestandardowe pulpity nawigacyjne. Ten przewodnik szczegółowo omawia wszystkie główne powierzchnie API: uwierzytelnianie, wstrzykiwanie CoT, strumieniowanie śladów w czasie rzeczywistym, zarządzanie misjami, przesyłanie pakietów danych, administrację grupami, webhooki oraz AI copilot TAKpilot jako przykład integracji. Jeśli najpierw musisz uruchomić serwer CloudTAK, zapoznaj się z naszym przewodnikiem wdrożenia serwera CloudTAK.

Uwierzytelnianie: tokeny JWT, klucze API i zakresy

API REST CloudTAK wymusza uwierzytelnianie na każdym punkcie końcowym z wyjątkiem sprawdzenia kondycji (GET /api/health). Obsługiwane są dwa typy poświadczeń, oba przekazywane jako nagłówek HTTP Authorization: Bearer <token>.

Tokeny JWT

Tokeny JWT są krótkotrwałe i wydawane dla każdej sesji użytkownika. Uzyskaj token, wysyłając poświadczenia do punktu końcowego logowania:

curl -s -X POST https://tak.yourdomain.com:8443/api/login \
  -H "Content-Type: application/json" \
  -d '{"username": "operator01", "password": "s3cur3p@ss"}' \
  | jq -r '.token'

Domyślny TTL to 86400 sekund (24 godziny); konfigurowalny przez CLOUDTAK_JWT_TTL. Tokeny JWT zawierają rolę użytkownika i członkostwo w grupach jako roszczenia, więc sprawdzanie uprawnień jest bezstanowe.

Klucze API

Klucze API są długowiecznymi tokenami odpowiednimi dla zautomatyzowanych integracji usługa-do-usługi. Generuj je przez API administratora:

curl -s -X POST https://tak.yourdomain.com:8443/api/token \
  -H "Authorization: Bearer $ADMIN_JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "sensor-array-east",
    "scopes": ["cot:write"],
    "rateLimit": 500
  }' | jq -r '.token'

Obsługiwane zakresy i do czego dają dostęp:

Zakres Daje dostęp do
cot:write Wstrzykiwanie zdarzeń CoT przez POST /api/cot
cot:read Zapytanie o historyczne ślady przez GET /api/cot
events:subscribe Połączenie ze strumieniem WebSocket na /api/ws
mission:write Tworzenie, aktualizowanie i usuwanie misji
package:write Przesyłanie pakietów danych i załączników
group:write Tworzenie grup i zarządzanie członkostwem
admin Wszystkie zakresy plus zarządzanie użytkownikami i konfiguracja serwera

Odwołaj klucz w dowolnym momencie: DELETE /api/token/{id}. Wylistuj aktywne klucze przez GET /api/token.

Bazowy URL i limity szybkości

Wszystkie punkty końcowe REST są obsługiwane pod adresem https://<host>:8443/api/. Domyślny globalny limit szybkości to 100 żądań na sekundę na klucz API. Odpowiedzi HTTP 429 zawierają nagłówek Retry-After. Specyfikacja OpenAPI jest dostępna pod adresem GET /api/docs.

Wstrzykiwanie CoT: POST /api/cot

Punkt końcowy wstrzykiwania CoT jest główną ścieżką do wypychania raportów pozycji, znaczników kontaktów, alertów i wszelkich innych zdarzeń CoT do obrazu taktycznego z systemów zewnętrznych. Akceptuje zarówno surowy CoT XML, jak i wygodny format JSON.

Payload XML

Dla systemów, które już generują natywny CoT XML — sensory działające na starszych wtyczkach ATAK, platformy SIGINT, kanały radarów naziemnych — wyślij bezpośrednio surową kopertę:

curl -s -X POST https://tak.yourdomain.com:8443/api/cot \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/xml" \
  -d '<?xml version="1.0" encoding="UTF-8"?>
<event version="2.0"
       uid="sensor-east-001"
       type="a-f-G-U-C"
       how="m-g"
       time="2026-05-29T14:32:00Z"
       start="2026-05-29T14:32:00Z"
       stale="2026-05-29T14:37:00Z">
  <point lat="50.4501" lon="30.5234" hae="145.0" ce="10.0" le="5.0"/>
  <detail>
    <contact callsign="SENSOR-EAST-01"/>
    <remarks>Kontakt radaru naziemnego, prędkość 12 kph, namiar 045</remarks>
    <group name="Surveillance" role="Team Member"/>
  </detail>
</event>'

Wymagane pola CoT: uid (unikalny ciąg dla encji), type (ciąg hierarchii typów CoT), time, start, stale (znaczniki czasu ISO 8601) i element <point> z lat, lon, hae, ce i le.

Payload JSON

Dla integracji zbudowanych na nowoczesnych stosach bez bibliotek CoT XML użyj formatu JSON:

curl -s -X POST https://tak.yourdomain.com:8443/api/cot \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "uid": "logistics-truck-07",
    "type": "a-f-G-U-C",
    "callsign": "LOG-07",
    "lat": 50.4610,
    "lon": 30.5190,
    "hae": 138.0,
    "ce": 5.0,
    "le": 3.0,
    "staleSeconds": 300,
    "remarks": "Konwój zaopatrzenia, szacowany czas dotarcia do punktu kontrolnego 14:45Z",
    "group": "Logistics",
    "role": "Team Member"
  }'

CloudTAK serializuje ten JSON do pełnej koperty XML CoT wewnętrznie. Pomyślne wstrzyknięcie zwraca HTTP 201 z wygenerowanym UID CoT w treści odpowiedzi. Zdarzenie natychmiast propaguje się do wszystkich subskrybowanych klientów i strumienia WebSocket.

Strumieniowanie śladów: WebSocket /api/ws

Do konsumpcji obrazu taktycznego w czasie rzeczywistym — budowania niestandardowego pulpitu nawigacyjnego, zasilania potoku AI, archiwizowania śladów w data lake — punkt końcowy WebSocket zapewnia ciągły, niskoniepotrzebny strumień zdarzeń CoT.

Łączenie i subskrybowanie

// Przykład Node.js z biblioteką 'ws'
const WebSocket = require('ws');

const ws = new WebSocket('wss://tak.yourdomain.com:8443/api/ws', {
  headers: { 'Authorization': `Bearer ${process.env.CLOUDTAK_API_KEY}` }
});

ws.on('open', () => {
  ws.send(JSON.stringify({
    type: 'subscribe',
    filter: {
      groups: ['Surveillance', 'Logistics'],
      bbox: [29.5, 50.0, 31.5, 51.0],
      types: ['a-f-G', 'a-h-G', 'a-u-G']
    }
  }));
});

ws.on('message', (data) => {
  const event = JSON.parse(data);
  if (event.type === 'cot') {
    console.log(`Ślad: ${event.payload.uid} na ${event.payload.lat},${event.payload.lon}`);
  } else if (event.type === 'ping') {
    ws.send(JSON.stringify({ type: 'pong' }));
  }
});

Serwer wysyła wiadomość ping co 30 sekund. Klienci muszą odpowiedzieć pong w ciągu 10 sekund lub połączenie zostanie zamknięte.

Aktualizowanie filtrów na aktywnym połączeniu

Wyślij nową wiadomość subscribe w dowolnym momencie, aby zastąpić bieżący filtr — bez rozłączania lub ponownego łączenia.

API misji: tworzenie, aktualizowanie, usuwanie i przypisywanie

Misje w CloudTAK to nazwane konteksty operacyjne grupujące ślady, pakiety danych i użytkowników. API misji umożliwia systemom zewnętrznym programatyczne tworzenie misji — na przykład narzędzie planowania generujące misje z porządku bitwy i wgrywające je do CloudTAK przed operacją.

Tworzenie misji

curl -s -X POST https://tak.yourdomain.com:8443/api/mission \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "OPERACJA CLEARWATER",
    "description": "Przejęcie punktu kontrolnego, Faza 1",
    "classification": "UNCLASSIFIED",
    "bbox": [30.10, 50.35, 30.25, 50.45],
    "groups": ["Alpha-Company", "ISR-Detachment"]
  }' | jq '{uid: .uid, name: .name}'

Odpowiedź zawiera uid misji (UUID) używany we wszystkich kolejnych operacjach. Tablica groups natychmiast przypisuje misję do wymienionych grup.

Aktualizowanie i usuwanie misji

Zaktualizuj metadane misji przez PATCH /api/mission/{uid}. Usuń misję przez DELETE /api/mission/{uid}. Miękkie usunięcie jest dostępne przez PATCH /api/mission/{uid} z "archived": true.

API pakietów danych: MBTiles, KMZ, GeoJSON i wersjonowanie

Pakiety danych dołączone do misji dystrybuują warstwy map i dane referencyjne do urządzeń polowych. CloudTAK akceptuje trzy formaty: MBTiles, KMZ i GeoJSON. Przesyłanie używa multipart form data:

# Wgrywanie warstwy MBTiles dla pokrycia mapy offline
curl -s -X POST \
  https://tak.yourdomain.com:8443/api/mission/${MISSION_UID}/attachment \
  -H "Authorization: Bearer $API_KEY" \
  -F "file=@/data/aoi-sector-north.mbtiles" \
  -F "name=Mapa bazowa sektora północnego" \
  -F "contentType=application/vnd.mbtiles" \
  | jq '{attachmentId: .id, version: .version}'

CloudTAK weryfikuje format pliku przy przesyłaniu. Każde przesyłanie tworzy nową wersję. Samodzielne warstwy map są przesyłane przez POST /api/layer. Dla wdrożeń offline-first zapoznaj się z naszym przewodnikiem po MBTiles i PMTiles dla map offline.

Grupy i kanały: filtrowanie widoczności i kontrola dostępu do śladów

Grupy CloudTAK implementują segregację widoczności śladów. Ślad niosący tag grupy jest widoczny tylko dla podłączonych klientów będących członkami tej grupy. Umożliwia to separację na zasadzie wiedzy koniecznej w ramach wspólnego serwera TAK.

Tworzenie grupy i przypisywanie użytkowników

# Tworzenie grupy
curl -s -X POST https://tak.yourdomain.com:8443/api/group \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "ISR-Detachment", "description": "Komórka Wywiad, Nadzór, Rozpoznanie"}' \
  | jq '.id'

# Dodawanie użytkownika do grupy
curl -s -X POST https://tak.yourdomain.com:8443/api/group/ISR-Detachment/user \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"username": "isr-analyst-01"}'

Członkostwo w grupie kontroluje trzy rzeczy: które ślady klient otrzymuje w strumieniu WebSocket, które misje pojawiają się w kanale misji klienta i które pakiety danych są dystrybuowane przy połączeniu. Klient może należeć do wielu grup jednocześnie. Ślady bez tagu grupy są widoczne dla wszystkich użytkowników na serwerze.

TAKpilot jako przykład integracji

TAKpilot jest AI copilotem Corvus Intelligence dla operacji opartych na TAK. Jest to konkretny przykład głębokiej integracji API CloudTAK: TAKpilot subskrybuje strumień śladów WebSocket, przetwarza polecenia w języku naturalnym od operatorów i wykonuje je jako wywołania API CloudTAK — przekładając ludzkie intencje bezpośrednio na aktualizacje obrazu taktycznego.

Polecenie w języku naturalnym takie jak "oznacz siatkę 38T YQ 45123 67890 jako wrogi kontakt, przypisz do misji Alpha-Company" wyzwala następującą sekwencję API w TAKpilot:

  1. Konwersja MGRS 38T YQ 45123 67890 na stopnie dziesiętne (wewnętrzna konwersja, bez wywołania API).
  2. POST /api/cot z typem a-h-G (wrogi naziemny), skonwertowanymi współrzędnymi i systemowo wygenerowanym znakiem wywoławczym z prefiksem AI-HOSTILE-.
  3. GET /api/mission?name=Alpha-Company w celu rozwiązania UID misji z częściowego odniesienia do nazwy.
  4. POST /api/mission/{uid}/cot w celu powiązania wstrzykniętego UID zdarzenia CoT z misją.
  5. Odpowiedź operatorowi przez interfejs czatu TAKpilot potwierdzająca akcję, zawierająca wygenerowany znak wywoławczy i współrzędne.

TAKpilot używa również strumienia WebSocket reaktywnie: gdy nowy wrogi ślad (typ a-h) pojawia się w monitorowanym obszarze, może automatycznie wyzwolić analizę wzorca zagrożeń i opublikować syntetyzowaną ocenę jako uwagę CoT widoczną dla grupy operatorów — bez czekania na jawne polecenie.

Webhooki: subskrybowanie zdarzeń i przekazywanie do systemów zewnętrznych

Webhooki umożliwiają CloudTAK wypychanie zdarzeń do systemów zewnętrznych zamiast wymagać od tych systemów odpytywania API REST lub utrzymywania trwałego połączenia WebSocket.

Rejestrowanie webhooka

curl -s -X POST https://tak.yourdomain.com:8443/api/webhook \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "kafka-bridge",
    "url": "https://integration.yourdomain.com/cloudtak-events",
    "events": ["new_track", "mission_update", "user_join"],
    "secret": "hmac_signing_secret_32chars_min",
    "active": true
  }' | jq '{id: .id, status: .status}'

CloudTAK podpisuje każdą dostawę webhooka podpisem HMAC-SHA256 obliczonym na surowym ciele JSON przy użyciu sekretu, dostarczanym w nagłówku X-CloudTAK-Signature. Weryfikuj podpis po stronie odbierającej, aby zapobiec sfałszowanym wywołaniom webhooka:

// Odbiornik webhooka Express.js z weryfikacją podpisu
const crypto = require('crypto');

app.post('/cloudtak-events', express.raw({type: 'application/json'}), (req, res) => {
  const sig = req.headers['x-cloudtak-signature'];
  const expected = 'sha256=' + crypto
    .createHmac('sha256', process.env.WEBHOOK_SECRET)
    .update(req.body)
    .digest('hex');

  if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
    return res.status(401).send('Niezgodność podpisu');
  }

  const event = JSON.parse(req.body);
  // Przekaż do Kafka, Slack, SIEM itp.
  kafkaProducer.send({ topic: 'tak-events', messages: [{ value: req.body }] });
  res.status(200).send('OK');
});

Niepowodzenia dostarczenia wyzwalają ponowne próby z wykładniczym wycofaniem: 1, 2, 4, 8, 16 sekund — następnie zdarzenie jest odrzucane i rejestrowane. Przeglądaj historię dostaw przez GET /api/webhook/{id}/deliveries.

Obsługiwane typy zdarzeń webhooka

  • new_track — nowy UID pojawia się na obrazie po raz pierwszy.
  • track_stale — minął czas nieaktualności śladu bez aktualizacji.
  • mission_update — misja została utworzona, zmodyfikowana, zarchiwizowana lub usunięta.
  • user_join — nowy klient połączył się i został uwierzytelniony.
  • user_leave — klient rozłączył się lub sesja wygasła.
  • cot_alert — odebrano zdarzenie CoT z prefiksem typu b-a (alert/alarm).