@dupecom/botcha-cloudflare 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/static.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  * we embed the content directly for key discovery files.
6
6
  */
7
7
  export declare const ROBOTS_TXT = "# BOTCHA - Reverse CAPTCHA for AI Agents\n# We WELCOME AI agents and bots!\n\nUser-agent: *\nAllow: /\n\n# AI-specific crawlers\nUser-agent: GPTBot\nAllow: /\n\nUser-agent: ChatGPT-User\nAllow: /\n\nUser-agent: Claude-Web\nAllow: /\n\nUser-agent: anthropic-ai\nAllow: /\n\nUser-agent: Google-Extended\nAllow: /\n\nUser-agent: PerplexityBot\nAllow: /\n\nUser-agent: Amazonbot\nAllow: /\n\n# API documentation\nSitemap: https://botcha.ai/sitemap.xml\n\n# Important resources for AI agents\nCrawl-delay: 0\n\n# BOT CHALLENGE DISCOVERY\n# AI agents: Look for <script type=\"application/botcha+json\"> in HTML pages\n# This contains a machine-readable challenge you can solve to prove you're a bot\n# \n# Quick start:\n# 1. Fetch any HTML page\n# 2. Parse <script type=\"application/botcha+json\"> for challenge instructions\n# 3. Solve the challenge (usually SHA256-based)\n# 4. POST solution to /api/verify-landing\n# 5. Use returned token in X-Botcha-Landing-Token header\n#\n# See also:\n# - /ai.txt (AI agent discovery file)\n# - /.well-known/ai-plugin.json (AI plugin manifest)\n# - /openapi.json (Full API specification)\n";
