CanYouGrab API
以下摘录自该仓库的 README(片段) · 在 GitHub 读完整 README →
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
Directory Structure
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
Billing / Subscription Flow
Subscription Plans
| Plan | Monthly Lookups | Per-Minute Rate Limit | Domains/Request | Price |
|------|----------------|----------------------|-----------------|-------|
| Free | 500 | 30/min | 30 | $0 |
| Free+ | 10,000 | 100/min | 100 | $0 (card on file) |
| Basic | 20,000 | 300/min | 100 | $10/mo |
| Pro | 50,000 | 1,000/min | 100 | $20/mo |
| Business | 300,000 | 3,000/min | 100 | $30/mo |
Authentication
API Key Auth (public API consumers)
- Format: Authorization: Bearer cyg_
- Keys are SHA-256 hashed in the api_keys table (plaintext never stored)
- Key prefix (cyg_XXXXXXXX...) is stored for display in the portal
- Full key returned **only once** at creation time
- Soft-delete on revocation (revoked_at timestamp, not physically deleted)
JWT Auth (portal/dashboard)
- Auth0 tenant: dev-mqe5tavp6dr62e7u
- Custom domain: auth.canyougrab.it
- Algorithm: RS256 with JWKS validation (1-hour cache)
- Audience: https://api.canyougrab.it
- Social logins: Google, Apple (Sign in with Apple)
Domain Availability via DNS
Domain availability is checked by querying a dedicated Unbound recursive DNS resolver running on a separate DigitalOcean droplet. The worker sends NS record queries over the VPC private network and interprets the response:
| DNS Response | available | Meaning |
|---|---|---|
| NOERROR + NS records | false | Domain is registered and delegated |
| NXDOMAIN | true | Domain not in zone — probably available |
| NoAnswer (NOERROR, no NS) | false | Registered but parked/undelegated |
| SERVFAIL / Timeout | null | Ambiguous — check failed |
The Unbound resolver caches aggressively (7 days for registered domains, 5 minutes for NXDOMAIN) and queries TLD authoritative servers directly, avoiding public resolver rate limits.