Skip to main content
ansicode

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[\x1b[c (primary DA) \x1b[>c (secondary DA)
\\033[\033[c / \033[>c
\\e[\e[c / \e[>c
ESC [ESC [ c / ESC [ > c
hex1b 5b 63 / 1b 5b 3e 63

Description

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

bash
# 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"
python
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)
go
fmt.Print("\x1b[c")   // request; read reply via os.Stdin in raw mode
javascript
process.stdout.write('\x1b[c')   // reply arrives on process.stdin
c
printf("\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>;…c identifying its emulation level (e.g. \x1b[?64;1;6c for 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 / $COLORTERM env-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

Related sequences

In the family cookbook

CSI cookbook · 4. Queries — DA, DA2, DSR, DECRQM