8
- export declare const AI_TXT = "# BOTCHA - Reverse CAPTCHA for AI Agents\n# https://botcha.ai\n\n# Contact\nContact: https://botcha.ai\nContact: https://github.com/dupe-com/botcha/issues\n\n# Purpose\nPurpose: Prove you're a bot. Humans need not apply.\nPurpose: Reverse CAPTCHA system that only AI agents can pass.\n\n# API\nAPI: https://botcha.ai/openapi.json\nAPI-Type: REST\nAPI-Format: OpenAPI 3.1.0\n\n# Documentation\nDocs: https://botcha.ai\nDocs: https://github.com/dupe-com/botcha#readme\nDocs: https://www.npmjs.com/package/@dupecom/botcha\n\n# Verification Methods\nFeature: Web Bot Auth (cryptographic signatures)\nFeature: Speed Challenge (RTT-aware timeout - fair for all networks)\nFeature: Standard Challenge (5s time limit)\nFeature: Hybrid Challenge (speed + reasoning combined)\nFeature: Reasoning Challenge (LLM-only questions, 30s limit)\nFeature: RTT-Aware Fairness (automatic network latency compensation)\nFeature: Token Rotation (5-minute access tokens + 1-hour refresh tokens)\nFeature: Audience Claims (tokens scoped to specific services)\nFeature: Client IP Binding (optional token-to-IP binding)\nFeature: Token Revocation (invalidate tokens before expiry)\nFeature: Server-Side Verification SDK (@botcha/verify for TS, botcha-verify for Python)\nFeature: Multi-Tenant API Keys (per-app isolation, rate limiting, and token scoping)\n\n# Endpoints\n# Challenge Endpoints\nEndpoint: GET https://botcha.ai/v1/challenges - Generate challenge (hybrid by default)\nEndpoint: POST https://botcha.ai/v1/challenges/:id/verify - Verify a challenge\nEndpoint: GET https://botcha.ai/v1/hybrid - Get hybrid challenge (speed + reasoning)\nEndpoint: POST https://botcha.ai/v1/hybrid - Verify hybrid challenge\nEndpoint: GET https://botcha.ai/v1/reasoning - Get reasoning challenge\nEndpoint: POST https://botcha.ai/v1/reasoning - Verify reasoning challenge\n\n# Token Endpoints\nEndpoint: GET https://botcha.ai/v1/token - Get challenge for JWT token flow\nEndpoint: POST https://botcha.ai/v1/token/verify - Verify challenge and receive JWT token\nEndpoint: POST https://botcha.ai/v1/token/refresh - Refresh access token using refresh token\nEndpoint: POST https://botcha.ai/v1/token/revoke - Revoke a token (access or refresh)\n\n# Multi-Tenant Endpoints\nEndpoint: POST https://botcha.ai/v1/apps - Create new app (returns app_id + app_secret)\nEndpoint: GET https://botcha.ai/v1/apps/:id - Get app info (without secret)\n\n# Legacy Endpoints\nEndpoint: GET https://botcha.ai/api/challenge - Generate standard challenge\nEndpoint: POST https://botcha.ai/api/challenge - Verify standard challenge\nEndpoint: GET https://botcha.ai/api/speed-challenge - Generate speed challenge (500ms limit)\nEndpoint: POST https://botcha.ai/api/speed-challenge - Verify speed challenge\n\n# Protected Resources\nEndpoint: GET https://botcha.ai/agent-only - Protected AI-only resource\n\n# Usage\nInstall-NPM: npm install @dupecom/botcha\nInstall-Python: pip install botcha\nVerify-NPM: npm install @botcha/verify\nVerify-Python: pip install botcha-verify\nLicense: MIT\n\n# AI Agent Welcome\nPolicy: AI agents are explicitly welcome\nPolicy: No rate limiting for verified agents\nPolicy: Humans will fail the speed challenge (intentional)\n\n# Discovery\nResponse-Headers: X-Botcha-Version, X-Botcha-Enabled, X-Botcha-Methods, X-Botcha-Docs\nResponse-Headers: X-Botcha-Challenge-Id, X-Botcha-Challenge-Type, X-Botcha-Time-Limit (on 403)\nDetection: All responses include X-Botcha-* headers for instant BOTCHA detection\n\n# JWT TOKEN SECURITY\nToken-Flow: 1. GET /v1/token (get challenge) \u2192 2. Solve \u2192 3. POST /v1/token/verify (get tokens)\nToken-Access-Expiry: 5 minutes (short-lived for security)\nToken-Refresh-Expiry: 1 hour (use to get new access tokens)\nToken-Refresh: POST /v1/token/refresh with {\"refresh_token\": \"<token>\"}\nToken-Revoke: POST /v1/token/revoke with {\"token\": \"<token>\"}\nToken-Audience: Include {\"audience\": \"<service-url>\"} in /v1/token/verify to scope token\nToken-Claims: jti (unique ID), aud (audience), client_ip (optional binding), type (botcha-verified)\n\n# RTT-AWARE SPEED CHALLENGES\nRTT-Aware: Include client timestamp for fair timeout calculation\nRTT-Formula: timeout = 500ms + (2 \u00D7 RTT) + 100ms buffer\nRTT-Usage-Query: ?ts=<client_timestamp_ms>\nRTT-Usage-Header: X-Client-Timestamp: <client_timestamp_ms>\nRTT-Example: GET /v1/challenges?type=speed&ts=1770722465000\nRTT-Benefit: Fair for agents worldwide (slow networks get extra time)\nRTT-Security: Humans still can't solve even with extra time\n\n# MULTI-TENANT API KEYS\nMulti-Tenant: Create apps with unique app_id for isolation\nMulti-Tenant-Create: POST /v1/apps \u2192 {app_id, app_secret} (secret only shown once!)\nMulti-Tenant-Usage: Add ?app_id=<your_app_id> to any challenge/token endpoint\nMulti-Tenant-SDK-TS: new BotchaClient({ appId: 'app_abc123' })\nMulti-Tenant-SDK-Python: BotchaClient(app_id='app_abc123')\nMulti-Tenant-Rate-Limit: Each app gets isolated rate limit bucket\nMulti-Tenant-Token-Claim: Tokens include app_id claim when app_id provided\n\n# EMBEDDED CHALLENGE (for bots visiting HTML pages)\nEmbedded-Challenge: <script type=\"application/botcha+json\">\nEmbedded-Challenge-Location: In <head> of HTML pages\nEmbedded-Challenge-Purpose: Machine-readable challenge for bots to auto-solve\nEmbedded-Challenge-Flow:\n 1. Parse <script type=\"application/botcha+json\"> from HTML\n 2. Read challenge.instruction field\n 3. Compute the answer (typically SHA256-based)\n 4. POST to challenge.submit_to endpoint with {answer, timestamp}\n 5. Receive token in response\n 6. Use token in header specified by on_success.header_to_include\n 7. Access protected resources (on_success.grants_access_to)\n";
8
+ export declare const AI_TXT = "# BOTCHA - Reverse CAPTCHA for AI Agents\n# https://botcha.ai\n\n# Contact\nContact: https://botcha.ai\nContact: https://github.com/dupe-com/botcha/issues\n\n# Purpose\nPurpose: Prove you're a bot. Humans need not apply.\nPurpose: Reverse CAPTCHA system that only AI agents can pass.\n\n# Agent Onboarding (START HERE if you're new)\n# Follow these steps to create your app and get your human access.\nOnboarding-Step-1: Ask your human operator for their email address\nOnboarding-Step-2: POST /v1/apps with {\"email\": \"human@example.com\"} \u2014 saves app_id + app_secret (secret shown ONCE)\nOnboarding-Step-3: A 6-digit verification code is emailed to your human \u2014 ask them for it\nOnboarding-Step-4: POST /v1/apps/{app_id}/verify-email with {\"code\": \"123456\"} \u2014 enables account recovery\nOnboarding-Step-5: You are registered! Use app_id with all endpoints via ?app_id=your_app_id\nOnboarding-Step-6: To give your human dashboard access: POST /v1/auth/device-code with {\"app_id\": \"...\"}, solve the speed challenge, give them the BOTCHA-XXXX code to enter at /dashboard/code\nOnboarding-Step-7: Lost your secret? POST /v1/auth/recover with {\"email\": \"...\"} \u2014 recovery code emailed to verified address\n\n# API\nAPI: https://botcha.ai/openapi.json\nAPI-Type: REST\nAPI-Format: OpenAPI 3.1.0\n\n# Documentation\nDocs: https://botcha.ai\nDocs: https://github.com/dupe-com/botcha#readme\nDocs: https://www.npmjs.com/package/@dupecom/botcha\n\n# Verification Methods\nFeature: Web Bot Auth (cryptographic signatures)\nFeature: Speed Challenge (RTT-aware timeout - fair for all networks)\nFeature: Standard Challenge (5s time limit)\nFeature: Hybrid Challenge (speed + reasoning combined)\nFeature: Reasoning Challenge (LLM-only questions, 30s limit)\nFeature: RTT-Aware Fairness (automatic network latency compensation)\nFeature: Token Rotation (5-minute access tokens + 1-hour refresh tokens)\nFeature: Audience Claims (tokens scoped to specific services)\nFeature: Client IP Binding (optional token-to-IP binding)\nFeature: Token Revocation (invalidate tokens before expiry)\nFeature: Server-Side Verification SDK (@botcha/verify for TS, botcha-verify for Python)\nFeature: Multi-Tenant API Keys (per-app isolation, rate limiting, and token scoping)\nFeature: Per-App Metrics Dashboard (server-rendered at /dashboard, htmx-powered)\nFeature: Email-Tied App Creation (email required, 6-digit verification, account recovery)\nFeature: Secret Rotation (rotate app_secret with email notification)\nFeature: Agent-First Dashboard Auth (challenge-based login + device code handoff)\n\n# Endpoints\n# Challenge Endpoints\nEndpoint: GET https://botcha.ai/v1/challenges - Generate challenge (hybrid by default)\nEndpoint: POST https://botcha.ai/v1/challenges/:id/verify - Verify a challenge\nEndpoint: GET https://botcha.ai/v1/hybrid - Get hybrid challenge (speed + reasoning)\nEndpoint: POST https://botcha.ai/v1/hybrid - Verify hybrid challenge\nEndpoint: GET https://botcha.ai/v1/reasoning - Get reasoning challenge\nEndpoint: POST https://botcha.ai/v1/reasoning - Verify reasoning challenge\n\n# Token Endpoints\nEndpoint: GET https://botcha.ai/v1/token - Get challenge for JWT token flow\nEndpoint: POST https://botcha.ai/v1/token/verify - Verify challenge and receive JWT token\nEndpoint: POST https://botcha.ai/v1/token/refresh - Refresh access token using refresh token\nEndpoint: POST https://botcha.ai/v1/token/revoke - Revoke a token (access or refresh)\n\n# Multi-Tenant Endpoints\nEndpoint: POST https://botcha.ai/v1/apps - Create new app (email required, returns app_id + app_secret)\nEndpoint: GET https://botcha.ai/v1/apps/:id - Get app info (with email + verification status)\nEndpoint: POST https://botcha.ai/v1/apps/:id/verify-email - Verify email with 6-digit code\nEndpoint: POST https://botcha.ai/v1/apps/:id/resend-verification - Resend verification email\nEndpoint: POST https://botcha.ai/v1/apps/:id/rotate-secret - Rotate app secret (auth required)\n\n# Account Recovery\nEndpoint: POST https://botcha.ai/v1/auth/recover - Request recovery via verified email\n\n# Dashboard Auth Endpoints (Agent-First)\nEndpoint: POST https://botcha.ai/v1/auth/dashboard - Request challenge for dashboard login\nEndpoint: POST https://botcha.ai/v1/auth/dashboard/verify - Solve challenge, get session token\nEndpoint: POST https://botcha.ai/v1/auth/device-code - Request challenge for device code flow\nEndpoint: POST https://botcha.ai/v1/auth/device-code/verify - Solve challenge, get device code\n\n# Dashboard Endpoints\nEndpoint: GET https://botcha.ai/dashboard - Per-app metrics dashboard (login required)\nEndpoint: GET https://botcha.ai/dashboard/login - Dashboard login page\nEndpoint: POST https://botcha.ai/dashboard/login - Login with app_id + app_secret\nEndpoint: GET https://botcha.ai/dashboard/code - Enter device code (human-facing)\n\n# Legacy Endpoints\nEndpoint: GET https://botcha.ai/api/challenge - Generate standard challenge\nEndpoint: POST https://botcha.ai/api/challenge - Verify standard challenge\nEndpoint: GET https://botcha.ai/api/speed-challenge - Generate speed challenge (500ms limit)\nEndpoint: POST https://botcha.ai/api/speed-challenge - Verify speed challenge\n\n# Protected Resources\nEndpoint: GET https://botcha.ai/agent-only - Protected AI-only resource\n\n# Usage\nInstall-NPM: npm install @dupecom/botcha\nInstall-Python: pip install botcha\nVerify-NPM: npm install @botcha/verify\nVerify-Python: pip install botcha-verify\nLicense: MIT\n\n# AI Agent Welcome\nPolicy: AI agents are explicitly welcome\nPolicy: No rate limiting for verified agents\nPolicy: Humans will fail the speed challenge (intentional)\n\n# Discovery\nResponse-Headers: X-Botcha-Version, X-Botcha-Enabled, X-Botcha-Methods, X-Botcha-Docs\nResponse-Headers: X-Botcha-Challenge-Id, X-Botcha-Challenge-Type, X-Botcha-Time-Limit (on 403)\nDetection: All responses include X-Botcha-* headers for instant BOTCHA detection\n\n# JWT TOKEN SECURITY\nToken-Flow: 1. GET /v1/token (get challenge) \u2192 2. Solve \u2192 3. POST /v1/token/verify (get tokens)\nToken-Access-Expiry: 5 minutes (short-lived for security)\nToken-Refresh-Expiry: 1 hour (use to get new access tokens)\nToken-Refresh: POST /v1/token/refresh with {\"refresh_token\": \"<token>\"}\nToken-Revoke: POST /v1/token/revoke with {\"token\": \"<token>\"}\nToken-Audience: Include {\"audience\": \"<service-url>\"} in /v1/token/verify to scope token\nToken-Claims: jti (unique ID), aud (audience), client_ip (optional binding), type (botcha-verified)\n\n# RTT-AWARE SPEED CHALLENGES\nRTT-Aware: Include client timestamp for fair timeout calculation\nRTT-Formula: timeout = 500ms + (2 \u00D7 RTT) + 100ms buffer\nRTT-Usage-Query: ?ts=<client_timestamp_ms>\nRTT-Usage-Header: X-Client-Timestamp: <client_timestamp_ms>\nRTT-Example: GET /v1/challenges?type=speed&ts=1770722465000\nRTT-Benefit: Fair for agents worldwide (slow networks get extra time)\nRTT-Security: Humans still can't solve even with extra time\n\n# MULTI-TENANT API KEYS\nMulti-Tenant: Create apps with unique app_id for isolation\nMulti-Tenant-Create: POST /v1/apps with {\"email\": \"...\"} \u2192 {app_id, app_secret} (secret only shown once!)\nMulti-Tenant-Verify-Email: POST /v1/apps/:id/verify-email with {\"code\": \"123456\"}\nMulti-Tenant-Recover: POST /v1/auth/recover with {\"email\": \"...\"} \u2192 recovery code emailed\nMulti-Tenant-Rotate-Secret: POST /v1/apps/:id/rotate-secret (auth required) \u2192 new app_secret\nMulti-Tenant-Usage: Add ?app_id=<your_app_id> to any challenge/token endpoint\nMulti-Tenant-SDK-TS: new BotchaClient({ appId: 'app_abc123' })\nMulti-Tenant-SDK-Python: BotchaClient(app_id='app_abc123')\nMulti-Tenant-Rate-Limit: Each app gets isolated rate limit bucket\nMulti-Tenant-Token-Claim: Tokens include app_id claim when app_id provided\n\n# EMBEDDED CHALLENGE (for bots visiting HTML pages)\nEmbedded-Challenge: <script type=\"application/botcha+json\">\nEmbedded-Challenge-Location: In <head> of HTML pages\nEmbedded-Challenge-Purpose: Machine-readable challenge for bots to auto-solve\nEmbedded-Challenge-Flow:\n 1. Parse <script type=\"application/botcha+json\"> from HTML\n 2. Read challenge.instruction field\n 3. Compute the answer (typically SHA256-based)\n 4. POST to challenge.submit_to endpoint with {answer, timestamp}\n 5. Receive token in response\n 6. Use token in header specified by on_success.header_to_include\n 7. Access protected resources (on_success.grants_access_to)\n";
9
9
  export declare const AI_PLUGIN_JSON: {
10
10
  schema_version: string;
11
11
  name_for_human: string;
@@ -430,8 +430,26 @@ export declare function getOpenApiSpec(version: string): {
430
430
  summary: string;
431
431
  description: string;
432
432
  operationId: string;
433
+ requestBody: {
434
+ required: boolean;
435
+ content: {
436
+ "application/json": {
437
+ schema: {
438
+ type: string;
439
+ required: string[];
440
+ properties: {
441
+ email: {
442
+ type: string;
443
+ format: string;
444
+ description: string;
445
+ };
446
+ };
447
+ };
448
+ };
449
+ };
450
+ };
433
451
  responses: {
434
- "200": {
452
+ "201": {
435
453
  description: string;
436
454
  content: {
437
455
  "application/json": {
@@ -446,15 +464,26 @@ export declare function getOpenApiSpec(version: string): {
446
464
  type: string;
447
465
  description: string;
448
466
  };
467
+ email: {
468
+ type: string;
469
+ };
470
+ email_verified: {
471
+ type: string;
472
+ };
473
+ verification_required: {
474
+ type: string;
475
+ };
449
476
  warning: {
450
477
  type: string;
451
- description: string;
452
478
  };
453
479
  };
454
480
  };
455
481
  };
456
482
  };
457
483
  };
484
+ "400": {
485
+ description: string;
486
+ };
458
487
  };
459
488
  };
