Mighty
Why MightyCitadel
Use cases
LendingIncome files before you fundInsuranceAppraisals to claim photosClaimsPhotos and estimates at first noticeAll use cases
SecurityDocsLog in
See it on your files

Docs

Direct SaaS purchase is no longer offered

New commercial terms are enterprise or custom, scoped on a call.

See it on your files
Browse docs
Start Here
Citadel Docs5-Minute QuickstartMighty PlatformUse CasesFAQ
Core Concepts
How Citadel WorksModalities And AttacksModes And ToleranceChoose Scan SettingsGlossarySessions And Scan GroupsDriftBilling, SCU, And Limits
Integration Guides
Integration GuidesMultimodal SupportScan Text And OCR OutputScan File UploadsDamage Photo AI Fraud ReviewScan Model OutputAsync Deep ScansError Handling
Frameworks
Framework Integration MapVercel AI SDK Chat GuardrailNext.js Upload GuardrailBackend API HelpersDocument Processing PipelineLangChain + LangGraph Guardrail
Workflows
Workflow Playbooks
API Reference
POST /v1/scan
Use With AI
Use With AI
Start Here
Citadel Docs5-Minute QuickstartMighty PlatformUse CasesFAQ
Core Concepts
How Citadel WorksModalities And AttacksModes And ToleranceChoose Scan SettingsGlossarySessions And Scan GroupsDriftBilling, SCU, And Limits
Integration Guides
Integration GuidesMultimodal SupportScan Text And OCR OutputScan File UploadsDamage Photo AI Fraud ReviewScan Model OutputAsync Deep ScansError Handling
Frameworks
Framework Integration MapVercel AI SDK Chat GuardrailNext.js Upload GuardrailBackend API HelpersDocument Processing PipelineLangChain + LangGraph Guardrail
Workflows
Workflow Playbooks
API Reference
POST /v1/scan
Use With AI
Use With AI
Loading docs…
Mighty

Citadel is Mighty's product. It finds generated or AI-edited fakes in customer files.

See it on your files

Platform

  • For Lending
  • For Insurance
  • For Claims
  • Product
  • Use Cases
  • Contact
  • Docs

Company

  • Why Mighty
  • Blog

Trust

  • Security
  • Status
  • Privacy
  • Terms
© 2026 Nine Suns Inc. All rights reserved.Citadel, from Mighty

Next.js Upload Guardrail

Scan browser uploads in a Next.js Route Handler before storage, OCR, extraction, or review.

Goal

Use this page when a browser uploads a file to your Next.js app.

This page proves one product flow:

browser upload -> Next.js server route -> Citadel scan -> store, quarantine, or reject

The point is not Next.js itself. The point is keeping the API key server-side and making sure files are scanned before storage, OCR, AI extraction, or review queues trust them.

When To Use This

Use it for:

  • Claim packet uploads.
  • Invoice or repair estimate uploads.
  • Damage photos uploaded through a web form.
  • Support attachments.
  • Any file that will later go to OCR, AI extraction, search, or workflow automation.

Architecture

  1. Browser posts the file to your Next.js route.
  2. The route forwards the file to Citadel with server-side auth.
  3. Citadel returns ALLOW, WARN, or BLOCK.
  4. The route stores, quarantines, or rejects the file.
  5. Downstream OCR or AI only runs after routing.

Route Handler

export const runtime = "nodejs";

export async function POST(request: Request) {
  const incoming = await request.formData();
  const file = incoming.get("file");

  if (!(file instanceof File)) {
    return Response.json({ error: "file is required" }, { status: 400 });
  }

  const mightyForm = new FormData();
  mightyForm.append("file", file);
  mightyForm.append("content_type", "auto");
  mightyForm.append("scan_phase", "input");
  mightyForm.append("mode", "secure");
  mightyForm.append("focus", "steg");
  mightyForm.append("data_sensitivity", "tolerant");

  const scanResponse = await fetch("https://gateway.trymighty.ai/v1/scan", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.MIGHTY_API_KEY}`,
    },
    body: mightyForm,
  });

  if (!scanResponse.ok) {
    return Response.json(
      { error: "upload scan failed" },
      { status: scanResponse.status },
    );
  }

  const scan = await scanResponse.json();

  if (scan.action === "BLOCK") {
    return Response.json(
      { error: "upload blocked", scan_id: scan.scan_id },
      { status: 400 },
    );
  }

  if (scan.action === "WARN") {
    await saveUploadForReview(file, scan);
    return Response.json({ status: "review", scan_id: scan.scan_id });
  }

  await saveUploadForProcessing(file, scan);
  return Response.json({ status: "accepted", scan_id: scan.scan_id });
}

Routing Logic

async function saveUploadForReview(file: File, scan: { scan_id: string }) {
  // Store in quarantine or a restricted bucket.
}

async function saveUploadForProcessing(file: File, scan: { scan_id: string }) {
  // Store normally and enqueue OCR or extraction.
}

Common Mistake

Do not call Citadel directly from the browser. The upload route should proxy the file so your API key stays server-side.

Do not store first and scan later unless the storage location is quarantine-only. The safer default is scan first, then store normally only after routing.

Acceptance Criteria

  • Missing file returns 400.
  • Citadel BLOCK prevents normal storage.
  • Citadel WARN stores to review or quarantine.
  • Citadel ALLOW stores and continues processing.
  • Logs include scan_id.
Next step

Ready to scan real traffic?

Book a working session on your files. Starting October 1, 2026, new commercial terms are enterprise or custom.

See it on your filesHandle limits

AI-Agent Prompt

AI-ready prompt
Add a Next.js upload guardrail

Paste this into Cursor, Codex, Claude Code, or Windsurf.

Add Citadel to a Next.js App Router upload endpoint.

Requirements:
- Use runtime=nodejs.
- Parse request.formData().
- Require a file field.
- Forward the file to POST https://gateway.trymighty.ai/v1/scan with multipart form data.
- Use content_type=auto, scan_phase=input, mode=secure, focus=steg, data_sensitivity=tolerant for mixed uploads. Use focus=all only after routing known image/PDF evidence that needs authenticity or edit review.
- Route BLOCK to reject or quarantine.
- Route WARN to quarantine and review.
- Route ALLOW to normal storage and processing.
- Store scan_id and scan_group_id with the upload record.

Acceptance criteria:
- API key only exists server-side.
- Tests cover missing file, ALLOW, WARN, BLOCK, and Citadel error status.

On this page

GoalWhen To Use ThisArchitectureRoute HandlerRouting LogicCommon MistakeAcceptance CriteriaAI-Agent Prompt