Full API Reference
Every action the extension understands. Copy-paste from here with the shared ask() helper (canonical).
Version 7.10.1 · Canonical envelopes (RTO_REQUEST/RTO_RESPONSE) · Multi-tab via tabKey · Firefox ✓ · Chrome (MV3) planned
{ type:'navigate' } style messages, see the Legacy compatibility table below for a drop-in mapping.
2) Minimal ask() Helper (canonical)
One helper app-wide. It posts RTO_REQUEST with an action and args, then resolves a paired RTO_RESPONSE (ok/data or ok:false,error:{code,…}).
<script>
const ADMIN_ORIGIN='admin', EXT_ORIGIN='extension';
let _seq=0, _waiters=new Map();
addEventListener('message', (e) => {
const d=e.data; if(!d||typeof d!=='object') return;
if(d.origin!==EXT_ORIGIN) return;
if(d.requestId && _waiters.has(d.requestId)) { _waiters.get(d.requestId)(d); _waiters.delete(d.requestId); }
});
function ask(action, args={}, timeoutMs=12000){
const requestId='r'+(++_seq);
postMessage({ origin:ADMIN_ORIGIN, type:'RTO_REQUEST', requestId, action, args }, '*');
return new Promise((resolve,reject)=>{
const t=setTimeout(()=>{ _waiters.delete(requestId); reject(Object.assign(new Error('timeout'),{ code:'TIMEOUT' })); }, timeoutMs);
_waiters.set(requestId, (resp)=>{ clearTimeout(t); resolve(resp); });
});
}
</script>
3) Envelopes (canonical)
Admin → Extension
Sent by your ask() helper.
{
"origin": "admin",
"type": "RTO_REQUEST",
"requestId": "r123",
"action": "detect" | "open" | "navigate" | "focus" | "focusByUrl" | "focusByPrefix" |
"focusMaster" | "getUrl" | "getCurrentUrl" | "getTitle" | "suppressNextFocus" |
"setMasterTab" | "listTabs" | "adoptTab" | "releaseTab" | "close" |
"runJs" | "domType" | "domSetValue" | "domClick" | "focusElement" |
"submitForm" | "selectSetValue" | "waitFor" | "domSetStyle" | "highlight" |
"getHtml" | "WRB_ENABLE" | "WRB_ADD" | "WRB_REMOVE" | "WRB_STATUS",
"args": { ... } // see tables below
}
Extension → Admin
Always check ok and handle error.code.
{
"origin": "extension",
"type": "RTO_RESPONSE",
"requestId": "r123",
"ok": true, // or false
"data": { ... }, // present when ok=true
"error": { "code":"STRING", "message":"Human readable", "details":any } // when ok=false
}
{type:'ping'} → {type:'pong'} remains supported, but prefer the canonical envelopes.4) Browser / Tab Actions
Most actions accept optional tabKey (string) or tabId (number) to target a specific remote tab.
| action | args | What it does | data (when ok) |
|---|---|---|---|
detect |
{ } |
Checks extension availability and returns version. | { version } |
open |
{ url, focus?:bool, newTab?:bool, tabKey?, tabId? } |
Create a controlled tab (or reuse) and navigate to url. |
{ tabId, url } |
navigate |
{ url, focus?:bool, tabKey?, tabId? } |
Navigate the controlled tab to url. |
{ tabId, url } |
focus |
{ tabKey?, tabId? } |
Bring the remote tab to front. | { tabId } |
focusByUrl |
{ url } |
Adopt & focus a tab matching url. |
{ tabId, url } |
focusByPrefix |
{ prefix } |
Adopt & focus a tab whose URL starts with prefix. |
{ tabId, url } |
focusMaster |
— | Return focus to the admin/master tab (if known). | { } |
getUrl / getCurrentUrl |
{ tabKey?, tabId? } |
Read current URL of the controlled tab. | { url } |
getTitle |
{ tabKey?, tabId? } |
Read document.title from the controlled tab. |
{ title } |
listTabs |
— | List known controlled tabs. | { items:[{tabId,tabKey?,url?,title?,focused?,createdAt?,lastSeenAt?}] } |
adoptTab |
{ tabId, tabKey? } |
Attach a friendly tabKey to an existing tab. |
{ tabId, tabKey } |
releaseTab |
{ tabKey? } |
Detach the logical key from a tab (tab remains open). | { tabId?, tabKey? } |
close |
{ tabKey?, tabId? } |
Close the targeted tab (policy-dependent). | { tabId } |
suppressNextFocus |
— | Disable auto-focus for the next open/navigate. |
{ } |
setMasterTab |
— | Mark this tab as the admin “master”. | { } |
open implicitly forces newTab:true to avoid stealing your admin tab.5) DOM Actions (summary)
Execute inside the controlled page (content script). Full details on DOM & Automation.
| action | args (common: tabKey?) | Notes |
|---|---|---|
domType | { selector, value, delayMs? } | Types with optional per-char delay, fires input/change. |
domSetValue | { selector, value, clear? } | Instant set; sensitive-field guard → FORBIDDEN. |
domClick | { selector } | Scroll into view then click. |
focusElement | { selector } | Avoids scroll jumps when possible. |
submitForm | { selector } | requestSubmit() when available. |
selectSetValue | { selector, value } | Sets a <select>, fires events. |
waitFor | { selector, timeoutMs } | Resolves on appearance; else TIMEOUT. |
domSetStyle | { selector, style:{…} } | Whitelisted props with !important. |
highlight | { selector, color?, ms? } | Temporary halo; auto-restore. |
getHtml | { selector, property } | One of: outerHTML|innerHTML|textContent|innerText|value. |
runJs | { code } | Keep snippets tiny; return a simple value. |
6) Responses & Error Codes
const r = await ask('getUrl');
if (r.ok) console.log('URL:', r.data.url);
else console.warn('Error', r.error.code, r.error.message);
| code | Raised by | Meaning | Typical fix |
|---|---|---|---|
INVALID_URL | open, navigate | Malformed / forbidden scheme (http/file/js) or local/LAN. | Use absolute https:// on public hosts. |
NO_CONTROLLED_TAB | getUrl/getTitle/DOM/runJs | No controlled tab exists. | Call open/navigate first. |
DOMAIN_NOT_ALLOWED | open, navigate, DOM | Host not on the Allow-list. | User adds host via popup; retry (built-in banner also resumes). |
ELEMENT_NOT_FOUND | domType/… | Selector matched nothing at execution time. | waitFor, fix selector, raise timeout. |
TIMEOUT | waitFor | Element never appeared. | Increase timeoutMs, add retries/backoff. |
FORBIDDEN | domType/domSetValue/getHtml(value) | Sensitive-field guard. | Avoid secrets; redesign the flow. |
EXECUTION_ERROR | runJs | Thrown by your snippet (null/CSP/syntax). | IIFE, guard nulls, keep it tiny. |
7) Copy-Paste Examples
7.1 Open → Wait → Click (no focus steal)
await ask('open', { url:'https://app.example.com/login', focus:false, newTab:true, tabKey:'auth' });
await ask('waitFor', { selector:'#email', timeoutMs:15000, tabKey:'auth' });
await ask('domSetValue', { selector:'#email', value:'user@example.com', tabKey:'auth' });
await ask('domSetValue', { selector:'#note', value:'hello world', tabKey:'auth' });
await ask('domClick', { selector:'button[type=submit]', tabKey:'auth' });
7.2 Focus Management
await ask('open', { url:'https://example.com', focus:false, newTab:true, tabKey:'main' });
await ask('suppressNextFocus');
await ask('navigate', { url:'https://example.com/dashboard', tabKey:'main' });
await ask('focusMaster'); // back to admin
7.3 QA Playlist (polite throttle)
const pages=['/a','/b','/c'].map(x=>'https://example.com'+x);
for (const url of pages){
await ask('navigate', { url, focus:false, tabKey:'qa' });
await ask('waitFor', { selector:'body', timeoutMs:12000, tabKey:'qa' });
await new Promise(r=>setTimeout(r, 600));
}
7.4 Multi-tab basics
const list = await ask('listTabs');
if (list.ok && list.data.items.length){
const first = list.data.items[0];
await ask('adoptTab', { tabId:first.tabId, tabKey:'ops' });
await ask('navigate', { url:'https://example.org/tools', tabKey:'ops' });
await ask('releaseTab', { tabKey:'ops' });
}
8) Optional Request Blocking (Firefox MV2)
Off by default. Scoped to the controlled tab. Use sparingly for QA.
await ask('WRB_ENABLE', { enable:true });
await ask('WRB_ADD', { host:'browser-intake-datadoghq.com' });
const status = await ask('WRB_STATUS'); // => { ok:true, data:{ wrbEnabled, blockList } }
await ask('WRB_REMOVE', { host:'browser-intake-datadoghq.com' });
await ask('WRB_ENABLE', { enable:false });
Chrome MV3: not used. Keep OFF for store submission.
9) Legacy Compatibility (≤ v7.9.x)
Older pages may send { type:'...' }. You can keep them working while migrating to ask(action,args).
| Legacy request | Current equivalent |
|---|---|
{ type:'open', url, focus?, newTab? } | ask('open', { url, focus, newTab }) |
{ type:'navigate', url, focus? } | ask('navigate', { url, focus }) |
{ type:'focus' } | ask('focus') |
{ type:'focusByUrl', url } | ask('focusByUrl', { url }) |
{ type:'focusByPrefix', prefix } | ask('focusByPrefix', { prefix }) |
{ type:'focusMaster' } | ask('focusMaster') |
{ type:'getUrl' } | ask('getUrl') or ask('getCurrentUrl') |
{ type:'getTitle' } | ask('getTitle') |
{ type:'domAction', action:'type', payload:{...} } | ask('domType', {...}) |
{ type:'domAction', action:'setValue', payload:{...} } | ask('domSetValue', {...}) |
{ type:'domAction', action:'click', payload:{...} } | ask('domClick', {...}) |
{ type:'domAction', action:'submit', payload:{...} } | ask('submitForm', {...}) |
{ type:'domAction', action:'selectSetValue', payload:{...} } | ask('selectSetValue', {...}) |
{ type:'domAction', action:'waitFor', payload:{...} } | ask('waitFor', {...}) |
{ type:'domAction', action:'domSetStyle', payload:{...} } | ask('domSetStyle', {...}) |
{ type:'domAction', action:'highlight', payload:{...} } | ask('highlight', {...}) |
{ type:'domAction', action:'getHtml', payload:{...} } | ask('getHtml', {...}) |
{ type:'runJs', payload:{ code } } | ask('runJs', { code }) |
10) Version & Compatibility
- Canonical envelope stable since 7.10. Minor updates add args/fields without breaking existing ones.
- Firefox ≥ 110. Chrome (MV3) planned.
- HTTPS-only; blocked:
http://,file://,javascript:, and local/LAN ranges (see the LAN page).
Next Pages
| Page | Description |
|---|---|
| Start | Overview, how it works, setup, quick start, and links to all sections. |
| Detect the Extension | Detection contract (ping/pong), install prompts, and graceful fallbacks when the extension isn’t present. |
| Allow-list & Permissions | Deny-by-default model, domain allow-list via popup, and suggested UX to guide users to enable hosts. |
| LAN / Localhost | How to safely enable intranet/localhost (flags + allow-list). |
| Remote Tab Control | Open/navigate/focus the controlled tab, read URL/title, select an existing tab, lifecycle & restore patterns. |
| DOM & Automation | Action catalog (type, setValue, click, select, submit, waitFor) and safe interaction tips. |
| Recipes & Flows | Copy-paste flows: resilient login, dashboard checks, table waits, filters, playlists, and allow-list banners. |
| Events | Event stream reference, subscription helpers, live logger widget, and basic metrics/durations collection. |
| Diagnostics | Inline console, error cookbook, QA self-check, and performance tips for troubleshooting flows quickly. |
| Full API Reference | Canonical message envelopes, request/response schemas, error codes, and return shapes for every action. |
| Compatibility | Supported browsers/versions, permissions nuances, CSP/iframe notes, and known limitations or workarounds. |
| Advanced Patterns | Idempotent flows, retries/backoff, state restore after reload, playlist strategies, and robust selectors. |
| Favorites | Star and group URLs, quick actions (open/focus/navigate), export/import sets, and playlist runs from favorites. |
| Real-World Flows (E2E) | Run end-to-end flows from your admin page: helper setup, modern message contract, copy-paste journeys (login, multi-tab, extract), lightweight assertions, best practices, and troubleshooting. |
Need help writing safe flows?