Every Cursor on Target (CoT) message is one XML document whose root element, <event>, carries a type code, a unique ID, three UTC timestamps and a <point> position; everything else rides inside the open <detail> container. That single shape moves positions, markers, chat, routes, drawings, emergencies and medical requests across ATAK, WinTAK, iTAK and TAK Server. This page is the copy-paste library: annotated, syntactically valid CoT XML for the messages tactical systems actually exchange, each with a note on what the receiving TAK client does with it.
For the format's history and design read our Cursor on Target format overview, and for a field-by-field walkthrough the CoT schema deep dive; this article deliberately stays at the "show me the XML" level. Element and attribute names below were verified against MITRE's public CoT base-event schema and sub-schema documentation and the CoT type definitions published with the TAK clients. Callsigns, UIDs and coordinates are fictional; timestamps are illustrative ISO-8601 UTC values.
The anatomy of a CoT message
A minimal, valid CoT event needs seven <event> attributes, exactly one <point>, and optionally a <detail>:
<event version="2.0" uid="ANDROID-9c2f71a4" type="a-f-G-U-C" how="m-g"
time="2026-10-07T06:12:44.000Z" start="2026-10-07T06:12:44.000Z"
stale="2026-10-07T06:13:14.000Z">
<point lat="50.450112" lon="30.523398" hae="152.4" ce="4.5" le="9.0"/>
<detail>
<contact callsign="GRIF-2" endpoint="*:-1:stcp"/>
<__group name="Cyan" role="Team Member"/>
<status battery="78"/>
<takv platform="ATAK-CIV" version="5.2.0" device="Samsung SM-G975F" os="34"/>
<track speed="1.4" course="270.0"/>
<precisionlocation geopointsrc="GPS" altsrc="GPS"/>
</detail>
</event>
What each part drives on the receiving client:
| Part | Meaning | What ATAK / TAK Server does with it |
|---|---|---|
uid | Identity of the thing, not the message | Same uid moves the existing marker; a new uid creates one. Deletes and emergency cancels target it. |
type | Dot-hyphen taxonomy of what it is | Selects the MIL-STD-2525 icon and affiliation colour; drives server-side filtering and federation rules. |
how | How the position was produced | Weights the report in fusion (GPS vs estimated vs relayed); ATAK renders it in marker details. |
time / start / stale | Generation time and validity window | After stale passes, clients grey out and then remove the marker; nobody sends an explicit expiry. |
point | lat/lon (WGS-84 decimal degrees), hae (metres above ellipsoid), ce/le (error radii) | Places the marker; ce can draw an accuracy ring. Unknown values use the sentinel 9999999. |
detail | Open extension container | Known children (below) set callsign, team colour, battery, speed vector; unknown children are ignored, not rejected. |
Three properties of <point> trip up integrators constantly. hae is height above the WGS-84 ellipsoid, not above mean sea level. ce and le are 1-sigma horizontal and vertical error bounds in metres, required by the schema even when unknown — the value 9999999.0 is the agreed "unknown" sentinel, and it is better than a confident-looking 0.0. And lat/lon are signed decimal degrees, six decimal places giving roughly 0.1 m resolution; there is no MGRS or UTM option in CoT.
CoT type codes and how values: a cheat sheet
The type attribute is a hyphen-separated path through a taxonomy whose first token says what kind of event this is:
| First token | Family | Typical uses |
|---|---|---|
a- | Atoms — real-world things | Units, vehicles, aircraft, casualties, incidents |
b- | Bits — information objects | Chat, routes, drawings, markers, video aliases, alarms |
t- | Tasking / control | Keepalive pings, delete tasks, data retrieval |
y- | Replies | Acknowledgements, tasking status |
For atoms, the second token is affiliation and the third is battle dimension; the rest descend the MIL-STD-2525 function tree in upper case, with lower-case letters reserved for CoT extensions:
| Token | Affiliation | Token | Battle dimension |
|---|---|---|---|
p | Pending | P | Space |
u | Unknown | A | Air |
a | Assumed friend | G | Ground |
f | Friend | S | Sea surface |
n | Neutral | U | Sea subsurface |
s | Suspect | X | Other |
h | Hostile | 2525 function IDs follow in upper case (e.g. -U-C combat, -E-V-A-T tank) | |
Because the taxonomy is prefix-decodable, a client that only understands a-h-G still renders a generic hostile ground icon for a-h-G-E-V-A-T. Common strings you will see in real traffic: a-f-G-U-C (friendly ground, combat — the default ATAK device type), a-f-A-M-F-Q / a-f-A-M-H-Q (friendly fixed-wing / rotary drone), a-u-G (unknown ground), b-m-p-s-m (spot map marker), b-t-f (GeoChat), b-m-r (route), b-r-f-h-c (9-line medical request). How the icons map to symbols is covered in symbology rendering in TAK and the standards comparison in APP-6 vs MIL-STD-2525.
The how attribute records provenance, and fusion systems use it to weight reports:
| how | Meaning |
|---|---|
h-e | Human-entered estimate |
h-c / h-t / h-p | Human-calculated / transcribed (voice, paper) / pasted from another window |
h-g-i-g-o | Officially "a highly suspect track" — in practice ATAK stamps most hand-dropped markers and GeoChat with it |
m-g | Machine-generated from GPS (refinements m-g-d DGPS, m-g-n INS+GPS) |
m-i / m-f / m-r | Mensurated from imagery / fused from several sources / relayed by a gateway |
m-n / m-s / m-c | From inertial navigation / simulation / configuration file |
Time rules: time, start and stale are ISO 8601 UTC ending in Z (fractional seconds optional). time is when the event was produced; start–stale is the validity window. Setting stale earlier than start is the original MITRE "drop track" convention — though in TAK networks an explicit delete task (below) is more reliable.
Position reports: friendly PLI and hostile/neutral markers
The example at the top of this page is a self position report (PLI): ATAK replays it every few seconds with the same uid, sets stale to roughly two to four report intervals plus padding, and lets every other client garbage-collect the marker if updates stop. Sensor-fed or operator-dropped markers use the same event shape with a different type and a longer stale:
<event version="2.0" uid="E-20261007-0413" type="a-h-G-E-V-A-T" how="h-g-i-g-o"
time="2026-10-07T06:41:02.000Z" start="2026-10-07T06:41:02.000Z"
stale="2026-10-07T18:41:02.000Z">
<point lat="50.412220" lon="30.591054" hae="9999999.0" ce="25.0" le="9999999.0"/>
<detail>
<contact callsign="K-41"/>
<remarks source="BAO.F.ATAK.ANDROID-9c2f71a4">Hull-down at treeline, 2 vehicles</remarks>
<usericon iconsetpath="COT_MAPPING_2525C/a-h/a-h-G-E-V-A-T"/>
<link uid="ANDROID-9c2f71a4" type="a-f-G-U-C" relation="p-p"/>
<archive/>
</detail>
</event>
What the receivers do: the type paints the red diamond tank symbol; contact/callsign becomes the label; usericon pins the exact icon set entry (the COT_MAPPING_2525C/<affiliation>/<type> form is what ATAK's 2525 palette emits); link relation="p-p" credits the producer; <archive/> tells clients to persist the marker instead of expiring it with stale. Unknown contacts simply use a-u-G; the yellow question-mark icon appears with no other change. For a plain coloured pin with no 2525 coding, ATAK uses a spot map marker:
<event version="2.0" uid="9405e320-9356-41c4-8449-f46990aa17f8"
type="b-m-p-s-m" how="h-g-i-g-o"
time="2026-10-07T06:55:10.000Z" start="2026-10-07T06:55:10.000Z"
stale="2026-10-08T06:55:10.000Z">
<point lat="50.456090" lon="30.563750" hae="9999999.0" ce="9999999.0" le="9999999.0"/>
<detail>
<contact callsign="R 1"/>
<color argb="-65536"/>
<usericon iconsetpath="COT_MAPPING_SPOTMAP/b-m-p-s-m/-65536"/>
</detail>
</event>
Here the icon is chosen by usericon from the spot-map palette and the ARGB colour value (a signed 32-bit integer, -65536 being opaque red) rather than by a symbology code — useful for friendly annotations that should not imply a 2525 identity.
GeoChat messages (b-t-f)
Chat in the TAK world is not a separate protocol: a GeoChat line is a CoT event of type b-t-f whose text rides in <remarks> and whose addressing rides in <__chat>/<chatgrp>:
<event version="2.0"
uid="GeoChat.ANDROID-9c2f71a4.All Chat Rooms.3f8c2b1e-77d3-4c9a-9e21-5b0f6a2d4e88"
type="b-t-f" how="h-g-i-g-o"
time="2026-10-07T07:02:31.000Z" start="2026-10-07T07:02:31.000Z"
stale="2026-10-08T07:02:31.000Z">
<point lat="0.0" lon="0.0" hae="0.0" ce="9999999.0" le="9999999.0"/>
<detail>
<__chat id="All Chat Rooms" chatroom="All Chat Rooms" groupOwner="false"
senderCallsign="GRIF-2"
messageId="3f8c2b1e-77d3-4c9a-9e21-5b0f6a2d4e88">
<chatgrp uid0="ANDROID-9c2f71a4" uid1="All Chat Rooms" id="All Chat Rooms"/>
</__chat>
<link uid="ANDROID-9c2f71a4" type="a-f-G-U-C" relation="p-p"/>
<remarks source="BAO.F.ATAK.ANDROID-9c2f71a4"
time="2026-10-07T07:02:31.000Z">Bearing 085, treeline, over.</remarks>
</detail>
</event>
Reading it: the event uid is conventionally GeoChat.<sender>.<conversation>.<message-uuid>, which makes deduplication on replay trivial; chatgrp/uid0 is the sender and uid1 is the destination — a single recipient's UID for a direct message, the room name for broadcast; remarks/@to carries the recipient UID on direct messages; stale is set a day out because chat must survive store-and-forward, unlike positions. Delivery/read receipts come back as types b-t-f-d and b-t-f-r. The event's point can anchor the message to a map location; ATAK also forwards the sender's live position unless the operator disables it. For the full store-and-forward and bandwidth picture see tactical chat and data strategy in TAK.
Routes, drawings and range-bearing lines
A route is one b-m-r event whose waypoints are <link> children — b-m-p-w for named waypoints, b-m-p-c for shape control points — followed by a <link_attr> styling block:
<event version="2.0" uid="9017073e-5658-42e7-baa8-b98f3c9c1622" type="b-m-r" how="h-e"
time="2026-10-07T07:20:00.000Z" start="2026-10-07T07:20:00.000Z"
stale="2026-10-08T07:20:00.000Z">
<point lat="0.0" lon="0.0" hae="9999999.0" ce="9999999.0" le="9999999.0"/>
<detail>
<link uid="f3acf150-d75c-407d-be43-e401ab40fe74" callsign="SP"
type="b-m-p-w" point="50.443353,-77.054400" remarks="" relation="c"/>
<link uid="820ebf04-1300-4c3a-a368-d6f1e21a5ddb" callsign=""
type="b-m-p-c" point="50.436413,-77.045642" remarks="" relation="c"/>
<link uid="f6926af1-deec-44f4-ae06-46065c829887" callsign="CP1"
type="b-m-p-w" point="50.446574,-77.040572" remarks="" relation="c"/>
<link_attr planningmethod="Infil" color="-1" method="Driving" prefix="CP"
type="Vehicle" stroke="3" direction="Infil" routetype="Primary"
order="Ascending Check Points"/>
<strokeColor value="-1"/>
<strokeWeight value="3.0"/>
<contact callsign="ROUTE ALFA"/>
<remarks></remarks>
<archive/>
<labels_on value="true"/>
</detail>
</event>
ATAK renders the link point list as the route geometry, promotes b-m-p-w entries to waypoint markers with their own callsigns, and reads link_attr for the travel mode (Driving|Walking|Flying|Swimming|Watercraft), direction (Infil|Exfil) and route type (Primary|Secondary). The event's own point is the 0/0 sentinel — the geometry lives entirely in the detail.
Drawings follow the same "geometry in detail" pattern. A circle is an ellipse with equal axes inside a <shape>:
<event version="2.0" uid="6d09b6f6-720a-4eef-a197-183012512316"
type="u-d-c-c" how="h-e"
time="2026-10-07T07:35:12.000Z" start="2026-10-07T07:35:12.000Z"
stale="2026-10-08T07:35:12.000Z">
<point lat="50.437376" lon="30.572999" hae="9999999.0" ce="9999999.0" le="9999999.0"/>
<detail>
<shape>
<ellipse major="300.0" minor="300.0" angle="360"/>
<link uid="6d09b6f6-720a-4eef-a197-183012512316.Style"
type="b-x-KmlStyle" relation="p-c">
<Style>
<LineStyle><color>ffffffff</color><width>4.0</width></LineStyle>
<PolyStyle><color>96ffffff</color></PolyStyle>
</Style>
</link>
</shape>
<strokeColor value="-1"/>
<strokeWeight value="4.0"/>
<fillColor value="-1761607681"/>
<contact callsign="PATROL AREA"/>
<labels_on value="true"/>
</detail>
</event>
The point is the centre, major/minor are metres, and the KML-style block nested under a b-x-KmlStyle link carries stroke and fill. A rectangle drops the shape element and lists its corners as <link point="lat,lon"/> children with type u-d-r; a freehand line does the same with type u-d-f, closing the polygon by repeating the first point as the last. A range-and-bearing line is different again: type u-rb-a, the point is the anchor, and the vector is numeric:
<event version="2.0" uid="58df2fcd-e33e-414f-a718-b18b50cd3137"
type="u-rb-a" how="h-e"
time="2026-10-07T07:44:03.000Z" start="2026-10-07T07:44:03.000Z"
stale="2026-10-08T07:44:03.000Z">
<point lat="50.420806" lon="30.554945" hae="9999999.0" ce="9999999.0" le="9999999.0"/>
<detail>
<range value="886.14"/>
<bearing value="45.6"/>
<inclination value="0.0"/>
<rangeUnits value="1"/>
<bearingUnits value="0"/>
<northRef value="0"/>
<strokeColor value="-65536"/>
<strokeWeight value="3.0"/>
<contact callsign="R&B 1"/>
</detail>
</event>
Units are encoded as small integers: rangeUnits 0=km, 1=metres, 2=miles, 3=yards, 4=feet, 5=nautical miles; bearingUnits 0=degrees, 1=mils, 2=radians; northRef 0=true, 1=magnetic, 2=grid. ATAK recomputes the arrowhead position from the anchor and the vector on import.
Emergency alerts and CASEVAC/MEDEVAC requests
Emergency beacons are small, urgent events: type b-a-o-tbl for a general 911 alert, stale only ten seconds out (the beacon is re-broadcast, not left to linger), and a UID convention of <device-uid>-9-1-1:
<event version="2.0" uid="ANDROID-9c2f71a4-9-1-1" type="b-a-o-tbl" how="h-g-i-g-o"
time="2026-10-07T08:01:57.000Z" start="2026-10-07T08:01:57.000Z"
stale="2026-10-07T08:02:07.000Z">
<point lat="50.448620" lon="30.531104" hae="160.0" ce="8.0" le="12.0"/>
<detail>
<link uid="ANDROID-9c2f71a4" type="a-f-G-U-C" relation="p-p"/>
<contact callsign="GRIF-2-Alert"/>
<emergency type="911 Alert">GRIF-2</emergency>
</detail>
</event>
The emergency/@type strings and their CoT types, as ATAK defines them:
| Alert | CoT type | Trigger in ATAK |
|---|---|---|
| 911 Alert | b-a-o-tbl | Emergency button, general |
| Ring The Bell | b-a-o-pan | Deliberate urgent attention request |
| In Contact | b-a-o-opn | Troops in contact |
| Geo-fence Breached | b-a-g | Track enters/leaves a monitored geofence |
| Custom | b-a-o-c | Plugin-defined |
| Cancel Alert | b-a-o-can | Operator cancels an active beacon |
On receipt, clients look up the link/@uid marker, raise the alert with range and bearing to the casualty's position, and keep the beacon alive; TAK Server re-broadcasts it periodically. A cancel reuses the same event uid and flips the detail:
<event version="2.0" uid="ANDROID-9c2f71a4-9-1-1" type="b-a-o-can" how="h-g-i-g-o"
time="2026-10-07T08:07:22.000Z" start="2026-10-07T08:07:22.000Z"
stale="2026-10-07T08:07:32.000Z">
<point lat="50.448620" lon="30.531104" hae="160.0" ce="8.0" le="12.0"/>
<detail>
<emergency cancel="true">GRIF-2</emergency>
</detail>
</event>
The 9-line MEDEVAC/CASEVAC request is a marker of type b-r-f-h-c whose detail carries a <_medevac_> element (note the underscores) holding the nine lines as attributes. A safe, widely understood subset:
<event version="2.0" uid="7b1e0c52-2f4d-4f18-9c6e-0d4a2b9f5c31"
type="b-r-f-h-c" how="h-g-i-g-o"
time="2026-10-07T08:10:40.000Z" start="2026-10-07T08:10:40.000Z"
stale="2026-10-07T09:10:40.000Z">
<point lat="50.448620" lon="30.531104" hae="160.0" ce="8.0" le="12.0"/>
<detail>
<contact callsign="GRIF-2"/>
<_medevac_ casevac="false" title="GRIF-2 9LINE" freq="41.50"
urgent="1" priority="0" routine="0"
litter="1" ambulatory="0"
security="2" hlz_marking="2"
equipment_none="true">
<zMistsMap>
<zMist title="MIST 1" z="Z1" m="GSW"
i="left thigh" s="HR 110, BP 100/60" t="tourniquet, TXA"/>
</zMistsMap>
</_medevac_>
<remarks>Pickup at gravel yard, wind 310/8</remarks>
</detail>
</event>
Decoding: patient counts by precedence live in urgent/priority/routine; line 5 in litter/ambulatory; security is an index 0–3 (N no enemy, P possible, E enemy in area, X escort required); hlz_marking indexes A panels, B pyro, C smoke, D none, E other; special equipment appears as boolean flags (hoist, extraction_equipment, ventilator); the clinical MIST report nests under zMistsMap. ATAK renders the full 9-line card and the HLZ tooling from this element. The operational workflow around it is covered in CASEVAC coordination software.
Sensor field of view and video links
MITRE's sensor sub-schema attaches a steerable field of view to any marker. Inside the platform's own position event — here a friendly rotary drone, type a-f-A-M-H-Q — add:
<event version="2.0" uid="UAV-ZP-07" type="a-f-A-M-H-Q" how="m-g"
time="2026-10-07T08:22:05.000Z" start="2026-10-07T08:22:05.000Z"
stale="2026-10-07T08:22:15.000Z">
<point lat="50.437120" lon="30.552870" hae="820.0" ce="12.0" le="15.0"/>
<detail>
<contact callsign="ZP-07" endpoint="*:-1:stcp"/>
<sensor azimuth="127.0" fov="30.0" vfov="22.0" range="2200.0"
elevation="-18.0" model="EO/IR turret"/>
<__video url="rtsp://192.168.4.60:8554/live.sdp"/>
</detail>
</event>
azimuth is degrees from true north, elevation tilt (negative is down), fov/vfov horizontal and vertical field in degrees, range slant range in metres — together they let ATAK draw the sensor cone on the map. The <__video> child binds the marker to a stream URL, so opening the marker opens the feed. Standalone camera registrations travel as their own events of type b-i-v carrying a <ConnectionEntry> with address, port, protocol and related tuner attributes, which populate the video manager on every client. For the wider pipeline — telemetry rates, KLV metadata, cueing — see drone telemetry integration with TAK.
This is where most integration programs stall: the radar, the drone autopilot, the acoustic sensor and the legacy C2 feed each describe the world differently, and each must be translated into valid CoT — correct types, honest ce/le, stable UIDs, sane stale times — or the COP fills with ghost tracks. We build exactly these CoT gateways and adapters, plus ATAK/WinTAK plugins that render the result. Tell us what feed you need on the tactical picture →
Deleting markers and keepalive ping/pong
CoT has no built-in delete; TAK layers one on top as a tasking event of type t-x-d-d whose <link> names the victim:
<event version="2.0" uid="6650d1ee-4b17-4d02-8c95-13a1f2e9b0aa"
type="t-x-d-d" how="h-g-i-g-o"
time="2026-10-07T08:31:19.000Z" start="2026-10-07T08:31:19.000Z"
stale="2026-10-07T08:31:29.000Z">
<point lat="0.0" lon="0.0" hae="9999999.0" ce="9999999.0" le="9999999.0"/>
<detail>
<link uid="E-20261007-0413" relation="p-p" type="a-h-G-E-V-A-T"/>
<__forcedelete/>
</detail>
</event>
Without <__forcedelete/> ATAK only marks the referenced item stale locally and removes it according to the user's stale-item settings; with it, the item is removed outright on every client that receives the task. The importer requires link/@uid, @relation and @type to be present and non-empty, so keep all three. Keepalive is even smaller — TAK clients ping a server that has gone quiet for about 15 seconds, repeating every few seconds, and treat the type t-x-c-t-r pong as a control message that never reaches the map:
<event version="2.0" uid="ANDROID-9c2f71a4-ping" type="t-x-c-t" how="m-g"
time="2026-10-07T08:33:50.000Z" start="2026-10-07T08:33:50.000Z"
stale="2026-10-07T08:34:00.000Z">
<point lat="0.0" lon="0.0" hae="0.0" ce="9999999.0" le="9999999.0"/>
</event>
If you are gateway-building, mirror this behaviour: a <uid>-ping event every interval you expect the connection checked, and silently discard pongs.
Generating valid CoT: timestamps, stale, UIDs, escaping
The recurring bugs in CoT emitters are predictable, and all of them are cheap to prevent:
- UTC, always. Every timestamp ends in
Z; local offsets or a missingZshift markers hours into the past or future. Fractional seconds are optional and any precision is legal. - Stale discipline. Moving tracks: two to four report intervals plus margin. Static markers: hours to days, with
<archive/>if they should persist. Never leavestaleat a default far future on a live track — ghost markers are the number-one field complaint. - Stable UIDs. Derive the uid from the entity (serial, track number, content hash), not from the message. Two real tracks sharing a uid collapse into one flickering marker.
- Honest errors. If you do not know altitude or accuracy, emit
9999999.0, not0. Fusion engines treat0as a claim. - Coordinates. Signed decimal degrees, WGS-84; six decimal places is ample. Truncating to four places (roughly 10 m) is a legitimate bandwidth choice some libraries make — but do it consistently.
- XML escaping. Escape
&,<,>in attribute values and text — callsigns and remarks will eventually contain an ampersand. One stray<in a remarks field kills the whole document at the parser. - Validate once, trust later. Lint your emitter's output against the published CoT event XSD during development. The XSD cannot catch semantic errors (stale before start, meaningless type tails), so add those checks as assertions in the encoder.
Sending CoT: mesh multicast vs TAK Server
Two transports cover almost every deployment. Serverless mesh SA multicasts each XML document as one UDP datagram to the standard TAK address 239.2.3.1:6969 (GeoChat historically also used 224.10.10.1:17012); every client on the segment hears everything, and there is no store-and-forward. The server model has clients connect to TAK Server over TCP — port 8087 plain, 8089 TLS with client certificates — which streams XML in both directions, fans events out with group and mission filtering, and can re-encode the stream as the compact TAK protobuf format negotiated per connection. The encoding and negotiation details, including when protobuf breaks tooling, are covered in TAK protocol: CoT XML vs protobuf; routing across server boundaries is covered in TAK Federation Hub architecture, and the coalition picture in bridging CoT and NATO standards.
One rule of thumb decides between them: if the receivers are on the same RF segment and loss is tolerable, multicast is free; if anyone is off-segment, on a different network, or needs replay while disconnected, you need the server — and so does anything that requires an audit trail.
Turn your sensor or C2 feed into valid CoT
We build CoT gateways and adapters that convert radar, drone, acoustic and legacy C2 feeds into clean Cursor on Target streams, plus ATAK and WinTAK plugins that present them on the tactical picture.
Prepared by the Corvus Intelligence engineering team, which builds CoT gateways, TAK Server integrations and ATAK/WinTAK plugins; every element name, type code and behaviour described here was verified against MITRE's public CoT schema documentation and the CoT definitions published with the TAK clients. About Corvus Intelligence →