Caddi
Sign inSign up

Getting started with Forms

Every Caddi project gets one form endpoint by default. You can add more from the dashboard. Each one has its own ID, rate limit, and webhooks.

1. Find your endpoint URL

The default project form endpoint is created at scaffold. You’ll find it as NEXT_PUBLIC_CADDI_FORM_URL in your dev environment. Or:

bash
caddi project info --json | jq .form_endpoint
# https://forms.caddi.build/api/f/fm_01H9X4K2P3JR

2. Wire it up with the SDK

ts
'use client';
import { submit } from '@caddi/forms-sdk';

export function ContactForm() {
  return (
    <form
      onSubmit={async (e) => {
        e.preventDefault();
        const fd = new FormData(e.currentTarget);
        const res = await submit({
          endpoint: process.env.NEXT_PUBLIC_CADDI_FORM_URL!,
          fields: Object.fromEntries(fd.entries()),
        });
        if (res.ok) location.assign('/thanks');
      }}
    >
      <input name="name"    required />
      <input name="email"   required type="email" />
      <textarea name="message" required />
      <button type="submit">Send</button>
    </form>
  );
}

3. (Or) call the raw endpoint

bash
curl -X POST $NEXT_PUBLIC_CADDI_FORM_URL \
  -H "content-type: application/json" \
  -d '{"name":"Alicia","email":"[email protected]","message":"hi"}'

# { "ok": true, "id": "sub_01H9X4K2P3JR4HX7" }

Full HTTP reference: POST /api/f/[id].

4. Watch the inbox

Submissions land at app.caddi.build/<agency>/forms/<project> in real time. Reply, export, or fire a webhook from there.

The default per-IP rate limit is 30 / 5 minutes. The default honeypot field is __website — leave it empty in your form HTML; bots will fill it and get silently spammed.

Next

Submissions →