. Or use the REST API directly with POST /v1/verify."}},{"@type":"Question","name":"Is there a free tier?","acceptedAnswer":{"@type":"Answer","text":"Yes. Get an API key instantly with no signup required. The free tier includes 1,000 verifications per day (30,000/month). No credit card needed."}},{"@type":"Question","name":"What signals does Device.AI analyze?","acceptedAnswer":{"@type":"Answer","text":"Device.AI analyzes user agent, automation framework presence (Selenium, Puppeteer, PhantomJS, etc.), canvas fingerprint, WebGL renderer, screen resolution, timezone, hardware concurrency, browser feature support, and connection type."}}]}]}
← Back to Blog
Next.jsBot DetectionAPIDeveloper Tools

Next.js Bot Detection: How to Protect API Routes and Server Actions in 2026

·10 min read·Device.AI Engineering

Next.js has three main surfaces that attract bot abuse: API routes, Server Actions, and edge middleware. Each has different constraints for adding bot detection, and each needs a slightly different integration approach. This guide covers all three.

Why Next.js Apps Are Common Bot Targets

Server Actions in particular are attractive to bots because they're easy to call directly with a POST request once the action ID is known, bypassing any client-side UI entirely. Form endpoints, waitlist signups, and checkout flows built with Server Actions routinely see credential-stuffing and scraping traffic that never touches the rendered page.

Option 1: Edge Middleware (Broadest Coverage)

Middleware runs before any route handler, making it the right place for blanket protection on high-risk paths:

// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export async function middleware(req: NextRequest) {
  const res = await fetch('https://device.ai/v1/verify', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.DEVICE_AI_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      ip: req.headers.get('x-forwarded-for'),
      userAgent: req.headers.get('user-agent'),
    }),
  });
  const { botScore } = await res.json();
  if (botScore > 0.85) {
    return new NextResponse('Forbidden', { status: 403 });
  }
  return NextResponse.next();
}

export const config = { matcher: ['/api/:path*', '/checkout/:path*'] };

Option 2: API Route Handlers

For finer-grained control (e.g., different thresholds per endpoint), call device.ai inside the route handler itself:

// app/api/signup/route.ts
import { NextRequest, NextResponse } from 'next/server';

export async function POST(req: NextRequest) {
  const verifyRes = await fetch('https://device.ai/v1/verify', {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${process.env.DEVICE_AI_KEY}` },
    body: JSON.stringify({ ip: req.headers.get('x-forwarded-for') }),
  });
  const { botScore } = await verifyRes.json();
  if (botScore > 0.8) {
    return NextResponse.json({ error: 'Request blocked' }, { status: 403 });
  }
  // proceed with signup logic
}

Option 3: Server Actions

Server Actions don't have direct access to request headers by default in all cases, so pass along what you can capture client-side (or use headers() from next/headers where available) and verify before mutating state:

// app/actions.ts
'use server';
import { headers } from 'next/headers';

export async function submitWaitlist(formData: FormData) {
  const hdrs = headers();
  const verifyRes = await fetch('https://device.ai/v1/verify', {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${process.env.DEVICE_AI_KEY}` },
    body: JSON.stringify({ ip: hdrs.get('x-forwarded-for'), userAgent: hdrs.get('user-agent') }),
  });
  const { botScore } = await verifyRes.json();
  if (botScore > 0.85) throw new Error('Request blocked');
  // proceed with mutation
}

Choosing Thresholds

Start conservative (block only botScore > 0.9) on customer-facing forms to avoid false positives, and tighten on endpoints with a history of abuse (waitlists, coupon codes, referral programs) where the cost of a false positive is low.

Get Started

Get a free API key at device.ai — no signup required — and add verification to your first route in minutes.

Ready to stop bots?

Get a free API key instantly. No signup, no credit card.

Get Free API Key →