← Back to Dev Tools

UA Payload Parser

Paste any User-Agent string — instantly break down browser, OS, engine, device & bot signals.

🔍
Paste a UA string above or click Use My UA to detect yours instantly.

What is a User Agent?

A User Agent (UA) is a string your browser sends with every HTTP request, telling servers what software is making the request. Servers use it for analytics, conditional CSS delivery, bot detection, and feature gating.

Why does my UA say "Mozilla/5.0"?

Legacy compatibility. Every browser says Mozilla/5.0 — it dates back to the browser wars of the 90s when sites served rich content only to Netscape. All browsers kept it to avoid being blocked.

How do sites detect bots?

Bots usually have strings like Googlebot, Bingbot, or curl. Sophisticated bots spoof real browser UAs but can still be fingerprinted via behavior, headers, and JS execution.

What is the "engine" field?

The rendering engine is what actually draws the webpage. Blink (Chrome, Edge), WebKit (Safari), and Gecko (Firefox) — each behaves slightly differently, which is why CSS sometimes needs vendor prefixes.

Can I trust UA strings?

No — any client can send any UA. Never use it for security decisions. It's useful for analytics and UX optimization, but always validate critical info server-side through other means.

lessChrome/i, 'Headless Chrome',false], [/PhantomJS/i, 'PhantomJS', false], [/Puppeteer/i, 'Puppeteer', false], ]; for (const [re, name, verified] of botPatterns) { if (re.test(u)) { r.bot = { is: true, name, verified }; break; } } /* ── OS ── */ if (/Windows NT 10\.0/.test(u)) { r.os.name = 'Windows'; r.os.version = '10 / 11'; } else if (/Windows NT 6\.3/.test(u)) { r.os.name = 'Windows'; r.os.version = '8.1'; } else if (/Windows NT 6\.1/.test(u)) { r.os.name = 'Windows'; r.os.version = '7'; } else if (/Windows NT/.test(u)) { r.os.name = 'Windows'; r.os.version = ''; } else if (/iPhone/.test(u)) { r.os.name = 'iOS'; const m = u.match(/CPU iPhone OS ([0-9_]+)/i); r.os.version = m ? m[1].replace(/_/g,'.') : ''; r.device.type = 'Mobile'; r.device.vendor = 'Apple'; r.device.model = 'iPhone'; } else if (/iPad/.test(u)) { r.os.name = 'iPadOS'; const m = u.match(/CPU OS ([0-9_]+)/i); r.os.version = m ? m[1].replace(/_/g,'.') : ''; r.device.type = 'Tablet'; r.device.vendor = 'Apple'; r.device.model = 'iPad'; } else if (/Macintosh|Mac OS X/.test(u)) { r.os.name = 'macOS'; const m = u.match(/Mac OS X ([0-9_\.]+)/i); r.os.version = m ? m[1].replace(/_/g,'.') : ''; } else if (/Android/.test(u)) { r.os.name = 'Android'; const m = u.match(/Android ([0-9.]+)/i); r.os.version = m ? m[1] : ''; // vendor/model const dm = u.match(/Android [0-9.]+;\s*([^)]+)\)/i); if (dm) { const parts = dm[1].trim().split(';'); r.device.vendor = parts[0]?.trim() || ''; r.device.model = parts[1]?.trim() || dm[1].trim(); } r.device.type = /Mobile/.test(u) ? 'Mobile' : 'Tablet'; } else if (/Linux/.test(u)) { r.os.name = 'Linux'; if (/Ubuntu/.test(u)) r.os.version = 'Ubuntu'; else if (/Fedora/.test(u)) r.os.version = 'Fedora'; } else if (/CrOS/.test(u)) { r.os.name = 'ChromeOS'; } else if (/X11/.test(u)) { r.os.name = 'Unix'; } /* ── Arch ── */ if (/Win64|x64|x86_64|amd64/i.test(u)) r.os.arch = '64-bit (x86)'; else if (/arm64|aarch64/i.test(u)) r.os.arch = '64-bit (ARM)'; else if (/armv7/i.test(u)) r.os.arch = '32-bit (ARM)'; else if (/i686|Win32|x86/i.test(u)) r.os.arch = '32-bit (x86)'; /* ── Engine ── */ const evM = u.match(/AppleWebKit\/([0-9.]+)/i); const gecM = u.match(/Gecko\/([0-9.]+)/i); if (/Gecko\//.test(u) && /Firefox/.test(u)) { r.engine = { name: 'Gecko', version: gecM ? gecM[1] : '' }; } else if (evM) { r.engine = { name: /Chrome|Chromium/.test(u) ? 'Blink' : 'WebKit', version: evM[1] }; } else if (!evM && !gecM) { r.engine = { name: 'Unknown', version: '' }; } /* ── Browser ── */ const browsers = [ [/Edg\/([0-9.]+)/, 'Microsoft Edge'], [/OPR\/([0-9.]+)/, 'Opera'], [/Opera\/([0-9.]+)/, 'Opera'], [/SamsungBrowser\/([0-9.]+)/, 'Samsung Browser'], [/UCBrowser\/([0-9.]+)/, 'UC Browser'], [/YaBrowser\/([0-9.]+)/, 'Yandex Browser'], [/Vivaldi\/([0-9.]+)/, 'Vivaldi'], [/Brave/, 'Brave'], [/Firefox\/([0-9.]+)/, 'Firefox'], [/Chromium\/([0-9.]+)/, 'Chromium'], [/Chrome\/([0-9.]+)/, 'Chrome'], [/Version\/([0-9.]+).*Safari/, 'Safari'], ]; for (const [re, name] of browsers) { const m = u.match(re); if (m) { r.browser.name = name; r.browser.version = m[1] || ''; r.browser.full = name + (m[1] ? ' ' + m[1] : ''); break; } } if (r.bot.is) { r.browser.name = r.bot.name; r.browser.full = r.bot.name; r.device.type = 'Bot'; } /* ── Extra flags ── */ if ( lessChrome/.test(u)) r.flags.push('Headless browser'); if (/Mobile/.test(u) && r.device.type === 'Desktop') r.device.type = 'Mobile'; if (/Tablet/.test(u)) r.device.type = 'Tablet'; return r; } /* ═══ RENDER ═══ */ function render(p, ua) { const deviceIcon = { Mobile:'📱', Tablet:'🖥️', Desktop:'💻', Bot:'🤖' }[p.device.type] || '💻'; const badgeCls = { Mobile:'badge-mobile', Tablet:'badge-tablet', Desktop:'badge-desktop', Bot:'badge-bot' }[p.device.type] || 'badge-desktop'; const heroLine = [p.browser.full, p.os.name + (p.os.version?' '+p.os.version:''), p.os.arch].filter(Boolean).join(' · '); // Token breakdown const tokens = tokenize(ua); // Plain-English explanation const explain = buildExplain(p); document.getElementById('output').innerHTML = `
${deviceIcon}

${p.bot.is ? p.bot.name : p.browser.full || 'Unknown Browser'}

${heroLine}

${p.device.type}
Browser & Engine
${row('Browser', p.browser.name, p.browser.name !== 'Unknown')} ${row('Version', p.browser.version, !!p.browser.version)} ${row('Engine', p.engine.name, p.engine.name !== 'Unknown')} ${row('Engine Ver', p.engine.version, !!p.engine.version)} ${row('Bot', p.bot.is ? (p.bot.name + (p.bot.verified?' ✓ verified':'')) : 'No', !p.bot.is, p.bot.is)}
OS & Device
${row('OS', p.os.name, p.os.name !== 'Unknown')} ${row('OS Version', p.os.version, !!p.os.version)} ${row('Architecture',p.os.arch, !!p.os.arch)} ${row('Device Type', p.device.type, true)} ${row('Vendor', p.device.vendor, !!p.device.vendor)} ${row('Model', p.device.model, !!p.device.model)}
Plain-English Breakdown
${explain}
Token Analysis
${tokens}
Browser OS Engine Device Bot Unknown token
`; } function row(key, val, detected, flagged=false) { const v = val || '—'; const cls = !val ? 'unknown' : flagged ? 'flagged' : detected ? 'detected' : ''; const copyId = 'cp_' + key.replace(/\s/g,'_'); return `
${key} ${v} ${val ? `` : ''}
`; } function tokenize(ua) { // Split on spaces and parens content const parts = []; const re = /\(([^)]*)\)|([^\s()]+)/g; let m; while ((m = re.exec(ua)) !== null) { if (m[1] !== undefined) { // paren group — split by ; m[1].split(';').forEach(p => p.trim() && parts.push(p.trim())); } else { parts.push(m[2]); } } return parts.map(p => { const cls = classifyToken(p); return `${escape(p.length>30?p.slice(0,28)+'…':p)}`; }).join(''); } function classifyToken(t) { if (/firefox|chrome|safari|opr|edg|version|chromium|samsung|uc|yabrowser|vivaldi|brave/i.test(t)) return 'token-browser'; if (/windows|mac os|android|linux|iphone|ipad|x11|cros|unix|ubuntu|fedora/i.test(t)) return 'token-os'; if (/webkit|gecko|blink|trident|presto/i.test(t)) return 'token-engine'; if (/mobile|tablet|phone|touch/i.test(t)) return 'token-device'; if (/bot|crawler|spider|scraper|curl|wget|python|postman/i.test(t)) return 'token-bot'; return ''; } function buildExplain(p) { if (p.bot.is) { const verifiedLine = p.bot.verified ? "It is a verified crawler from a major search engine — legitimate traffic." : "It is not a verified search engine crawler — could be a scraper, preview fetcher, or API client."; return `This is a bot / automated agent called ${p.bot.name}. ${verifiedLine} It is not a real user browser. Most analytics platforms filter these out automatically.`; } const b = p.browser.name !== "Unknown" ? `${p.browser.full}` : "an unknown browser"; const o = p.os.name !== "Unknown" ? `${p.os.name}${p.os.version ? " " + p.os.version : ""}` : "an unknown OS"; const e = p.engine.name !== "Unknown" ? `uses the ${p.engine.name} rendering engine` : ""; const d = p.device.type === "Mobile" ? "a mobile phone" : p.device.type === "Tablet" ? "a tablet" : "a desktop or laptop"; const arch = p.os.arch ? ` running on a ${p.os.arch} processor` : ""; const vendor = p.device.vendor ? ` (${p.device.vendor}${p.device.model ? " \u2013 " + p.device.model : ""})` : ""; const eJoin = e ? ", and it " : " is "; const engineNote = p.engine.name === "Blink" ? "Blink is the engine behind Chrome and Edge — widely supported, fastest for modern CSS." : p.engine.name === "WebKit" ? "WebKit powers Safari — some CSS features may behave differently than Blink-based browsers." : p.engine.name === "Gecko" ? "Gecko is Firefox's engine — excellent standards compliance, sometimes stricter than Blink." : ""; const headlessNote = p.flags.includes("Headless browser") ? "⚠ Headless browser detected — this is likely automated scraping or testing (e.g. Puppeteer, Playwright)." : ""; return `This request came from ${b} running on ${o}${arch}. It ${e}${eJoin}accessing from ${d}${vendor}. ${engineNote} ${headlessNote}`; } function escape(s) { return s.replace(/&/g,'&').replace(//g,'>'); } /* ═══ ACTIONS ═══ */ function parseUA() { const ua = document.getElementById('uaInput').value.trim(); document.getElementById('uaLen').textContent = ua ? `${ua.length} chars` : ''; if (!ua) { document.getElementById('output').innerHTML = `
🔍
Paste a UA string above or click Use My UA.
`; return; } const p = parse(ua); render(p, ua); } function useMyUA() { const ua = navigator.userAgent; document.getElementById('uaInput').value = ua; document.getElementById('uaLen').textContent = `${ua.length} chars`; parseUA(); } function clearAll() { document.getElementById('uaInput').value = ''; document.getElementById('uaLen').textContent = ''; document.getElementById('output').innerHTML = `
🔍
Paste a UA string above or click Use My UA.
`; } function loadTest(key) { document.getElementById('uaInput').value = TEST_UAS[key] || ''; parseUA(); } async function copyRaw() { const ua = document.getElementById('uaInput').value.trim(); if (!ua) return; await navigator.clipboard.writeText(ua); const btn = document.getElementById('copyRawBtn'); btn.textContent = '✓ Copied'; btn.classList.add('success'); setTimeout(() => { btn.textContent = 'Copy UA'; btn.classList.remove('success'); }, 1500); } async function copyField(id, btn) { const el = document.getElementById(id); if (!el || el.textContent === '—') return; await navigator.clipboard.writeText(el.textContent); btn.textContent = '✓'; btn.classList.add('ok'); setTimeout(() => { btn.textContent = '⧉'; btn.classList.remove('ok'); }, 1400); } /* ═══ BOOT — auto-detect ═══ */ useMyUA();