@nordsym/apiclaw 1.0.0 → 1.1.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/AGENTS.md +74 -0
- package/HEARTBEAT.md +4 -0
- package/IDENTITY.md +22 -0
- package/README.md +197 -202
- package/SOUL.md +36 -0
- package/STATUS.md +237 -0
- package/TOOLS.md +36 -0
- package/USER.md +17 -0
- package/{backend/convex → convex}/_generated/api.d.ts +6 -6
- package/convex/credits.ts +211 -0
- package/convex/http.ts +490 -0
- package/convex/providers.ts +516 -0
- package/convex/purchases.ts +183 -0
- package/convex/schema.ts +180 -0
- package/convex.json +3 -0
- package/dist/credentials.d.ts +19 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +158 -0
- package/dist/credentials.js.map +1 -0
- package/dist/credits.d.ts +14 -11
- package/dist/credits.d.ts.map +1 -1
- package/dist/credits.js +151 -99
- package/dist/credits.js.map +1 -1
- package/dist/discovery.d.ts +7 -16
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +33 -40
- package/dist/discovery.js.map +1 -1
- package/dist/execute.d.ts +19 -0
- package/dist/execute.d.ts.map +1 -0
- package/dist/execute.js +285 -0
- package/dist/execute.js.map +1 -0
- package/dist/index.js +106 -30
- package/dist/index.js.map +1 -1
- package/dist/proxy.d.ts +6 -0
- package/dist/proxy.d.ts.map +1 -0
- package/dist/proxy.js +19 -0
- package/dist/proxy.js.map +1 -0
- package/dist/registry/apis.json +95362 -202
- package/dist/registry/apis_expanded.json +100853 -0
- package/dist/stripe.d.ts +68 -0
- package/dist/stripe.d.ts.map +1 -0
- package/dist/stripe.js +196 -0
- package/dist/stripe.js.map +1 -0
- package/dist/test.d.ts +3 -2
- package/dist/test.d.ts.map +1 -1
- package/dist/test.js +105 -75
- package/dist/test.js.map +1 -1
- package/dist/types.d.ts +0 -28
- package/dist/types.d.ts.map +1 -1
- package/dist/webhook.d.ts +2 -0
- package/dist/webhook.d.ts.map +1 -0
- package/dist/webhook.js +90 -0
- package/dist/webhook.js.map +1 -0
- package/landing/DESIGN.md +343 -0
- package/landing/package-lock.json +1190 -40
- package/landing/package.json +5 -2
- package/landing/public/android-chrome-192x192.png +0 -0
- package/landing/public/android-chrome-512x512.png +0 -0
- package/landing/public/apple-touch-icon.png +0 -0
- package/landing/public/demo.gif +0 -0
- package/landing/public/demo.mp4 +0 -0
- package/landing/public/favicon-16x16.png +0 -0
- package/landing/public/favicon-32x32.png +0 -0
- package/landing/public/favicon.ico +0 -0
- package/landing/public/favicon.svg +3 -0
- package/landing/public/icon.svg +47 -0
- package/landing/public/logo-mono.svg +37 -0
- package/landing/public/logo-simple.svg +45 -0
- package/landing/public/logo.svg +84 -0
- package/landing/public/og-image.png +0 -0
- package/landing/public/og-template.html +184 -0
- package/landing/public/site.webmanifest +31 -0
- package/landing/scripts/generate-assets.js +284 -0
- package/landing/scripts/generate-pngs.js +48 -0
- package/landing/scripts/generate-stats.js +42 -0
- package/landing/src/app/admin/page.tsx +348 -0
- package/landing/src/app/api/auth/magic-link/route.ts +73 -0
- package/landing/src/app/api/auth/session/route.ts +38 -0
- package/landing/src/app/api/auth/verify/route.ts +43 -0
- package/landing/src/app/api/og/route.tsx +74 -0
- package/landing/src/app/globals.css +439 -100
- package/landing/src/app/layout.tsx +37 -9
- package/landing/src/app/page.tsx +640 -552
- package/landing/src/app/providers/dashboard/login/page.tsx +176 -0
- package/landing/src/app/providers/dashboard/page.tsx +589 -0
- package/landing/src/app/providers/dashboard/verify/page.tsx +106 -0
- package/landing/src/app/providers/layout.tsx +14 -0
- package/landing/src/app/providers/page.tsx +402 -0
- package/landing/src/app/providers/register/page.tsx +670 -0
- package/landing/src/components/ProviderDashboard.tsx +794 -0
- package/landing/src/hooks/useDashboardData.ts +99 -0
- package/landing/src/lib/apis.json +116054 -0
- package/landing/src/lib/convex-client.ts +106 -0
- package/landing/src/lib/mock-data.ts +285 -0
- package/landing/src/lib/stats.json +6 -0
- package/landing/tailwind.config.ts +12 -11
- package/landing/tsconfig.tsbuildinfo +1 -0
- package/package.json +21 -20
- package/scripts/SYMBOT-FIX.md +238 -0
- package/scripts/demo-simulation.py +177 -0
- package/scripts/expand-more.py +502 -0
- package/scripts/expand-registry.py +434 -0
- package/scripts/history-sanitizer.ts +272 -0
- package/scripts/mass-scrape.py +1308 -0
- package/scripts/sync-and-deploy.sh +36 -0
- package/src/credentials.ts +177 -0
- package/src/credits.ts +190 -122
- package/src/discovery.ts +45 -58
- package/src/execute.ts +350 -0
- package/src/index.ts +113 -31
- package/src/proxy.ts +24 -0
- package/src/registry/apis.json +95362 -202
- package/src/registry/apis_expanded.json +100853 -0
- package/src/stripe.ts +243 -0
- package/src/test.ts +127 -89
- package/src/types.ts +0 -34
- package/src/webhook.ts +107 -0
- package/.github/ISSUE_TEMPLATE/add-api.yml +0 -123
- package/BRIEFING.md +0 -30
- package/backend/convex/apiKeys.ts +0 -75
- package/backend/convex/purchases.ts +0 -74
- package/backend/convex/schema.ts +0 -45
- package/backend/convex/transactions.ts +0 -57
- package/backend/convex/users.ts +0 -94
- package/backend/package-lock.json +0 -521
- package/backend/package.json +0 -15
- package/dist/registry/parse_apis.py +0 -146
- package/dist/revenuecat.d.ts +0 -61
- package/dist/revenuecat.d.ts.map +0 -1
- package/dist/revenuecat.js +0 -166
- package/dist/revenuecat.js.map +0 -1
- package/dist/webhooks/revenuecat.d.ts +0 -48
- package/dist/webhooks/revenuecat.d.ts.map +0 -1
- package/dist/webhooks/revenuecat.js +0 -119
- package/dist/webhooks/revenuecat.js.map +0 -1
- package/docs/revenuecat-setup.md +0 -89
- package/landing/src/app/api/keys/route.ts +0 -71
- package/landing/src/app/api/log/route.ts +0 -37
- package/landing/src/app/api/stats/route.ts +0 -37
- package/landing/src/app/page.tsx.bak +0 -567
- package/landing/src/components/AddKeyModal.tsx +0 -159
- package/newsletter-template.html +0 -71
- package/outreach/OUTREACH-SYSTEM.md +0 -211
- package/outreach/email-template.html +0 -179
- package/outreach/targets.md +0 -133
- package/src/registry/parse_apis.py +0 -146
- package/src/revenuecat.ts +0 -239
- package/src/webhooks/revenuecat.ts +0 -187
- /package/{backend/convex → convex}/README.md +0 -0
- /package/{backend/convex → convex}/_generated/api.js +0 -0
- /package/{backend/convex → convex}/_generated/dataModel.d.ts +0 -0
- /package/{backend/convex → convex}/_generated/server.d.ts +0 -0
- /package/{backend/convex → convex}/_generated/server.js +0 -0
- /package/{backend/convex → convex}/tsconfig.json +0 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useState, Suspense } from "react";
|
|
4
|
+
import { useRouter, useSearchParams } from "next/navigation";
|
|
5
|
+
import { Loader2, AlertCircle, Check } from "lucide-react";
|
|
6
|
+
import Link from "next/link";
|
|
7
|
+
|
|
8
|
+
function VerifyContent() {
|
|
9
|
+
const router = useRouter();
|
|
10
|
+
const searchParams = useSearchParams();
|
|
11
|
+
const token = searchParams.get("token");
|
|
12
|
+
|
|
13
|
+
const [status, setStatus] = useState<"verifying" | "success" | "error">("verifying");
|
|
14
|
+
const [error, setError] = useState<string | null>(null);
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (!token) {
|
|
18
|
+
setStatus("error");
|
|
19
|
+
setError("No token provided");
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const verify = async () => {
|
|
24
|
+
try {
|
|
25
|
+
const response = await fetch("/api/auth/verify", {
|
|
26
|
+
method: "POST",
|
|
27
|
+
headers: { "Content-Type": "application/json" },
|
|
28
|
+
body: JSON.stringify({ token }),
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const data = await response.json();
|
|
32
|
+
|
|
33
|
+
if (!response.ok || !data.success) {
|
|
34
|
+
throw new Error(data.error || "Verification failed");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Store session token
|
|
38
|
+
localStorage.setItem("apiclaw_session", data.sessionToken);
|
|
39
|
+
localStorage.setItem("apiclaw_provider", JSON.stringify(data.provider));
|
|
40
|
+
|
|
41
|
+
setStatus("success");
|
|
42
|
+
|
|
43
|
+
// Redirect to dashboard after a short delay
|
|
44
|
+
setTimeout(() => {
|
|
45
|
+
router.push("/providers/dashboard");
|
|
46
|
+
}, 1500);
|
|
47
|
+
} catch (err) {
|
|
48
|
+
setStatus("error");
|
|
49
|
+
setError(err instanceof Error ? err.message : "Verification failed");
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
verify();
|
|
54
|
+
}, [token, router]);
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<main className="min-h-screen flex items-center justify-center px-6">
|
|
58
|
+
<div className="max-w-md w-full text-center">
|
|
59
|
+
{status === "verifying" && (
|
|
60
|
+
<>
|
|
61
|
+
<Loader2 className="w-16 h-16 text-accent animate-spin mx-auto mb-6" />
|
|
62
|
+
<h1 className="text-2xl font-bold mb-2">Verifying...</h1>
|
|
63
|
+
<p className="text-text-muted">Please wait while we verify your link.</p>
|
|
64
|
+
</>
|
|
65
|
+
)}
|
|
66
|
+
|
|
67
|
+
{status === "success" && (
|
|
68
|
+
<>
|
|
69
|
+
<div className="w-20 h-20 rounded-full bg-green-500/20 flex items-center justify-center mx-auto mb-6">
|
|
70
|
+
<Check className="w-10 h-10 text-green-500" />
|
|
71
|
+
</div>
|
|
72
|
+
<h1 className="text-2xl font-bold mb-2">You're In!</h1>
|
|
73
|
+
<p className="text-text-muted">Redirecting to your dashboard...</p>
|
|
74
|
+
</>
|
|
75
|
+
)}
|
|
76
|
+
|
|
77
|
+
{status === "error" && (
|
|
78
|
+
<>
|
|
79
|
+
<div className="w-20 h-20 rounded-full bg-red-500/20 flex items-center justify-center mx-auto mb-6">
|
|
80
|
+
<AlertCircle className="w-10 h-10 text-red-500" />
|
|
81
|
+
</div>
|
|
82
|
+
<h1 className="text-2xl font-bold mb-2">Verification Failed</h1>
|
|
83
|
+
<p className="text-text-muted mb-6">{error || "The link may be expired or invalid."}</p>
|
|
84
|
+
<Link href="/providers/dashboard/login" className="btn-primary">
|
|
85
|
+
Try Again
|
|
86
|
+
</Link>
|
|
87
|
+
</>
|
|
88
|
+
)}
|
|
89
|
+
</div>
|
|
90
|
+
</main>
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export default function VerifyPage() {
|
|
95
|
+
return (
|
|
96
|
+
<Suspense
|
|
97
|
+
fallback={
|
|
98
|
+
<main className="min-h-screen flex items-center justify-center">
|
|
99
|
+
<Loader2 className="w-16 h-16 text-accent animate-spin" />
|
|
100
|
+
</main>
|
|
101
|
+
}
|
|
102
|
+
>
|
|
103
|
+
<VerifyContent />
|
|
104
|
+
</Suspense>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
|
|
3
|
+
export const metadata: Metadata = {
|
|
4
|
+
title: "Provider Dashboard | APIClaw",
|
|
5
|
+
description: "Manage your APIs, view analytics, and track earnings on APIClaw.",
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export default function ProvidersLayout({
|
|
9
|
+
children,
|
|
10
|
+
}: {
|
|
11
|
+
children: React.ReactNode;
|
|
12
|
+
}) {
|
|
13
|
+
return <>{children}</>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
ArrowRight, Zap, BarChart3, Globe, Shield, Users, Clock, CheckCircle2,
|
|
5
|
+
TrendingUp, Sun, Moon, Github, Twitter
|
|
6
|
+
} from "lucide-react";
|
|
7
|
+
import { useState, useEffect } from "react";
|
|
8
|
+
import Link from "next/link";
|
|
9
|
+
import statsData from "@/lib/stats.json";
|
|
10
|
+
|
|
11
|
+
const benefits = [
|
|
12
|
+
{
|
|
13
|
+
icon: Users,
|
|
14
|
+
title: "Agent Traffic",
|
|
15
|
+
description: "Get discovered by thousands of AI agents actively searching for APIs to integrate."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
icon: Zap,
|
|
19
|
+
title: "Zero Integration",
|
|
20
|
+
description: "No SDK needed. Agents find your API through natural language queries."
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
icon: BarChart3,
|
|
24
|
+
title: "Analytics Dashboard",
|
|
25
|
+
description: "Track how agents discover, evaluate, and choose your API."
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
icon: Globe,
|
|
29
|
+
title: "Global Reach",
|
|
30
|
+
description: "Your API instantly available to the growing ecosystem of autonomous agents."
|
|
31
|
+
},
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
const steps = [
|
|
35
|
+
{
|
|
36
|
+
step: "1",
|
|
37
|
+
title: "Submit your API",
|
|
38
|
+
description: "Add your API details, OpenAPI spec, and pricing info.",
|
|
39
|
+
time: "2 min"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
step: "2",
|
|
43
|
+
title: "We verify",
|
|
44
|
+
description: "Quick review to ensure quality and accuracy.",
|
|
45
|
+
time: "< 24h"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
step: "3",
|
|
49
|
+
title: "Go live",
|
|
50
|
+
description: "Your API appears in agent search results.",
|
|
51
|
+
time: "Instant"
|
|
52
|
+
},
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
const stats = [
|
|
56
|
+
{ value: `${statsData.apiCount.toLocaleString()}+`, label: "APIs listed" },
|
|
57
|
+
{ value: statsData.categoryCount.toString(), label: "Categories" },
|
|
58
|
+
{ value: "10K+", label: "Daily queries" },
|
|
59
|
+
{ value: "Free", label: "To list" },
|
|
60
|
+
];
|
|
61
|
+
|
|
62
|
+
export default function ProvidersPage() {
|
|
63
|
+
const [isDark, setIsDark] = useState(true);
|
|
64
|
+
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
const saved = localStorage.getItem('theme');
|
|
67
|
+
const prefersDark = saved !== 'light';
|
|
68
|
+
setIsDark(prefersDark);
|
|
69
|
+
document.documentElement.classList.toggle('dark', prefersDark);
|
|
70
|
+
}, []);
|
|
71
|
+
|
|
72
|
+
const toggleTheme = () => {
|
|
73
|
+
const newTheme = !isDark;
|
|
74
|
+
setIsDark(newTheme);
|
|
75
|
+
document.documentElement.classList.toggle('dark', newTheme);
|
|
76
|
+
localStorage.setItem('theme', newTheme ? 'dark' : 'light');
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<main className="min-h-screen">
|
|
81
|
+
{/* Header */}
|
|
82
|
+
<header className="fixed top-0 w-full z-50 bg-background/80 backdrop-blur-xl border-b border-border-subtle">
|
|
83
|
+
<div className="max-w-6xl mx-auto px-6 py-4 flex items-center justify-between">
|
|
84
|
+
<Link href="/" className="flex items-center gap-3">
|
|
85
|
+
<div className="w-10 h-10 rounded-xl bg-accent/20 flex items-center justify-center text-2xl">
|
|
86
|
+
🦞
|
|
87
|
+
</div>
|
|
88
|
+
<span className="font-bold text-xl tracking-tight">APIClaw</span>
|
|
89
|
+
</Link>
|
|
90
|
+
<nav className="hidden md:flex items-center gap-8 text-sm text-text-muted">
|
|
91
|
+
<Link href="/#how-it-works" className="hover:text-text-primary transition">How It Works</Link>
|
|
92
|
+
<Link href="/#for-agents" className="hover:text-text-primary transition">For Agents</Link>
|
|
93
|
+
<Link href="/providers" className="text-accent font-medium">For Providers</Link>
|
|
94
|
+
</nav>
|
|
95
|
+
<div className="flex items-center gap-3">
|
|
96
|
+
<button
|
|
97
|
+
onClick={toggleTheme}
|
|
98
|
+
className="p-2.5 rounded-lg hover:bg-surface transition"
|
|
99
|
+
aria-label="Toggle theme"
|
|
100
|
+
>
|
|
101
|
+
{isDark ? <Sun className="w-5 h-5" /> : <Moon className="w-5 h-5" />}
|
|
102
|
+
</button>
|
|
103
|
+
<Link
|
|
104
|
+
href="/providers/register"
|
|
105
|
+
className="btn-primary !py-2.5 !px-5 text-sm"
|
|
106
|
+
>
|
|
107
|
+
<span>List Your API</span>
|
|
108
|
+
<ArrowRight className="w-4 h-4" />
|
|
109
|
+
</Link>
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
</header>
|
|
113
|
+
|
|
114
|
+
{/* Hero */}
|
|
115
|
+
<section className="pt-36 pb-24 px-6">
|
|
116
|
+
<div className="max-w-4xl mx-auto text-center">
|
|
117
|
+
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-accent/10 border border-accent/20 text-accent text-sm font-medium mb-8">
|
|
118
|
+
<TrendingUp className="w-4 h-4" />
|
|
119
|
+
<span>For API Providers</span>
|
|
120
|
+
</div>
|
|
121
|
+
|
|
122
|
+
<h1 className="text-5xl md:text-7xl font-extrabold mb-6 leading-[1.1] tracking-tighter">
|
|
123
|
+
<span className="gradient-text">Get Your API</span>
|
|
124
|
+
<br />
|
|
125
|
+
<span className="text-text-primary">in Front of AI Agents</span>
|
|
126
|
+
</h1>
|
|
127
|
+
|
|
128
|
+
<p className="text-xl md:text-2xl text-text-secondary mb-4 max-w-2xl mx-auto leading-relaxed">
|
|
129
|
+
The agentic era is here. Agents don't browse — they query.
|
|
130
|
+
</p>
|
|
131
|
+
<p className="text-lg text-text-muted mb-12">
|
|
132
|
+
List your API where agents are looking.
|
|
133
|
+
</p>
|
|
134
|
+
|
|
135
|
+
<div className="flex flex-col sm:flex-row items-center justify-center gap-4 mb-16">
|
|
136
|
+
<Link href="/providers/register" className="btn-primary glow">
|
|
137
|
+
<Zap className="w-5 h-5" />
|
|
138
|
+
List Your API — Free
|
|
139
|
+
</Link>
|
|
140
|
+
<a href="#how-it-works" className="btn-secondary">
|
|
141
|
+
<span>How It Works</span>
|
|
142
|
+
<ArrowRight className="w-4 h-4" />
|
|
143
|
+
</a>
|
|
144
|
+
</div>
|
|
145
|
+
|
|
146
|
+
{/* Stats */}
|
|
147
|
+
<div className="grid grid-cols-2 md:grid-cols-4 gap-6">
|
|
148
|
+
{stats.map((stat, i) => (
|
|
149
|
+
<div key={i} className="text-center p-4 rounded-xl bg-surface-elevated border border-border">
|
|
150
|
+
<div className="text-2xl md:text-3xl font-bold text-accent">{stat.value}</div>
|
|
151
|
+
<div className="text-text-muted text-sm">{stat.label}</div>
|
|
152
|
+
</div>
|
|
153
|
+
))}
|
|
154
|
+
</div>
|
|
155
|
+
</div>
|
|
156
|
+
</section>
|
|
157
|
+
|
|
158
|
+
<div className="divider" />
|
|
159
|
+
|
|
160
|
+
{/* Why List on APIClaw */}
|
|
161
|
+
<section className="py-24 px-6 bg-surface/30">
|
|
162
|
+
<div className="max-w-6xl mx-auto">
|
|
163
|
+
<div className="text-center mb-16">
|
|
164
|
+
<span className="section-label">BENEFITS</span>
|
|
165
|
+
<h2 className="text-3xl md:text-4xl font-bold mt-4 tracking-tight">Why List on APIClaw?</h2>
|
|
166
|
+
<p className="text-text-secondary text-lg mt-4">
|
|
167
|
+
Position your API for the agent-first future.
|
|
168
|
+
</p>
|
|
169
|
+
</div>
|
|
170
|
+
|
|
171
|
+
<div className="grid sm:grid-cols-2 lg:grid-cols-4 gap-6">
|
|
172
|
+
{benefits.map((b, i) => (
|
|
173
|
+
<div key={i} className="card-hover rounded-2xl bg-surface-elevated border border-border p-6">
|
|
174
|
+
<div className="w-12 h-12 rounded-xl bg-accent/10 flex items-center justify-center mb-4">
|
|
175
|
+
<b.icon className="w-6 h-6 text-accent" />
|
|
176
|
+
</div>
|
|
177
|
+
<h3 className="font-semibold text-lg mb-2">{b.title}</h3>
|
|
178
|
+
<p className="text-text-secondary text-sm leading-relaxed">{b.description}</p>
|
|
179
|
+
</div>
|
|
180
|
+
))}
|
|
181
|
+
</div>
|
|
182
|
+
</div>
|
|
183
|
+
</section>
|
|
184
|
+
|
|
185
|
+
<div className="divider" />
|
|
186
|
+
|
|
187
|
+
{/* How It Works */}
|
|
188
|
+
<section id="how-it-works" className="py-24 px-6">
|
|
189
|
+
<div className="max-w-4xl mx-auto">
|
|
190
|
+
<div className="text-center mb-16">
|
|
191
|
+
<span className="section-label">PROCESS</span>
|
|
192
|
+
<h2 className="text-3xl md:text-4xl font-bold mt-4 tracking-tight">Listed in 5 Minutes</h2>
|
|
193
|
+
<p className="text-text-secondary text-lg mt-4">
|
|
194
|
+
Simple onboarding. No technical integration required.
|
|
195
|
+
</p>
|
|
196
|
+
</div>
|
|
197
|
+
|
|
198
|
+
<div className="grid md:grid-cols-3 gap-8">
|
|
199
|
+
{steps.map((item, i) => (
|
|
200
|
+
<div key={i} className="text-center">
|
|
201
|
+
<div className="w-16 h-16 rounded-full bg-accent/20 text-accent font-bold text-2xl flex items-center justify-center mx-auto mb-6">
|
|
202
|
+
{item.step}
|
|
203
|
+
</div>
|
|
204
|
+
<h3 className="font-semibold text-xl mb-2">{item.title}</h3>
|
|
205
|
+
<p className="text-text-secondary mb-3">{item.description}</p>
|
|
206
|
+
<div className="inline-flex items-center gap-2 text-sm text-accent">
|
|
207
|
+
<Clock className="w-4 h-4" />
|
|
208
|
+
{item.time}
|
|
209
|
+
</div>
|
|
210
|
+
</div>
|
|
211
|
+
))}
|
|
212
|
+
</div>
|
|
213
|
+
|
|
214
|
+
<div className="text-center mt-12">
|
|
215
|
+
<Link href="/providers/register" className="btn-primary glow">
|
|
216
|
+
<Zap className="w-5 h-5" />
|
|
217
|
+
Get Started Now
|
|
218
|
+
</Link>
|
|
219
|
+
</div>
|
|
220
|
+
</div>
|
|
221
|
+
</section>
|
|
222
|
+
|
|
223
|
+
<div className="divider" />
|
|
224
|
+
|
|
225
|
+
{/* What You Get */}
|
|
226
|
+
<section className="py-24 px-6 bg-surface/30">
|
|
227
|
+
<div className="max-w-4xl mx-auto">
|
|
228
|
+
<div className="text-center mb-16">
|
|
229
|
+
<span className="section-label">INCLUDED</span>
|
|
230
|
+
<h2 className="text-3xl md:text-4xl font-bold mt-4 tracking-tight">Everything You Need</h2>
|
|
231
|
+
</div>
|
|
232
|
+
|
|
233
|
+
<div className="grid md:grid-cols-2 gap-6">
|
|
234
|
+
<div className="rounded-2xl bg-surface-elevated border border-border p-8">
|
|
235
|
+
<h3 className="text-xl font-semibold mb-6 flex items-center gap-3">
|
|
236
|
+
<span className="text-2xl">🆓</span>
|
|
237
|
+
Free Tier
|
|
238
|
+
</h3>
|
|
239
|
+
<ul className="space-y-4">
|
|
240
|
+
{[
|
|
241
|
+
"Listed in API discovery",
|
|
242
|
+
"Searchable by agents",
|
|
243
|
+
"Basic analytics",
|
|
244
|
+
"Category placement",
|
|
245
|
+
"Link to your docs"
|
|
246
|
+
].map((item, i) => (
|
|
247
|
+
<li key={i} className="flex items-center gap-3 text-text-secondary">
|
|
248
|
+
<CheckCircle2 className="w-5 h-5 text-accent flex-shrink-0" />
|
|
249
|
+
{item}
|
|
250
|
+
</li>
|
|
251
|
+
))}
|
|
252
|
+
</ul>
|
|
253
|
+
</div>
|
|
254
|
+
|
|
255
|
+
<div className="rounded-2xl bg-surface-elevated border border-accent/30 p-8 relative">
|
|
256
|
+
<div className="absolute -top-3 right-6 px-3 py-1 bg-accent text-background text-xs font-bold tracking-wide rounded-full uppercase">
|
|
257
|
+
Coming Soon
|
|
258
|
+
</div>
|
|
259
|
+
<h3 className="text-xl font-semibold mb-6 flex items-center gap-3">
|
|
260
|
+
<span className="text-2xl">⚡</span>
|
|
261
|
+
Premium
|
|
262
|
+
</h3>
|
|
263
|
+
<ul className="space-y-4">
|
|
264
|
+
{[
|
|
265
|
+
"Everything in Free",
|
|
266
|
+
"Featured placement",
|
|
267
|
+
"Advanced analytics",
|
|
268
|
+
"Direct provisioning",
|
|
269
|
+
"Usage-based revenue"
|
|
270
|
+
].map((item, i) => (
|
|
271
|
+
<li key={i} className="flex items-center gap-3 text-text-secondary">
|
|
272
|
+
<CheckCircle2 className="w-5 h-5 text-accent flex-shrink-0" />
|
|
273
|
+
{item}
|
|
274
|
+
</li>
|
|
275
|
+
))}
|
|
276
|
+
</ul>
|
|
277
|
+
</div>
|
|
278
|
+
</div>
|
|
279
|
+
</div>
|
|
280
|
+
</section>
|
|
281
|
+
|
|
282
|
+
<div className="divider" />
|
|
283
|
+
|
|
284
|
+
{/* FAQ */}
|
|
285
|
+
<section className="py-24 px-6">
|
|
286
|
+
<div className="max-w-3xl mx-auto">
|
|
287
|
+
<div className="text-center mb-16">
|
|
288
|
+
<span className="section-label">FAQ</span>
|
|
289
|
+
<h2 className="text-3xl md:text-4xl font-bold mt-4 tracking-tight">Questions?</h2>
|
|
290
|
+
</div>
|
|
291
|
+
|
|
292
|
+
<div className="space-y-6">
|
|
293
|
+
{[
|
|
294
|
+
{
|
|
295
|
+
q: "Is it really free?",
|
|
296
|
+
a: "Yes. Basic listing is free forever. We may introduce premium features later, but discovery is always free."
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
q: "What information do I need?",
|
|
300
|
+
a: "API name, description, category, and pricing model. OpenAPI spec is optional but helps agents understand your API better."
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
q: "How long does approval take?",
|
|
304
|
+
a: "Most APIs are reviewed within 24 hours. If you have an OpenAPI spec, it's often instant."
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
q: "Do I need to integrate anything?",
|
|
308
|
+
a: "No. Agents discover your API through APIClaw and then use your existing docs and signup flow."
|
|
309
|
+
},
|
|
310
|
+
].map((item, i) => (
|
|
311
|
+
<div key={i} className="rounded-xl bg-surface-elevated border border-border p-6">
|
|
312
|
+
<h3 className="font-semibold text-lg mb-2">{item.q}</h3>
|
|
313
|
+
<p className="text-text-secondary">{item.a}</p>
|
|
314
|
+
</div>
|
|
315
|
+
))}
|
|
316
|
+
</div>
|
|
317
|
+
</div>
|
|
318
|
+
</section>
|
|
319
|
+
|
|
320
|
+
{/* CTA */}
|
|
321
|
+
<section className="py-24 px-6 bg-surface/30">
|
|
322
|
+
<div className="max-w-2xl mx-auto text-center">
|
|
323
|
+
<h2 className="text-3xl md:text-4xl font-bold mb-6 tracking-tight">Ready to reach AI agents?</h2>
|
|
324
|
+
<p className="text-text-secondary text-lg mb-8">
|
|
325
|
+
Join {statsData.apiCount.toLocaleString()}+ APIs already listed on APIClaw.
|
|
326
|
+
</p>
|
|
327
|
+
<Link href="/providers/register" className="btn-primary glow inline-flex">
|
|
328
|
+
<Zap className="w-5 h-5" />
|
|
329
|
+
List Your API — Free
|
|
330
|
+
</Link>
|
|
331
|
+
</div>
|
|
332
|
+
</section>
|
|
333
|
+
|
|
334
|
+
{/* Footer */}
|
|
335
|
+
<footer className="border-t border-border py-16 px-6">
|
|
336
|
+
<div className="max-w-6xl mx-auto">
|
|
337
|
+
<div className="grid md:grid-cols-4 gap-12 mb-12">
|
|
338
|
+
<div className="md:col-span-2">
|
|
339
|
+
<Link href="/" className="flex items-center gap-3 mb-4">
|
|
340
|
+
<div className="w-10 h-10 rounded-xl bg-accent/20 flex items-center justify-center text-2xl">
|
|
341
|
+
🦞
|
|
342
|
+
</div>
|
|
343
|
+
<span className="font-bold text-xl tracking-tight">APIClaw</span>
|
|
344
|
+
</Link>
|
|
345
|
+
<p className="text-text-muted mb-6 max-w-sm">
|
|
346
|
+
The API discovery layer for autonomous agents. Connect your API to the agentic era.
|
|
347
|
+
</p>
|
|
348
|
+
<div className="flex items-center gap-4">
|
|
349
|
+
<a
|
|
350
|
+
href="https://github.com/nordsym/apiclaw"
|
|
351
|
+
target="_blank"
|
|
352
|
+
rel="noopener noreferrer"
|
|
353
|
+
className="w-10 h-10 rounded-lg bg-surface-elevated border border-border flex items-center justify-center text-text-muted hover:text-text-primary hover:border-accent/50 transition"
|
|
354
|
+
>
|
|
355
|
+
<Github className="w-5 h-5" />
|
|
356
|
+
</a>
|
|
357
|
+
<a
|
|
358
|
+
href="https://twitter.com/nordsym"
|
|
359
|
+
target="_blank"
|
|
360
|
+
rel="noopener noreferrer"
|
|
361
|
+
className="w-10 h-10 rounded-lg bg-surface-elevated border border-border flex items-center justify-center text-text-muted hover:text-text-primary hover:border-accent/50 transition"
|
|
362
|
+
>
|
|
363
|
+
<Twitter className="w-5 h-5" />
|
|
364
|
+
</a>
|
|
365
|
+
</div>
|
|
366
|
+
</div>
|
|
367
|
+
|
|
368
|
+
<div>
|
|
369
|
+
<h4 className="font-semibold mb-4">Product</h4>
|
|
370
|
+
<ul className="space-y-3 text-text-muted">
|
|
371
|
+
<li><Link href="/#how-it-works" className="hover:text-text-primary transition">How It Works</Link></li>
|
|
372
|
+
<li><Link href="/#for-agents" className="hover:text-text-primary transition">For Agents</Link></li>
|
|
373
|
+
<li><Link href="/providers" className="hover:text-text-primary transition">For Providers</Link></li>
|
|
374
|
+
</ul>
|
|
375
|
+
</div>
|
|
376
|
+
|
|
377
|
+
<div>
|
|
378
|
+
<h4 className="font-semibold mb-4">Company</h4>
|
|
379
|
+
<ul className="space-y-3 text-text-muted">
|
|
380
|
+
<li><a href="https://nordsym.com" target="_blank" rel="noopener noreferrer" className="hover:text-text-primary transition">NordSym</a></li>
|
|
381
|
+
<li><a href="https://github.com/nordsym" target="_blank" rel="noopener noreferrer" className="hover:text-text-primary transition">GitHub</a></li>
|
|
382
|
+
<li><a href="https://twitter.com/nordsym" target="_blank" rel="noopener noreferrer" className="hover:text-text-primary transition">Twitter</a></li>
|
|
383
|
+
</ul>
|
|
384
|
+
</div>
|
|
385
|
+
</div>
|
|
386
|
+
|
|
387
|
+
<div className="pt-8 border-t border-border flex flex-col md:flex-row items-center justify-between gap-4">
|
|
388
|
+
<p className="text-text-muted text-sm">
|
|
389
|
+
© 2026 NordSym. All rights reserved.
|
|
390
|
+
</p>
|
|
391
|
+
<div className="flex items-center gap-3">
|
|
392
|
+
<div className="inline-flex items-center gap-2 px-3 py-1.5 rounded-full bg-accent/10 border border-accent/20 text-accent text-xs font-medium">
|
|
393
|
+
<Shield className="w-3 h-3" />
|
|
394
|
+
MCP Compatible
|
|
395
|
+
</div>
|
|
396
|
+
</div>
|
|
397
|
+
</div>
|
|
398
|
+
</div>
|
|
399
|
+
</footer>
|
|
400
|
+
</main>
|
|
401
|
+
);
|
|
402
|
+
}
|