Skip to content

How do I get the raw body of a Serverless Function?

You can use Vercel Serverless Functions to recieve webhooks from third-party services like Stripe. Certain providers require access to the raw body inside the function to validate the signature from the request.

With Node.js

import type { VercelRequest, VercelResponse } from '@vercel/node';
import type { Readable } from 'node:stream';

export const config = {
  api: {
    bodyParser: false,
  },
};

async function buffer(readable: Readable) {
  const chunks = [];
  for await (const chunk of readable) {
    chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk);
  }
  return Buffer.concat(chunks);
}

export default async function (req: VercelRequest, res: VercelResponse) {
  if (req.method === 'POST') {
    const buf = await buffer(req);
    const rawBody = buf.toString('utf8');

    res.json({ rawBody });
  } else {
    res.setHeader('Allow', 'POST');
    res.status(405).end('Method Not Allowed');
  }
}

A Node.js Serverless Function that returns the raw body sent.

With Next.js

When using Next.js API Routes deployed as Serverless Functions on Vercel, you need to change your code to use the native Next.js types.

- import type { VercelRequest, VercelResponse } from '@vercel/node'
+ import type { NextApiRequest, NextApiResponse } from 'next'


- export default async function (req: VercelRequest, res: VercelResponse) {
+ export default async function (req: NextApiRequest, res: NextApiResponse) {

Switching the imported types to use Next.js.

Testing Locally

You can verify your function can accept and parse raw bodies locally:

  1. Start your local development server with vercel dev (or next dev).
  2. In another terminal window, run the cURL command below.
$ curl -X POST -H "Content-Type: text/plain" --data "This is raw data" http://localhost:3000/api/test

A sample cURL command to make a POST request to your function.

You should see a response like {"rawBody": "This is raw data"}.

Couldn't find the guide you need?