Submit a form via raw HTTP. JSON or multipart. The endpoint id is per-project.
JSON
bash
curl -X POST https://forms.caddi.build/api/f/fm_01H9X4K2P3JR \
-H "content-type: application/json" \
-H "idempotency-key: $(uuidgen)" \
-d '{"name":"Alicia","email":"[email protected]","message":"hi"}'
# 200 OK
{ "ok": true, "id": "sub_01H9X4K2P3..." }
Multipart (with files)
bash
curl -X POST https://forms.caddi.build/api/f/fm_01H9X4K2P3JR \
-H "idempotency-key: $(uuidgen)" \
-F "name=Alicia" \
-F "[email protected]" \
-F "message=here is my resume" \
-F "attachment=@./resume.pdf"
Headers
content-type — required. application/json or multipart/form-data.idempotency-key — strongly recommended. Submitting the same key twice within 24h returns the original submission.x-caddi-honeypot — optional. Passing any value silently routes the submission to Spam.
Responses
json · 200 OK
{
"ok": true,
"id": "sub_01H9X4K2P3JR4HX7"
}
json · 422 Unprocessable
{
"ok": false,
"errors": {
"email": "must be a valid email address"
}
}
json · 429 Too many requests
{
"ok": false,
"error": "rate_limited",
"retryAfter": 60
}
Rate limits
Per-IP and per-endpoint. Defaults: 30 requests / 5 minutes / IP. Configurable per-form. The 429 response includes retry-after in seconds.