Virtual Projects — AI-driven project setup
AI agents create and configure a Zapnoty project on behalf of the user. The user only confirms the prepared project with an Accept button — no docs to read, no keys to copy.
Flow
- User asks an AI agent (Claude, Cursor): «Set up Zapnoty for me».
- AI asks for email and calls POST /v1/virtual-projects with config (permissions, templates, webhook).
- Receives temp_api_key (zn_virt_…), accept_url and virtual_project_id. Can further configure through CRUD endpoints with that key.
- AI tells the user: «Done. Open app.zapnoty.com with the email you provided and click Accept».
- User logs in via magic link, sees the project with an 'AI prepared' badge, clicks Accept — gets a permanent zn_live_ key. The old zn_virt_ becomes invalid.
API
Public POST /v1/virtual-projects (no API key). Rate-limit: 5/hour and 30/day per creator IP. UNIQUE on target_email among pending: only one pending project per email at a time.
Response
GET /v1/virtual-projects/{id}/status
Public, no auth. AI can poll to check if the user accepted. Returns one of: virtual_pending / active / expired.
Temp key restrictions
zn_virt_<key> is used for setup, not for runtime operations. This prevents an AI from sending spam to anyone before the user consents.
Blocked: /v1/send, /v1/send/preview, /v1/otp/*, /v1/broadcast, /v1/auth/session, /v1/helpdesk/tickets, /v1/helpdesk/request — anything that sends messages or creates sessions.
Allowed: CRUD permissions/templates/tags/webhook/sender/auto-messages/scheduled. The AI can prepare everything and verify with zapnoty_list_setup.
TTL: 24 hours. If the user doesn't click Accept, the cleanup worker deletes the project automatically. AI sees status=expired.
Abuse protection: 5 virtual projects/hour and 30/day per creator IP. UNIQUE constraint on target_email — can't spam someone's account with multiple pending projects.
MCP server (mcp.zapnoty.com)
So AI agents automatically know about the Zapnoty API, we run an MCP server. AI client connects once, then tools are available in all conversations.
Claude Desktop
Cursor / Continue / Goose
Available tools
zapnoty_create_virtual_project — create a pending project → return temp_api_key and accept_url
zapnoty_check_status — check status (pending / active / expired)
zapnoty_create_template — add message template
zapnoty_create_permission — add permission (category)
zapnoty_create_tag — add tag for segmentation
zapnoty_set_webhook — configure webhook URL and events
zapnoty_list_setup — summary of current setup (permissions + templates + tags)
Security and abuse protection
- Before Accept, the project doesn't work: it can't send any messages, OTP, or webhook events.
- On Accept, zn_virt_<key> is invalidated — a new zn_live_<key> is generated. If the AI cached the temp key, it becomes useless (401) after Accept.
- Public form endpoints /f/{form_id} for a virtual_pending project silently return 200 without persisting — so an external attacker can't tell the project is pending.
- Only one pending project per email at a time. An attacker can't flood someone's account with multiple pending projects.
- Rate limit 5/hour, 30/day per creator IP — protects against DB flood. Cleanup worker removes expired records after 24h.