SOP: connect contact forms with Orbitype, Vercel and SendGrid
A practical guide to send reliable contact notifications from Nuxt forms on Vercel with SendGrid, with optional contact storage in Orbitype.
To connect a Nuxt contact form with SendGrid and Orbitype safely, keep one principle in place: the browser sends data only to your server; the server validates it, sends the notification, and optionally stores it. That keeps secrets out of the client and prevents an optional database failure from hiding a valid lead.
This SOP is for Nuxt 3 sites using Orbitype headless and deployed on Vercel. The intended result is a POST /api/contacts route that notifies SENDGRID_TO_EMAIL and can insert a submission into a contacts table.
Quick answer: the recommended architecture
Visitor
→ site form
→ Nuxt/Vercel POST /api/contacts
→ SendGrid Mail Send → lead inbox
→ Orbitype SQL (optional) → contacts table
The server route is the only place that knows SENDGRID_API_KEY and the Orbitype SQL key. Set the submitter’s email as Reply-To; do not use it as the sender because SendGrid requires the sender to be verified.
What you need before starting
- A form that sends JSON to
POST /api/contacts. - A SendGrid account with a Mail Send API key.
- A SendGrid-verified sender address or domain.
- Local and Vercel environment variables.
- Orbitype SQL access only if submissions need to be stored.
If your form already connects to an email audience, apply the same server-side integration principle described in this secure form-to-email procedure: private keys must never be included in JavaScript downloaded by visitors.
1. Configure SendGrid correctly
Create an API key in Settings → API Keys with the minimum Mail Send permission. Then verify the address—or preferably the domain—you will use as SENDGRID_FROM_EMAIL in Settings → Sender Authentication.
The route needs these variables:
| Variable | Purpose |
|---|---|
SENDGRID_API_KEY | Authenticates Mail Send requests. |
SENDGRID_FROM_EMAIL | A SendGrid-verified sender address. |
SENDGRID_FROM_NAME | Display name for the notification. |
SENDGRID_TO_EMAIL | Inbox that receives new leads. |
A 403 response or an unverified-sender message nearly always means SENDGRID_FROM_EMAIL has no valid identity. While the client’s domain is being verified, temporarily use an address already approved in the same SendGrid account.
2. Make Orbitype optional contact storage
Email delivery is the critical outcome: it prevents a lead from being missed. Orbitype adds a searchable copy of the submission, but its unavailability should not turn a valid form submission into an error for the visitor.
The SQL integration uses these variables:
ORBITYPE_MOCK=false
ORBITYPE_API_SQL_URL="https://core.orbitype.com/api/sql/v1"
ORBITYPE_API_SQL_KEY="your-orbitype-sql-key"
If needed, create a table that reflects the form’s actual payload:
CREATE TABLE IF NOT EXISTS contacts (
id varchar(255) DEFAULT uid() PRIMARY KEY,
first_name text DEFAULT ''::text,
last_name text DEFAULT ''::text,
email text DEFAULT ''::text,
phone text DEFAULT ''::text,
interest text DEFAULT ''::text,
learner_type text DEFAULT ''::text,
message text DEFAULT ''::text,
created_at timestamptz DEFAULT CURRENT_TIMESTAMP
);
Keep form field names, API validation, and database columns aligned. If interest becomes a different field, update all three places in the same change.
3. Use the same environment contract locally and in production
Use real values in your local .env only; that file must not be committed. Keep the names and safe placeholders in .env.example:
# SendGrid
SENDGRID_API_KEY="SG...."
SENDGRID_FROM_EMAIL="verified-sender@example.com"
SENDGRID_FROM_NAME="Site name"
SENDGRID_TO_EMAIL="leads@example.com"
# Orbitype: optional when contacts are stored
ORBITYPE_MOCK=false
ORBITYPE_API_SQL_URL="https://core.orbitype.com/api/sql/v1"
ORBITYPE_API_SQL_KEY="your-sql-api-key"
In Vercel, add the same set under Settings → Environment Variables for Production and, if forms are reviewed before release, Preview too. Then create a new deployment: adding a variable does not update an existing deployment.
4. Required behavior for POST /api/contacts
The route should validate required fields before contacting external services. Once validation succeeds, send the email and store the contact when Orbitype is enabled. If email delivery fails, return a clear error rather than pretending the lead was received. If email succeeds but storage fails, keep the success response and record the storage state safely.
A useful response distinguishes the outcomes:
{
"ok": true,
"emailed": true,
"stored": false
}
Never return keys, full provider payloads, or internal implementation details to the browser. In server logs, avoid retaining messages or personal data longer than necessary.
5. Test the complete flow
Restart Nuxt after editing environment values. Then send a controlled request to your local route:
curl -s -X POST http://127.0.0.1:3000/api/contacts \
-H "Content-Type: application/json" \
-d '{
"first_name": "Test",
"last_name": "User",
"email": "you@example.com",
"phone": "+41 00 000 00 00",
"interest": "example",
"learner_type": "example",
"message": "Connectivity test"
}'
Confirm these points in order:
- The API returns
ok: trueandemailed: true. - The configured inbox receives the message and staff can reply directly to the submitter.
- When Orbitype is enabled, the expected row exists in
contacts. - After deploying on Vercel, repeat the test through the public form.
Common issues and fixes
| Symptom | Likely cause | Recommended action |
|---|---|---|
SendGrid returns 403 | Sender is not verified | Verify the domain or use an approved FROM address. |
400 for missing fields | Payload does not match the route | Check field names, types, and form validation. |
emailed: true, stored: false | Missing table or SQL key | Create contacts and configure Orbitype variables. |
| Works locally but not on Vercel | Missing values or old deployment | Configure Production/Preview and redeploy. |
| Email does not arrive | Wrong inbox, spam, or delay | Check Spam, SENDGRID_TO_EMAIL, and SendGrid activity. |
Go-live checklist
- SendGrid Mail Send API key created.
-
SENDGRID_FROM_EMAILverified. -
SENDGRID_*available locally and in Vercel. - Orbitype SQL table and key configured when needed.
- Field validation and
Reply-Toimplemented in the route. - Local test confirms email delivery and, when applicable, storage.
- Production was redeployed after secrets were configured.
- No
.envfile or API key was added to Git.
The implementation is reliable when the visitor receives an honest outcome, the team receives the lead, and optional services never silence a valid contact request. Keeping that priority order protects both the operation and its credentials.