Brand Studio docs
Engineering manualAPI route source

/api/brands/export

Exact current route handler: hosted-app/app/api/brands/export/route.js

Methods: GET. Input signals: query parameters. Literal response-status signals: 200.

Source: hosted-app/app/api/brands/export/route.js. Imports: ../../../../lib/brand-monitoring-export.mjs, ../../../../lib/comprehensive-pull.mjs, ../../../../lib/supabase-rest.mjs, next/server. Exact source is shown for inspection; its presence does not prove authentication, validation or live behavior.

All API routes · API and execution contract

// GET /api/brands/export?domain=&format=md|json — a monitoring summary for one
// brand in one document: basics, homepage changes, website pages and changed
// pages, social, search, schedules and reports. Markdown for a person or an
// LLM, JSON with explicit coverage/omissions for tools. Not a complete evidence export. Sessions and API keys with read_reports. Reads saved
// data only. See lib/brand-monitoring-export.mjs.

import { NextResponse } from "next/server";
import { supabaseConfigFromEnv } from "../../../../lib/supabase-rest.mjs";
import { bearerTokenFromHeader } from "../../../../lib/comprehensive-pull.mjs";
import { buildBrandExport, brandExportFileName } from "../../../../lib/brand-monitoring-export.mjs";

export const runtime = "nodejs";
export const dynamic = "force-dynamic";
export const maxDuration = 60;

const PRIVATE = { "cache-control": "private, no-store", "x-content-type-options": "nosniff" };

export async function GET(request) {
  const url = new URL(request.url);
  const format = url.searchParams.get("format") === "json" ? "json" : "md";
  const result = await buildBrandExport({ token: bearerTokenFromHeader(request.headers.get("authorization")), config: supabaseConfigFromEnv(process.env),
    domain: url.searchParams.get("domain") || "", baseUrl: process.env.BRAND_STUDIO_PUBLIC_URL || url.origin });
  if (!result.ok) return NextResponse.json(result.body, { status: result.http_status, headers: PRIVATE });
  const file = brandExportFileName(result.body.json.domain, format);
  const disposition = { "content-disposition": "attachment; filename=\"" + file + "\"" };
  if (format === "json") return new NextResponse(JSON.stringify(result.body.json, null, 2), { status: 200, headers: { ...PRIVATE, ...disposition, "content-type": "application/json; charset=utf-8" } });
  return new NextResponse(result.body.markdown, { status: 200, headers: { ...PRIVATE, ...disposition, "content-type": "text/markdown; charset=utf-8" } });
}