/** * Admin API read-only tour with the official Node SDK (openai@7.18): users, projects, audit logs, usage, costs. * STATUS: ACCOUNT_RESTRICTED — run 2026-09-18 with our project key: every call rejected with * PermissionDeniedError 403 "Missing scopes: api.management.read"/"api.usage.read" (audit logs: AuthenticationError 401). * With OPENAI_ADMIN_KEY set the same code prints real data. Never mutates anything. * Run: node --env-file=.env examples/openai/admin/admin_readonly.ts */ import OpenAI from "openai"; import { appendFileSync } from "node:fs"; const client = new OpenAI({ adminAPIKey: process.env.OPENAI_ADMIN_KEY ?? process.env.OPENAI_API_KEY, maxRetries: 0 }); const start = Math.floor(Date.now() / 1000) - 7 * 86400; const mask = (s: string) => s.replace(/sk-(ant-)?[A-Za-z0-9_-]{8,}/g, "sk-***REDACTED***"); const log = (method: string, path: string, status: number, note: string) => appendFileSync("reports/live-requests.jsonl", JSON.stringify({ ts: new Date().toISOString().replace(/\.\d+Z$/, "Z"), provider: "openai", method, path, status, est_cost_usd: 0, note: mask(note) }) + "\n"); async function attempt(label: string, path: string, fn: () => Promise) { try { const out = await fn(); log("GET", path, 200, `admin example ${label}`); console.log(200, label, JSON.stringify(out).slice(0, 200)); } catch (e) { if (e instanceof OpenAI.APIError) { log("GET", path, e.status ?? 0, `admin example ${label}: ${e.constructor.name}`); console.log(e.status, label, e.constructor.name, `code=${e.code}`, `requestID=${e.requestID}`, mask(String(e.message)).slice(0, 160)); } else throw e; } } await attempt("users", "/v1/organization/users", async () => (await client.admin.organization.users.list({ limit: 5 })).data.map((u) => u.email)); await attempt("projects", "/v1/organization/projects", async () => (await client.admin.organization.projects.list({ limit: 5 })).data.map((p) => [p.id, p.name, p.status])); await attempt("audit_logs", "/v1/organization/audit_logs", async () => (await client.admin.organization.auditLogs.list({ limit: 5 })).data.map((a) => a.type)); await attempt("usage.completions", "/v1/organization/usage/completions", async () => (await client.admin.organization.usage.completions({ start_time: start, bucket_width: "1d", group_by: ["model"], limit: 7 })).data.map((b) => [b.start_time, b.results.length])); await attempt("costs", "/v1/organization/costs", async () => (await client.admin.organization.usage.costs({ start_time: start, bucket_width: "1d", group_by: ["line_item"], limit: 7 })).data.map((b) => [b.start_time, b.results.length]));