SDK API Reference
The TypeScript-level contract for the open beta SDK and the current runtime behavior behind each method.
Global Declaration
The browser runtime injects globalThis.airglow before app code runs. Invited app developers should include the declaration file from airglow-apps/airglow.d.ts in local app workspaces.
interface AirglowFetchResponse<T = any> {
status: number;
ok: boolean;
json(): Promise<T>;
text(): Promise<string>;
}
interface AirglowWindowOptions {
width?: number;
height?: number;
popup?: boolean;
}
interface AirglowRedirectRule {
domains: string[];
target: string;
}
interface AirglowError extends Error {
name: "AirglowError";
code?: string;
status?: number;
requestId?: string;
details?: any;
}
interface Airglow {
sdkVersion: "0.1.0-beta.1";
fetch<T = any>(
url: string,
opts?: RequestInit & { includeCookies?: boolean },
): Promise<AirglowFetchResponse<T>>;
storage: {
get<T = any>(key: string): Promise<T | undefined>;
set(key: string, value: any): Promise<void>;
delete(key: string): Promise<void>;
list(): Promise<string[]>;
};
log: {
info(message: string, data?: any): Promise<void>;
warn(message: string, data?: any): Promise<void>;
error(message: string, data?: any): Promise<void>;
};
rpc<T = any>(functionName: string, payload?: any): Promise<T>;
identity: {
getRedirectURL(): Promise<string>;
launchWebAuthFlow(url: string): Promise<string>;
};
openWindow(url: string, opts?: AirglowWindowOptions): Promise<void>;
openWindowAndWaitClose(url: string, opts?: AirglowWindowOptions): Promise<void>;
platform: {
registerRedirects(rules: AirglowRedirectRule[]): Promise<void>;
allowIframes(domains: string[], initiators?: string[]): Promise<void>;
};
}
declare const airglow: Airglow;airglow.fetch
| Mode | Cookies | CORS | Requirement | Use for |
|---|---|---|---|---|
Native fetch | Browser default | Enforced | None | Same-origin or normal web requests from app code. |
airglow.fetch(url) | No | Bypassed by service worker fetch | URL must be reachable by extension/server runtime | Third-party APIs without user session cookies. |
airglow.fetch(url, { includeCookies: true }) | Yes | Runs in target page context | Matching host_permissions | Authenticated browser-session requests to a site the user is logged into. |
const res = await airglow.fetch("https://api.example.com/items", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ limit: 10 }),
});
if (!res.ok) {
await airglow.log.warn("API failed", { status: res.status });
}
const data = await res.json();Cookie mode is permissioned
includeCookies: true is rejected unless the app manifest has a matching host_permissions entry. The extension may create a background tab on the target origin if no matching tab is already open.
airglow.storage
Storage is app-scoped in chrome.storage.local with the airglow:app:{appId}: prefix. UI, userscripts, and startup share the same app namespace.
await airglow.storage.set("draft", { title: "Release notes" });
const draft = await airglow.storage.get<{ title: string }>("draft");
await airglow.storage.delete("draft");
const keys = await airglow.storage.list();Client settings use storage.get
For keys declared in manifest secrets, airglow.storage.get(key) reads the user secret first and the dev secret fallback second. This is the current beta behavior and should be renamed or documented carefully before wider release.
airglow.log
Use SDK logs for app-observable events and recoverable failures. The SDK also captures uncaught errors and unhandled promise rejections and forwards them as error logs.
await airglow.log.info("import_started", { count: rows.length });
await airglow.log.warn("rate_limit_retry", { attempt, waitMs });
await airglow.log.error("import_failed", { reason: error.message });airglow.rpc
airglow.rpc(name, payload) calls POST /api/apps/:appId/rpc/:name on the app server. Server functions should be used for server secrets, shared provider keys, OAuth exchange, and rate-limited model calls.
// airglow-apps/hn-tagger/server/tag.ts
export default async function tag(payload: { titles: string[] }) {
const apiKey = process.env.ANTHROPIC_API_KEY;
if (!apiKey) {
throw new Error("ANTHROPIC_API_KEY is not configured");
}
return {
titles: payload.titles,
generatedAt: new Date().toISOString(),
};
}
// userscripts/hn.ts or ui/App.tsx
const result = await airglow.rpc("tag", { titles });RPC error behavior
Transport failures and HTTP 4xx/5xx responses reject with AirglowError. The error can include code, status, requestId, and details. Server functions that intentionally return { error } with HTTP 200 are still returned as normal values.
Identity, Windows, Platform
| API | Purpose | Notes |
|---|---|---|
airglow.identity.getRedirectURL() | Return Chrome extension OAuth redirect URL. | Use when building OAuth authorization URLs. |
airglow.identity.launchWebAuthFlow(url) | Open auth popup and resolve with final redirect URL. | Rejects if the user closes the popup. |
airglow.openWindow(url, opts) | Open a centered Chrome popup or normal window. | Use instead of window.open from userscripts. |
airglow.openWindowAndWaitClose(url, opts) | Open a window and wait until it closes. | Useful for OAuth or external review flows. |
airglow.platform.registerRedirects(rules) | Register app-owned redirect rules. | Call from idempotent startup code. |
airglow.platform.allowIframes(domains, initiators?) | Allow selected iframe domains by relaxing response headers. | Privileged beta capability. Keep the domain list narrow. |