> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getsabo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Contact Form API

> Learn how to customize the backend API endpoint for the contact form, including server-side validation and submission handling.

<Info>
  This endpoint receives contact form submissions, validates input with Zod, and returns a JSON response. It does not require authentication by default.
</Info>

This API endpoint receives and processes submissions from the frontend contact form. It's responsible for server-side validation and handling the submitted data.

* **Endpoint**: `POST /api/contact`
* **File Location**: `src/app/api/contact/route.ts`

## Parameters

<ParamField body="firstName" type="string">
  Sender's first name. Minimum length: 2.
</ParamField>

<ParamField body="lastName" type="string">
  Sender's last name. Minimum length: 2.
</ParamField>

<ParamField body="email" type="string">
  Valid email address for reply.
</ParamField>

<ParamField body="company" type="string">
  Company or organization name. Minimum length: 2.
</ParamField>

<ParamField body="message" type="string">
  Message content. Minimum length: 10.
</ParamField>

## Request/Response

#### Example Request

```bash theme={null}
curl -X POST 'http://localhost:3000/api/contact' \
  -H 'Content-Type: application/json' \
  -d '{
    "firstName": "Jane",
    "lastName": "Doe",
    "email": "jane@example.com",
    "company": "Acme Inc",
    "message": "I would like to learn more about Sabo."
  }'
```

#### Example Response (Success)

```json theme={null}
{
  "success": true,
  "message": "Thank you for your message! We'll get back to you soon."
}
```

#### Example Response (Validation Error · 400)

```json theme={null}
{
  "success": false,
  "message": "Validation failed",
  "errors": [
    {
      "code": "too_small",
      "minimum": 2,
      "type": "string",
      "inclusive": true,
      "exact": false,
      "message": "First name must be at least 2 characters",
      "path": ["firstName"]
    }
  ]
}
```

#### Example Response (Server Error · 500)

```json theme={null}
{
  "success": false,
  "message": "An error occurred while processing your request"
}
```

## How It Works

1. **Receives Data**: The endpoint accepts a `POST` request with a JSON body containing the form data.
2. **Validates Data**: It uses a Zod schema to perform server-side validation. This is a crucial security step to ensure data integrity. If validation fails, it returns a `400 Bad Request` error.
3. **Processes Data**: By default, the endpoint logs the validated data to the server console.
4. **Returns Response**: On success, it returns a `200 OK` response with a success message.

## Customizing the Submission Logic

To make the contact form useful, you need to replace the default `console.log` action with your own business logic. A common use case is to send an email notification.

### Example: Sending an Email with Resend

Here's how you can modify the endpoint to send an email using [Resend](https://resend.com/), a popular email service for React developers.

<Steps>
  <Step title="Install Resend">
    First, add the Resend package to your project.

    ```bash theme={null}
    pnpm add resend
    ```
  </Step>

  <Step title="Get API Key">
    Sign up for a Resend account and get your API key. Add it to your `.env.local` file.

    ```bash .env.local theme={null}
    RESEND_API_KEY=your_api_key_here
    ```
  </Step>

  <Step title="Update the API Endpoint">
    Modify the `route.ts` file to import Resend and use it to send an email with the form data.

    ```ts src/app/api/contact/route.ts theme={null}
    import { NextResponse } from "next/server";
    import { z } from "zod";
    import { Resend } from "resend";

    // Initialize Resend
    const resend = new Resend(process.env.RESEND_API_KEY);

    const contactFormSchema = z.object({
      firstName: z.string().min(2),
      lastName: z.string().min(2),
      email: z.string().email(),
      company: z.string().optional(),
      message: z.string().min(10),
    });

    export async function POST(request: Request) {
      try {
        const body = await request.json();
        const data = contactFormSchema.parse(body);

        // Replace console.log with email sending logic
        await resend.emails.send({
          from: 'onboarding@resend.dev', // Your verified sending email
          to: 'your-personal-email@example.com', // Your personal email to receive notifications
          subject: `New Contact Form Submission from ${data.firstName}`,
          text: `Name: ${data.firstName} ${data.lastName}\nEmail: ${data.email}\nCompany: ${data.company || 'N/A'}\nMessage: ${data.message}`,
        });

        return NextResponse.json({ message: "Form submitted successfully!" });
      } catch (error) {
        if (error instanceof z.ZodError) {
          return NextResponse.json({ error: error.errors }, { status: 400 });
        }
        return NextResponse.json({ error: "Something went wrong" }, { status: 500 });
      }
    }
    ```
  </Step>
</Steps>

<Tip>
  You can also use this endpoint to save submissions to a database, post to a Slack channel, or integrate with any other service.
</Tip>

<Note>
  Resend is optional and not bundled by default. This example shows how you can wire it if you need email notifications. For global route protection vs per‑route guards, see <a href="/core-features/routing-and-middleware">Routing & Middleware</a>.
</Note>
