DA — Device Attributes (CSI c / CSI > c)
Ask the terminal what kind of VT it is — primary (CSI c) returns features, secondary (CSI > c) returns model + firmware.
Byte forms
Every common string-literal form so you can paste-and-search either direction.
\x1b[c (primary DA) \x1b[>c (secondary DA)\033[c / \033[>c\e[c / \e[>cESC [ c / ESC [ > c1b 5b 63 / 1b 5b 3e 63Description
Device Attributes — a request/reply pair the application sends and the terminal answers via the input stream. Primary DA (\x1b[c, sometimes \x1b[0c) — terminal replies with \x1b[?64;...c listing the VT class and supported optional features (132-column mode, sixel, ReGIS, user-defined keys, etc.). Secondary DA (\x1b[>c, sometimes \x1b[>0c) — terminal replies with \x1b[>Pp;Pv;Pcc where Pp is the model (0=VT100, 1=VT220, 41=VT420, 61=xterm-style, 65=VT525, etc.), Pv is the firmware version, Pcc is the ROM cart serial (usually 0). Apps use DA on startup to feature-detect — neovim's t_Co autodetect, tmux's title-set capability probing, mintty's xterm-compat checks all rely on it.
Spec citation: ECMA-48 §8.3.24 (DA) / xterm-ctlseqs
Examples
# Send primary DA and read the reply (raw mode):\nstty -echo raw min 0 time 5\nprintf '\033[c'; IFS= read -r -t 1 -d c REPLY; stty sane\necho "DA reply: $REPLY c"import sys, termios, tty, select\nfd = sys.stdin.fileno(); old = termios.tcgetattr(fd); tty.setraw(fd)\ntry:\n sys.stdout.write('\x1b[c'); sys.stdout.flush()\n r, _, _ = select.select([fd], [], [], 1.0)\n print(repr(sys.stdin.read(64)) if r else 'no reply')\nfinally:\n termios.tcsetattr(fd, termios.TCSADRAIN, old)fmt.Print("\x1b[c") // request; read reply via os.Stdin in raw modeprocess.stdout.write('\x1b[c') // reply arrives on process.stdinprintf("\x1b[c"); fflush(stdout); /* read reply from stdin */Used in
Real-world tools that emit this sequence — anchors the bytes to commands you've already used.
- tmux attach-time feature probetmux ≥ 3.2 emits DA1 (`\x1b[c`) on every client attach to detect terminal capabilities — the reply's parameter list drives the `default-terminal` selection (`tmux-256color` vs `tmux-direct`), `allow-passthrough` defaults, and bracketed-paste availability advertised inside the panes
- ncurses initialization (`initscr()`)ncurses `initscr()` and `newterm()` send DA1 during the terminal-state probe phase, before reading the user's `$TERM` terminfo entry — the reply is cross-checked against the terminfo `da` boolean to detect ncurses-on-a-VT-without-real-DA situations (rare on modern systems)
- neovim `:checkhealth nvim` terminal sectionneovim 0.9+ emits DA1 + DA2 + DA3 + XTVERSION as the `term://` feature-detection chain — `:checkhealth nvim` reports the parsed DA1 response as `Terminal: DEC VT220 (62)` or `Terminal: VT525 (65)` so users can see what the terminal advertised
- kitty `kitten query-terminal`kitty's bundled `kitten query-terminal` runs DA1 + DA2 + DA3 + XTGETTCAP + DECRQSS as a one-shot terminal-capability dump — output format mirrors xterm's `XTQUERY` debug logs, used by integrators to confirm feature parity when porting plugins
- wezterm `wezterm cli list-clients` capability columnwezterm's CLI populates the `client-features` column by parsing DA1 responses cached from the client connect handshake — operators reading the table can spot a connected pane whose DA1 said `?1;2` (VT100 with advanced video) vs `?64;1;9;15;22;29` (VT420)
Frequently asked
Short answers to the questions developers actually search for this sequence.
- How do I detect what terminal I'm running in?
- Send
\x1b[c(Primary Device Attributes) and read the reply from stdin — the terminal answers with\x1b[?<class>;<feature>;…cidentifying its emulation level (e.g.\x1b[?64;1;6cfor a VT520-class with cols-132 and selective-erase). For finer detail, send\x1b[>c(Secondary DA) to get terminal type + firmware version; modern terminals also accept XTVERSION (\x1b[>q) which returns a human-readable name + version string. - What do I do if the terminal never replies?
- Set a timeout — 50-100ms is the standard window for a DA query, after which assume the terminal doesn't implement the response. The user might be on a serial line with no terminal attached, or inside a logging pipe where stdin is
/dev/null. Falling back to$TERM/$COLORTERMenv-var sniffing is the usual recovery path.
Terminal support
- xterm
- yes
- Linux console (fbcon)
- yes
- macOS Terminal.app
- yes
- iTerm2
- yes
- Windows Terminal
- yes
- cmd.exe / ConPTY
- partial
- kitty
- yes
- alacritty
- yes
- WezTerm
- yes
- Ghostty
- yes
- GNOME Terminal
- yes
- Konsole
- yes
- tmux
- yes
- GNU screen
- yes
| xterm | Linux console (fbcon) | macOS Terminal.app | iTerm2 | Windows Terminal | cmd.exe / ConPTY | kitty | alacritty | WezTerm | Ghostty | GNOME Terminal | Konsole | tmux | GNU screen |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| yes | yes | yes | yes | yes | partial | yes | yes | yes | yes | yes | yes | yes | yes |