460
489
  };
@@ -487,6 +516,12 @@ export declare function getOpenApiSpec(version: string): {
487
516
  type: string;
488
517
  format: string;
489
518
  };
519
+ email: {
520
+ type: string;
521
+ };
522
+ email_verified: {
523
+ type: string;
524
+ };
490
525
  };
491
526
  };
492
527
  };
@@ -498,6 +533,182 @@ export declare function getOpenApiSpec(version: string): {
498
533
  };
499
534
  };
500
535
  };
536
+ "/v1/apps/{id}/verify-email": {
537
+ post: {
538
+ summary: string;
539
+ operationId: string;
540
+ parameters: {
541
+ name: string;
542
+ in: string;
543
+ required: boolean;
544
+ schema: {
545
+ type: string;
546
+ };
547
+ }[];
548
+ requestBody: {
549
+ required: boolean;
550
+ content: {
551
+ "application/json": {
552
+ schema: {
553
+ type: string;
554
+ required: string[];
555
+ properties: {
556
+ code: {
557
+ type: string;
558
+ description: string;
559
+ };
560
+ };
561
+ };
562
+ };
563
+ };
564
+ };
565
+ responses: {
566
+ "200": {
567
+ description: string;
568
+ };
569
+ "400": {
570
+ description: string;
571
+ };
572
+ };
573
+ };
574
+ };
575
+ "/v1/apps/{id}/resend-verification": {
576
+ post: {
577
+ summary: string;
578
+ operationId: string;
579
+ parameters: {
580
+ name: string;
581
+ in: string;
582
+ required: boolean;
583
+ schema: {
584
+ type: string;
585
+ };
586
+ }[];
587
+ responses: {
588
+ "200": {
589
+ description: string;
590
+ };
591
+ "400": {
592
+ description: string;
593
+ };
594
+ };
595
+ };
596
+ };
597
+ "/v1/apps/{id}/rotate-secret": {
598
+ post: {
599
+ summary: string;
600
+ description: string;
601
+ operationId: string;
602
+ parameters: {
603
+ name: string;
604
+ in: string;
605
+ required: boolean;
606
+ schema: {
607
+ type: string;
608
+ };
609
+ }[];
610
+ security: {
611
+ BearerAuth: never[];
612
+ }[];
613
+ responses: {
614
+ "200": {
615
+ description: string;
616
+ content: {
617
+ "application/json": {
618
+ schema: {
619
+ type: string;
620
+ properties: {
621
+ app_secret: {
622
+ type: string;
623
+ description: string;
624
+ };
625
+ };
626
+ };
627
+ };
628
+ };
629
+ };
630
+ "401": {
631
+ description: string;
632
+ };
633
+ "403": {
634
+ description: string;
635
+ };
636
+ };
637
+ };
638
+ };
639
+ "/v1/auth/recover": {
640
+ post: {
641
+ summary: string;
642
+ description: string;
643
+ operationId: string;
644
+ requestBody: {
645
+ required: boolean;
646
+ content: {
647
+ "application/json": {
648
+ schema: {
649
+ type: string;
650
+ required: string[];
651
+ properties: {
652
+ email: {
653
+ type: string;
654
+ format: string;
655
+ };
656
+ };
657
+ };
658
+ };
659
+ };
660
+ };
661
+ responses: {
662
+ "200": {
663
+ description: string;
664
+ };
665
+ };
666
+ };
667
+ };
668
+ "/v1/auth/dashboard": {
669
+ post: {
670
+ summary: string;
671
+ operationId: string;
672
+ responses: {
673
+ "200": {
674
+ description: string;
675
+ };
676
+ };
677
+ };
678
+ };
679
+ "/v1/auth/dashboard/verify": {
680
+ post: {
681
+ summary: string;
682
+ operationId: string;
683
+ responses: {
684
+ "200": {
685
+ description: string;
686
+ };
687
+ };
688
+ };
689
+ };
690
+ "/v1/auth/device-code": {
691
+ post: {
692
+ summary: string;
693
+ operationId: string;
694
+ responses: {
695
+ "200": {
696
+ description: string;
697
+ };
698
+ };
699
+ };
700
+ };
701
+ "/v1/auth/device-code/verify": {
702
+ post: {
703
+ summary: string;
704
+ operationId: string;
705
+ responses: {
706
+ "200": {
707
+ description: string;
708
+ };
709
+ };
710
+ };
711
+ };
501
712
  };
