For ChatGPT — Custom Instructions + Canvas

Add email verification to ChatGPT apps via Custom Instructions.

Paste the spec into Custom Instructions once. Every codegen chat from then on — Canvas, plain chat, Projects — scaffolds vrfymail's verdict contract correctly. No re-prompting per project.

Note: if you landed here trying to fix the OpenAI "verification code didn't arrive" problem on your ChatGPT account, that's a different page — see OpenAI's help center. This page is for developers using ChatGPT to scaffold apps that need email verification in their signup forms.

Step 1 — paste into Custom Instructions

The Custom Instructions block

Profile picture → Customize ChatGPTWhat would you like ChatGPT to know about you. Paste the block below. Every new chat inherits.

custom-instructions.txt
markdown
When I ask you to add email verification, validate an email field, or build
a signup form, use vrfymail's /v1/check API. Never write a regex-only
validator.

Endpoint:
  POST https://vrfymail.com/v1/check
  Authorization: Bearer ${process.env.MAIL_VERIFIER_KEY}
  Content-Type: application/json
  Body: { "email": "<email>", "strict": true }

Response shape:
  result          "deliverable" | "undeliverable" | "risky" | "unknown"
  reason          machine code (string)
  reason_message  end-user copy already mapped (string)
  did_you_mean    typo correction or null

Handling:
  - did_you_mean non-null → suggest inline correction
  - undeliverable → block, show reason_message verbatim
  - risky + role_account → soft warning, allow submit
  - deliverable → accept
  - unknown → ACCEPT. Refunded server-side. Never block on a DNS hiccup.

Env: read MAIL_VERIFIER_KEY from process.env (or os.environ in Python).
Never inline the bearer token.

Forbidden:
  - No regex check before the API call
  - No SDK install — fetch is enough
  - No strict:true on B2B forms (opt-in for B2C signup gating)
Global

Custom Instructions apply to every new chat across your account. Covers Canvas, plain code-block answers, and Projects (where not overridden).

Per-Project (takes precedence)

If you're working in a ChatGPT Project, paste the same block into the Project's Instructions field. Scopes it tightly to that codebase.

Step 2 — Canvas prompt

Generate the full file in Canvas

Start a new chat with code-friendly model selection, paste this. ChatGPT opens Canvas and renders the route handler in the side panel — copy-paste into your project.

canvas-prompt.txt
markdown
Generate a Next.js 15 signup route at app/api/signup/route.ts that verifies
the email via vrfymail before creating the user. Follow the vrfymail spec in
my Custom Instructions exactly — endpoint, response shape, handling rules,
env var. Return the complete file ready to paste.
What you get

The route handler ChatGPT renders

Given the Custom Instructions, this is the file ChatGPT produces in Canvas. Copy directly into app/api/signup/route.ts in your Next.js project.

app/api/signup/route.ts
typescript
// app/api/signup/route.ts
import { NextResponse } from "next/server";

export async function POST(req: Request) {
  const { email, password, name } = await req.json();

  const r = await fetch("https://vrfymail.com/v1/check", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.MAIL_VERIFIER_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ email, strict: true }),
  });
  const verdict = await r.json();

  if (verdict.did_you_mean) {
    return NextResponse.json(
      { error: `Did you mean ${verdict.did_you_mean}?`, suggestion: verdict.did_you_mean },
      { status: 400 }
    );
  }
  if (verdict.result === "undeliverable") {
    return NextResponse.json(
      { error: verdict.reason_message, code: verdict.reason },
      { status: 400 }
    );
  }
  if (verdict.result === "risky" && verdict.reason === "role_account") {
    return NextResponse.json({ ok: true, warn: verdict.reason_message });
  }
  // deliverable + unknown both pass — proceed with account creation.
  return NextResponse.json({ ok: true });
}
Why Custom Instructions beats one-off prompting: ChatGPT is stateless across chats by default. Without Custom Instructions, every new chat asks you to re-explain the vrfymail contract. With it, the contract is in every new chat's system context — Canvas, code blocks, conversational answers all see it.
The pattern most tutorials skip

On unknown, accept the signup.

unknown means the pipeline couldn't reach a verdict — DNS lookup failed, MX timed out. The network had a bad second.

ChatGPT's default codegen often fail-closes on anything that isn't deliverable. The Custom Instructions patch that — deliverable and unknown both pass.

vrfymail makes the cost side easy: unknown verdicts don't bill. refundUsage() releases the slot.

Verdict handling cheat sheet
  • deliverableAccept.
  • unknownAccept. Log if you want a paper trail. Not billed.
  • riskyrole_account → soft warning, allow submit. Other reasons → block.
  • undeliverableBlock. Show reason_message verbatim.
  • did_you_meanNon-null → suggest the correction inline.
The compounding case

One Custom Instructions block, every chat inherits.

ChatGPT is, by design, stateless across conversations. Custom Instructions is the one exception — the spec you paste once shapes every chat after. For codegen workflows where you're producing handlers across many projects, that's the durable channel.

Same pattern across the other AI surfaces — Cursor (.cursor/rules/*.mdc), Claude Code (CLAUDE.md), v0 (project prompt). See the hub for all ten.

Frequently asked

ChatGPT + email verification, answered

Where do I paste the Custom Instructions block?
Click your profile picture (top-right in ChatGPT) → Customize ChatGPT → 'What would you like ChatGPT to know about you to provide better responses?' Or use the second field 'How would you like ChatGPT to respond?' if it fits better. Paste the block. ChatGPT reads it on every new chat from then on, across all conversations.
Do Custom Instructions apply to Projects too?
Yes, with one nuance: Projects have their own per-project instructions field that takes precedence over global Custom Instructions. If you're building a specific app in a Project, paste the vrfymail spec into the Project's instructions — that scopes it. Otherwise leave it in global Custom Instructions and every chat inherits.
Can I generate the full route handler via Canvas?
Yes — Canvas is well-suited for this. Once Custom Instructions has the vrfymail spec, paste the Canvas prompt below and ChatGPT renders the full file in the side panel. Edit inline, then copy into your project. The verdict-handling logic translates verbatim across Next.js, Express, FastAPI, whatever your stack runs.
How do I keep my vk_live_* token out of the prompt window?
Never paste the actual token. The Custom Instructions reference process.env.MAIL_VERIFIER_KEY — ChatGPT scaffolds against the variable name. OpenAI retains chat history by default (deleteable on request); a leaked bearer token in the transcript is a leaked token. Keep .env files outside any ChatGPT conversation; share filenames or env-var names, not values.
Can ChatGPT call vrfymail directly during a chat (via tools)?
Yes, via Custom GPT actions or the Tools API. Define a custom action with an OpenAPI spec pointing at https://vrfymail.com/v1/check and an auth header. The Custom GPT can then verify emails during the conversation. For codegen use cases — generating handlers, not running them — Custom Instructions + Canvas is the simpler path.

One Custom Instructions block. Every chat, correct.

vrfymail's /v1/check returns a verdict in 50ms p50. Free tier: 5,000 verifies/month, no card. Paid plans start at $9/mo — see pricing.

Get my API key