CanYouGrab API
Domain availability lookup API with subscription billing, built on FastAPI + DNS (Unbound resolver).
Live services:
- API:
https://api.canyougrab.it
- Developer portal:
https://portal.canyougrab.it
- Auth:
https://auth.canyougrab.it (Auth0 custom domain)
Architecture Overview
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Developer Portal β
β (Zudoku/React on portal.canyougrab.it) β
β Usage Dashboard Β· API Keys Β· Pricing Β· API Reference (OAS) β
ββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββββ
β Auth0 JWT (portal) / Bearer API key (API)
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β FastAPI Backend (v5.0.0) β
β api.canyougrab.it:8000 β
β β
β βββββββββββββββ ββββββββββββ ββββββββββββ βββββββββββββββ β
β β app.py β β keys.py β βbilling.pyβ β auth.py β β
β β /check/bulk β β /keys β β/billing β β API key + β β
β β /usage β β CRUD β β/stripe β β JWT auth β β
β β β β rotate β β webhook β β β β
β ββββββββ¬βββββββ ββββββββββββ ββββββ¬ββββββ βββββββββββββββ β
β β β β
βββββββββββΌβββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββ
β β
βΌ βΌ
βββββββββββββββββββ βββββββββββββββββββ
β Valkey (Redis) β β Stripe API β
β Job queue + β β Subscriptions β
β Rate limiting β β Webhooks β
ββββββββββ¬βββββββββ βββββββββββββββββββ
β
βΌ
βββββββββββββββββββ ββββββββββββββββββββββββββββββββ
β RQ Worker βββDNSβββΆ β Unbound Resolver β
β (worker.py) β β (dedicated droplet) β
β ThreadPool(10) β β NS queries via VPC β
β via RQ queue β ββββββββββββββββββββββββββββββββ
βββββββββββββββββββ
ββββββββββββββββββββββββββββββββ
ββββββββββββββββββββΆβ PostgreSQL β
(auth, usage, β API keys + Usage logs β
billing only) ββββββββββββββββββββββββββββββββ
Directory Structure
zuplo/
βββ backend/ # Python FastAPI backend
β βββ app.py # Main API: /check/bulk, /usage, /health
β βββ auth.py # API key auth (SHA-256) + Auth0 JWT auth (RS256)
β βββ billing.py # Stripe checkout, portal, webhooks, card-on-file, usage details
β βββ keys.py # API key CRUD: create, list, rotate, revoke (+ Turnstile)
β βββ antifraud.py # Anti-fraud: Turnstile, device fingerprints, risk scoring
β βββ email_utils.py # Email normalization + disposable email detection
β βββ dns_client.py # DNS-based domain availability checking via Unbound
β βββ queries.py # PostgreSQL queries: usage tracking, auth, billing
β βββ valkey_client.py # Redis/Valkey job queue client (RQ-backed)
β βββ rq_tasks.py # RQ task function: process_domain_job()
β βββ worker.py # RQ worker process (ThreadPoolExecutor per job)
β βββ migrations/ # SQL migrations
β β βββ 001_free_tier_antifraud.sql
β βββ requirements.txt # Python dependencies
βββ portal/ # Developer portal (Zuplo + Zudoku)
β βββ config/
β β βββ routes.oas.json # OpenAPI 3.1 spec (public API documentation)
β β βββ policies.json # Zuplo policies (empty β all routing is direct)
β βββ docs/ # Zudoku documentation portal
β β βββ src/
β β β βββ config.ts # API_BASE, Turnstile site key, Stripe PK
β β β βββ UsageDashboard.tsx # Usage + billing dashboard component
β β β βββ PricingPage.tsx # Plan selection + Stripe checkout
β β β βββ PricingPlans.tsx # Pricing card grid component
β β β βββ CardSetupPage.tsx # Stripe Elements card-on-file for Free+
β β βββ public/ # Static assets (logos, banners, CSS overrides)
β β βββ zudoku.config.tsx # Portal config: theme, nav, Auth0, API key mgmt
β β βββ package.json # Frontend dependencies (React 19, Zudoku)
β βββ package.json # Workspace root (Zuplo v6, TypeScript v5)
β βββ README.md # Zuplo boilerplate (not project-specific)
βββ mcp-server/ # MCP package for ChatGPT, Claude, and remote MCP clients
β βββ pyproject.toml # MCP package metadata + version
β βββ server.json # MCP registry/server metadata
β βββ uv.lock # Locked MCP runtime dependencies
β βββ src/canyougrab_mcp/
β βββ __init__.py
β βββ server.py # stdio + streamable-http MCP entrypoint
βββ .github/workflows/
β βββ deploy.yml # Production deploy (on tag push v*)
β βββ deploy-dev.yml # Dev deploy (on push to dev branch)
βββ .claude/
β βββ launch.json # Local dev server config (port 9200)
βββ package.json # Root workspace config
API Endpoints
Public API (API key auth: Authorization: Bearer cyg_...)
| Method | Path | Description |
|---|
POST | /api/check/bulk | Check up to 100 domains. Long-polls until results ready (30s max). |
GET | /api/account/usage | Usage summary for the authenticated consumer. |
GET | /api/account/quota-check | Lightweight monthly + per-minute quota check. |
GET | /health | Health check (no auth). |
Portal API (Auth0 JWT auth)
| Method | Path | Description |
|---|
POST | /api/keys | Create new API key. |
GET | /api/keys | List user's API keys. |
POST | /api/keys/{id}/rotate | Rotate key (revoke old, create new). |
DELETE | /api/keys/{id} | Revoke (soft-delete) a key. |
POST | /api/billing/checkout | Create Stripe Checkout session. |
POST | /api/billing/portal | Create Stripe Customer Portal session. |
POST | /api/billing/setup-card | Create SetupIntent for Free+ card-on-file. |
POST | /api/billing/confirm-free-plus | Verify card fingerprint and upgrade to Free+. |
GET | /api/billing/card-status | Check if user has a card on file. |
GET | /api/billing/usage/detailed | Per-key usage breakdown for portal dashboard. |
POST | /api/antifraud/turnstile/verify | Verify Cloudflare Turnstile token. |
POST | /api/antifraud/device/register | Register device fingerprint (Fingerprint Pro). |
GET | /api/antifraud/risk | Get risk assessment for authenticated user. |
POST | /api/antifraud/assess-signup | Run multi-signal risk assessment at signup. |
Internal / Webhook
| Method | Path | Description |
|---|
POST | /api/account/usage/detailed | Multi-consumer usage breakdown. |
POST | /api/stripe/webhook | Stripe webhook receiver (signature-verified). |
Core Request Flow
Domain Availability Check