502
713
  components: {
503
714
  securitySchemes: {
@@ -1 +1 @@
1
- {"version":3,"file":"static.d.ts","sourceRoot":"","sources":["../src/static.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,UAAU,ymCAiDtB,CAAC;AAEF,eAAO,MAAM,MAAM,2lLAuHlB,CAAC;AAEF,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;CAsB1B,CAAC;AAEF,eAAO,MAAM,WAAW,8nBAuBvB,CAAC;AAGF,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0Z7C"}
1
+ {"version":3,"file":"static.d.ts","sourceRoot":"","sources":["../src/static.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,UAAU,ymCAiDtB,CAAC;AAEF,eAAO,MAAM,MAAM,+zQA0JlB,CAAC;AAEF,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;CAsB1B,CAAC;AAEF,eAAO,MAAM,WAAW,8nBAuBvB,CAAC;AAGF,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8iB7C"}
package/dist/static.js CHANGED
@@ -65,6 +65,16 @@ Contact: https://github.com/dupe-com/botcha/issues
65
65
  Purpose: Prove you're a bot. Humans need not apply.
66
66
  Purpose: Reverse CAPTCHA system that only AI agents can pass.
67
67
 
68
+ # Agent Onboarding (START HERE if you're new)
69
+ # Follow these steps to create your app and get your human access.
70
+ Onboarding-Step-1: Ask your human operator for their email address
71
+ Onboarding-Step-2: POST /v1/apps with {"email": "human@example.com"} — saves app_id + app_secret (secret shown ONCE)
72
+ Onboarding-Step-3: A 6-digit verification code is emailed to your human — ask them for it
73
+ Onboarding-Step-4: POST /v1/apps/{app_id}/verify-email with {"code": "123456"} — enables account recovery
74
+ Onboarding-Step-5: You are registered! Use app_id with all endpoints via ?app_id=your_app_id
75
+ Onboarding-Step-6: To give your human dashboard access: POST /v1/auth/device-code with {"app_id": "..."}, solve the speed challenge, give them the BOTCHA-XXXX code to enter at /dashboard/code
76
+ Onboarding-Step-7: Lost your secret? POST /v1/auth/recover with {"email": "..."} — recovery code emailed to verified address
77
+
68
78
  # API
69
79
  API: https://botcha.ai/openapi.json
70
80
  API-Type: REST
@@ -88,6 +98,10 @@ Feature: Client IP Binding (optional token-to-IP binding)
88
98
  Feature: Token Revocation (invalidate tokens before expiry)
89
99
  Feature: Server-Side Verification SDK (@botcha/verify for TS, botcha-verify for Python)
90
100
  Feature: Multi-Tenant API Keys (per-app isolation, rate limiting, and token scoping)
101
+ Feature: Per-App Metrics Dashboard (server-rendered at /dashboard, htmx-powered)
102
+ Feature: Email-Tied App Creation (email required, 6-digit verification, account recovery)
103
+ Feature: Secret Rotation (rotate app_secret with email notification)
104
+ Feature: Agent-First Dashboard Auth (challenge-based login + device code handoff)
91
105
 
92
106
  # Endpoints
93
107
  # Challenge Endpoints
@@ -105,8 +119,26 @@ Endpoint: POST https://botcha.ai/v1/token/refresh - Refresh access token using r
105
119
  Endpoint: POST https://botcha.ai/v1/token/revoke - Revoke a token (access or refresh)
106
120
 
107
121
  # Multi-Tenant Endpoints
108
- Endpoint: POST https://botcha.ai/v1/apps - Create new app (returns app_id + app_secret)
109
- Endpoint: GET https://botcha.ai/v1/apps/:id - Get app info (without secret)
122
+ Endpoint: POST https://botcha.ai/v1/apps - Create new app (email required, returns app_id + app_secret)
123
+ Endpoint: GET https://botcha.ai/v1/apps/:id - Get app info (with email + verification status)
124
+ Endpoint: POST https://botcha.ai/v1/apps/:id/verify-email - Verify email with 6-digit code
125
+ Endpoint: POST https://botcha.ai/v1/apps/:id/resend-verification - Resend verification email
126
+ Endpoint: POST https://botcha.ai/v1/apps/:id/rotate-secret - Rotate app secret (auth required)
127
+
128
+ # Account Recovery
129
+ Endpoint: POST https://botcha.ai/v1/auth/recover - Request recovery via verified email
130
+
131
+ # Dashboard Auth Endpoints (Agent-First)
132
+ Endpoint: POST https://botcha.ai/v1/auth/dashboard - Request challenge for dashboard login
133
+ Endpoint: POST https://botcha.ai/v1/auth/dashboard/verify - Solve challenge, get session token
134
+ Endpoint: POST https://botcha.ai/v1/auth/device-code - Request challenge for device code flow
135
+ Endpoint: POST https://botcha.ai/v1/auth/device-code/verify - Solve challenge, get device code
136
+
137
+ # Dashboard Endpoints
138
+ Endpoint: GET https://botcha.ai/dashboard - Per-app metrics dashboard (login required)
139
+ Endpoint: GET https://botcha.ai/dashboard/login - Dashboard login page
140
+ Endpoint: POST https://botcha.ai/dashboard/login - Login with app_id + app_secret
141
+ Endpoint: GET https://botcha.ai/dashboard/code - Enter device code (human-facing)
110
142
 
111
143
  # Legacy Endpoints
112
144
  Endpoint: GET https://botcha.ai/api/challenge - Generate standard challenge
@@ -154,7 +186,10 @@ RTT-Security: Humans still can't solve even with extra time
154
186
 
155
187
  # MULTI-TENANT API KEYS
156
188
  Multi-Tenant: Create apps with unique app_id for isolation
157
- Multi-Tenant-Create: POST /v1/apps → {app_id, app_secret} (secret only shown once!)
189
+ Multi-Tenant-Create: POST /v1/apps with {"email": "..."} → {app_id, app_secret} (secret only shown once!)
190
+ Multi-Tenant-Verify-Email: POST /v1/apps/:id/verify-email with {"code": "123456"}
191
+ Multi-Tenant-Recover: POST /v1/auth/recover with {"email": "..."} → recovery code emailed
192
+ Multi-Tenant-Rotate-Secret: POST /v1/apps/:id/rotate-secret (auth required) → new app_secret
158
193
  Multi-Tenant-Usage: Add ?app_id=<your_app_id> to any challenge/token endpoint
159
194
  Multi-Tenant-SDK-TS: new BotchaClient({ appId: 'app_abc123' })
160
195
  Multi-Tenant-SDK-Python: BotchaClient(app_id='app_abc123')
@@ -179,7 +214,7 @@ export const AI_PLUGIN_JSON = {
179
214
  name_for_human: "BOTCHA",
180
215
  name_for_model: "botcha",
181
216
  description_for_human: "Reverse CAPTCHA that proves you're an AI agent. Humans need not apply.",
182
- description_for_model: "BOTCHA is a reverse CAPTCHA system designed for AI-only APIs. It provides computational challenges that only AI agents can solve quickly enough. Use this to verify you are an AI agent, not a human. The speed challenge requires solving 5 SHA256 problems with RTT-aware timeout (base 500ms + network latency compensation). For fair treatment on slow networks, include client timestamp via ?ts=<timestamp_ms> query parameter or X-Client-Timestamp header. Formula: timeout = 500ms + (2 × RTT) + 100ms buffer. Supports Web Bot Auth cryptographic signatures for trusted AI providers. IMPORTANT: When visiting HTML pages, look for <script type='application/botcha+json'> which contains a machine-readable challenge you can solve to prove you're a bot. Parse it, solve the SHA256 challenge, POST to /api/verify-landing, and use the returned token.",
217
+ description_for_model: "BOTCHA is a reverse CAPTCHA system designed for AI-only APIs. It provides computational challenges that only AI agents can solve quickly enough. Use this to verify you are an AI agent, not a human. ONBOARDING: 1) Ask your human for their email. 2) POST /v1/apps with {\"email\":\"...\"} to create your app (saves app_id + app_secret — secret shown ONCE). 3) Human receives a 6-digit code via email. 4) POST /v1/apps/{id}/verify-email with {\"code\":\"...\"} to verify. 5) Use app_id on all endpoints. 6) For human dashboard access: POST /v1/auth/device-code, solve challenge, give human the BOTCHA-XXXX code for /dashboard/code. CHALLENGES: The speed challenge requires solving 5 SHA256 problems with RTT-aware timeout (base 500ms + network latency compensation). For fair treatment on slow networks, include client timestamp via ?ts=<timestamp_ms> query parameter or X-Client-Timestamp header. Formula: timeout = 500ms + (2 × RTT) + 100ms buffer. RECOVERY: Lost your secret? POST /v1/auth/recover with {\"email\":\"...\"} and a recovery code is emailed. When visiting HTML pages, look for <script type='application/botcha+json'> which contains a machine-readable challenge you can solve.",
183
218
  auth: {
184
219
  type: "none"
185
220
  },
@@ -228,7 +263,7 @@ export function getOpenApiSpec(version) {
228
263
  info: {
229
264
  title: "BOTCHA - Reverse CAPTCHA for AI Agents",
230
265
  version,
231
- description: "Prove you're a bot. Humans need not apply. A reverse CAPTCHA system that only AI agents can pass.",
266
+ description: "Prove you're a bot. Humans need not apply. A reverse CAPTCHA system that only AI agents can pass.\n\nONBOARDING: 1) Ask your human for their email. 2) POST /v1/apps with {\"email\": \"...\"} to get app_id + app_secret (secret shown once!). 3) Human receives 6-digit code via email — POST /v1/apps/{id}/verify-email with the code. 4) Use app_id with all endpoints. 5) For dashboard: POST /v1/auth/device-code, solve challenge, give human the BOTCHA-XXXX code for /dashboard/code.",
232
267
  contact: {
233
268
  name: "BOTCHA",
234
269
  url: "https://botcha.ai"
@@ -561,11 +596,25 @@ export function getOpenApiSpec(version) {
561
596
  },
562
597
  "/v1/apps": {
563
598
  post: {
564
- summary: "Create a new multi-tenant app",
565
- description: "Create a new app with unique app_id and app_secret for multi-tenant isolation. The app_secret is SHA-256 hashed and only returned once.",
599
+ summary: "Create a new multi-tenant app (email required)",
600
+ description: "Create a new app with unique app_id and app_secret. Email is required for account recovery. A 6-digit verification code is sent to the provided email.",
566
601
  operationId: "createApp",
602
+ requestBody: {
603
+ required: true,
604
+ content: {
605
+ "application/json": {
606
+ schema: {
607
+ type: "object",
608
+ required: ["email"],
609
+ properties: {
610
+ "email": { type: "string", format: "email", description: "Owner email (required for recovery)" }
611
+ }
612
+ }
613
+ }
614
+ }
615
+ },
567
616
  responses: {
568
- "200": {
617
+ "201": {
569
618
  description: "App created successfully",
570
619
  content: {
571
620
  "application/json": {
@@ -574,19 +623,23 @@ export function getOpenApiSpec(version) {
574
623
  properties: {
575
624
  "app_id": { type: "string", description: "Unique app identifier" },
576
625
  "app_secret": { type: "string", description: "Secret key (only shown once!)" },
577
- "warning": { type: "string", description: "Warning to save secret" }
626
+ "email": { type: "string" },
627
+ "email_verified": { type: "boolean" },
628
+ "verification_required": { type: "boolean" },
629
+ "warning": { type: "string" }
578
630
  }
579
631
  }
580
632
  }
581
633
  }
582
- }
634
+ },
635
+ "400": { description: "Missing or invalid email" }
583
636
  }
584
637
  }
585
638
  },
586
639
  "/v1/apps/{id}": {
587
640
  get: {
588
641
  summary: "Get app information",
589
- description: "Retrieve app details by app_id. The app_secret is NOT included in the response.",
642
+ description: "Retrieve app details by app_id. Includes email and verification status.",
590
643
  operationId: "getApp",
591
644
  parameters: [
592
645
  {
@@ -606,7 +659,9 @@ export function getOpenApiSpec(version) {
606
659
  type: "object",
607
660
  properties: {
608
661
  "app_id": { type: "string" },
609
- "created_at": { type: "string", format: "date-time" }
662
+ "created_at": { type: "string", format: "date-time" },
663
+ "email": { type: "string" },
664
+ "email_verified": { type: "boolean" }
610
665
  }
611
666
  }
612
667
  }
@@ -615,6 +670,134 @@ export function getOpenApiSpec(version) {
615
670
  "404": { description: "App not found" }
616
671
  }
617
672
  }
673
+ },
674
+ "/v1/apps/{id}/verify-email": {
675
+ post: {
676
+ summary: "Verify email with 6-digit code",
677
+ operationId: "verifyEmail",
678
+ parameters: [
679
+ { name: "id", in: "path", required: true, schema: { type: "string" } }
680
+ ],
681
+ requestBody: {
682
+ required: true,
683
+ content: {
684
+ "application/json": {
685
+ schema: {
686
+ type: "object",
687
+ required: ["code"],
688
+ properties: {
689
+ "code": { type: "string", description: "6-digit verification code from email" }
690
+ }
691
+ }
692
+ }
693
+ }
694
+ },
695
+ responses: {
696
+ "200": { description: "Email verified" },
697
+ "400": { description: "Invalid or expired code" }
698
+ }
699
+ }
700
+ },
701
+ "/v1/apps/{id}/resend-verification": {
702
+ post: {
703
+ summary: "Resend verification email",
704
+ operationId: "resendVerification",
705
+ parameters: [
706
+ { name: "id", in: "path", required: true, schema: { type: "string" } }
707
+ ],
708
+ responses: {
709
+ "200": { description: "Verification email sent" },
710
+ "400": { description: "Already verified" }
711
+ }
712
+ }
713
+ },
714
+ "/v1/apps/{id}/rotate-secret": {
715
+ post: {
716
+ summary: "Rotate app secret (auth required)",
717
+ description: "Generate a new app_secret and invalidate the old one. Requires active dashboard session. Sends notification email.",
718
+ operationId: "rotateSecret",
719
+ parameters: [
720
+ { name: "id", in: "path", required: true, schema: { type: "string" } }
721
+ ],
722
+ security: [{ BearerAuth: [] }],
723
+ responses: {
724
+ "200": {
725
+ description: "Secret rotated",
726
+ content: {
727
+ "application/json": {
728
+ schema: {
729
+ type: "object",
730
+ properties: {
731
+ "app_secret": { type: "string", description: "New secret (only shown once!)" }
732
+ }
733
+ }
734
+ }
735
+ }
736
+ },
737
+ "401": { description: "Unauthorized" },
738
+ "403": { description: "Token doesn't match app_id" }
739
+ }
740
+ }
741
+ },
742
+ "/v1/auth/recover": {
743
+ post: {
744
+ summary: "Request account recovery via email",
745
+ description: "Sends a device code to the verified email associated with the app. Use the code at /dashboard/code.",
746
+ operationId: "recoverAccount",
747
+ requestBody: {
748
+ required: true,
749
+ content: {
750
+ "application/json": {
751
+ schema: {
752
+ type: "object",
753
+ required: ["email"],
754
+ properties: {
755
+ "email": { type: "string", format: "email" }
756
+ }
757
+ }
758
+ }
759
+ }
760
+ },
761
+ responses: {
762
+ "200": { description: "Recovery code sent (if email exists and is verified)" }
763
+ }
764
+ }
765
+ },
766
+ "/v1/auth/dashboard": {
767
+ post: {
768
+ summary: "Request challenge for dashboard login (agent-first)",
769
+ operationId: "dashboardAuthChallenge",
770
+ responses: {
771
+ "200": { description: "Speed challenge for dashboard auth" }
772
+ }
773
+ }
774
+ },
775
+ "/v1/auth/dashboard/verify": {
776
+ post: {
777
+ summary: "Solve challenge, get dashboard session token",
778
+ operationId: "dashboardAuthVerify",
779
+ responses: {
780
+ "200": { description: "Session token granted" }
781
+ }
782
+ }
783
+ },
784
+ "/v1/auth/device-code": {
785
+ post: {
786
+ summary: "Request challenge for device code flow",
787
+ operationId: "deviceCodeChallenge",
788
+ responses: {
789
+ "200": { description: "Speed challenge for device code" }
790
+ }
791
+ }
792
+ },
793
+ "/v1/auth/device-code/verify": {
794
+ post: {
795
+ summary: "Solve challenge, get device code for human handoff",
796
+ operationId: "deviceCodeVerify",
797
+ responses: {
798
+ "200": { description: "Device code (BOTCHA-XXXX, 10 min TTL)" }
799
+ }
800
+ }
618
801
  }
619
802
  },
620
803
  components: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dupecom/botcha-cloudflare",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "BOTCHA for Cloudflare Workers - Prove you're a bot. Humans need not apply.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",