@nordsym/apiclaw 1.2.0 → 1.2.2
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/.env.prod +1 -0
- package/README.md +5 -5
- package/STATUS.md +7 -7
- package/convex/http.ts +33 -1
- package/data/combined-02-25.json +5602 -0
- package/data/night-batch-02-25.json +2732 -0
- package/data/night-expansion-02-25.json +2872 -0
- package/dist/credentials.d.ts.map +1 -1
- package/dist/credentials.js +15 -0
- package/dist/credentials.js.map +1 -1
- package/dist/execute.d.ts +1 -1
- package/dist/execute.d.ts.map +1 -1
- package/dist/execute.js +77 -1
- package/dist/execute.js.map +1 -1
- package/dist/index.js +9 -7
- package/dist/index.js.map +1 -1
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +1 -1
- package/dist/proxy.js.map +1 -1
- package/dist/registry/apis.json +44476 -174
- package/landing/src/app/api/auth/magic-link/route.ts +8 -1
- package/landing/src/app/api/auth/verify/route.ts +7 -4
- package/landing/src/app/docs/page.tsx +83 -82
- package/landing/src/app/earn/page.tsx +8 -8
- package/landing/src/app/page.tsx +208 -15
- package/landing/src/app/providers/page.tsx +6 -5
- package/landing/src/app/providers/register/page.tsx +1 -1
- package/landing/src/lib/convex-client.ts +6 -2
- package/landing/src/lib/stats.json +1 -1
- package/package.json +3 -2
- package/scripts/merge-to-registry.py +77 -0
- package/scripts/night-batch-02-24.py +391 -0
- package/scripts/night-batch-02-25.py +479 -0
- package/scripts/night-batch-03-24-b2.py +387 -0
- package/scripts/night-batch-03-24-b3.py +284 -0
- package/scripts/night-batch-03-24.py +447 -0
- package/scripts/night-batch-06-24-b2.py +695 -0
- package/scripts/night-batch-06-24-b3.py +696 -0
- package/scripts/night-batch-06-24.py +825 -0
- package/scripts/night-expansion-02-24-02.py +708 -0
- package/scripts/night-expansion-02-25.py +668 -0
- package/src/credentials.ts +16 -0
- package/src/execute.ts +87 -1
- package/src/index.ts +9 -7
- package/src/proxy.ts +1 -1
- package/src/registry/apis.json +44476 -174
|
@@ -24,7 +24,14 @@ export async function POST(req: NextRequest) {
|
|
|
24
24
|
throw new Error("Failed to create magic link");
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
const
|
|
27
|
+
const result = await response.json();
|
|
28
|
+
|
|
29
|
+
// Convex wraps response in { status: "success", value: {...} }
|
|
30
|
+
const token = result.value?.token || result.token;
|
|
31
|
+
|
|
32
|
+
if (!token) {
|
|
33
|
+
throw new Error("Failed to get token from Convex");
|
|
34
|
+
}
|
|
28
35
|
|
|
29
36
|
// Send magic link email via n8n
|
|
30
37
|
const magicLinkUrl = `${process.env.NEXT_PUBLIC_APP_URL || "https://apiclaw.nordsym.com"}/providers/dashboard/verify?token=${token}`;
|
|
@@ -25,16 +25,19 @@ export async function POST(req: NextRequest) {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
const result = await response.json();
|
|
28
|
+
|
|
29
|
+
// Convex wraps response in { status: "success", value: {...} }
|
|
30
|
+
const data = result.value || result;
|
|
28
31
|
|
|
29
|
-
if (!
|
|
30
|
-
return NextResponse.json({ error:
|
|
32
|
+
if (!data.success) {
|
|
33
|
+
return NextResponse.json({ error: data.error || "Invalid token" }, { status: 400 });
|
|
31
34
|
}
|
|
32
35
|
|
|
33
36
|
// Return session token
|
|
34
37
|
return NextResponse.json({
|
|
35
38
|
success: true,
|
|
36
|
-
sessionToken:
|
|
37
|
-
provider:
|
|
39
|
+
sessionToken: data.sessionToken,
|
|
40
|
+
provider: data.provider,
|
|
38
41
|
});
|
|
39
42
|
} catch (error) {
|
|
40
43
|
console.error("Verify error:", error);
|
|
@@ -5,12 +5,12 @@ import { useState, useEffect } from 'react';
|
|
|
5
5
|
import { Sun, Moon } from 'lucide-react';
|
|
6
6
|
|
|
7
7
|
export default function DocsPage() {
|
|
8
|
-
const [theme, setTheme] = useState<'light' | 'dark'>('
|
|
8
|
+
const [theme, setTheme] = useState<'light' | 'dark'>('light');
|
|
9
9
|
|
|
10
10
|
useEffect(() => {
|
|
11
11
|
const savedTheme = localStorage.getItem('apiclaw-theme') as 'light' | 'dark' | null;
|
|
12
|
-
|
|
13
|
-
const initialTheme = savedTheme ||
|
|
12
|
+
// Default to light for docs
|
|
13
|
+
const initialTheme = savedTheme || 'light';
|
|
14
14
|
setTheme(initialTheme);
|
|
15
15
|
document.documentElement.classList.toggle('dark', initialTheme === 'dark');
|
|
16
16
|
}, []);
|
|
@@ -33,14 +33,14 @@ export default function DocsPage() {
|
|
|
33
33
|
APIClaw
|
|
34
34
|
</span>
|
|
35
35
|
</Link>
|
|
36
|
-
<nav className="flex items-center gap-6">
|
|
37
|
-
<Link href="/" className="text-[var(--text-secondary)] hover:text-[var(--accent)] transition-colors">Home</Link>
|
|
38
|
-
<Link href="/providers" className="text-[var(--text-secondary)] hover:text-[var(--accent)] transition-colors">Providers</Link>
|
|
39
|
-
<Link href="/earn" className="text-[var(--text-secondary)] hover:text-[var(--accent)] transition-colors">Earn Credits</Link>
|
|
36
|
+
<nav className="flex items-center gap-4 md:gap-6">
|
|
37
|
+
<Link href="/" className="hidden sm:block text-[var(--text-secondary)] hover:text-[var(--accent)] transition-colors text-sm md:text-base">Home</Link>
|
|
38
|
+
<Link href="/providers" className="hidden md:block text-[var(--text-secondary)] hover:text-[var(--accent)] transition-colors text-sm md:text-base">Providers</Link>
|
|
39
|
+
<Link href="/earn" className="hidden md:block text-[var(--text-secondary)] hover:text-[var(--accent)] transition-colors text-sm md:text-base">Earn Credits</Link>
|
|
40
40
|
<a
|
|
41
41
|
href="https://github.com/nordsym/apiclaw"
|
|
42
42
|
target="_blank"
|
|
43
|
-
className="text-[var(--text-secondary)] hover:text-[var(--accent)] transition-colors"
|
|
43
|
+
className="text-[var(--text-secondary)] hover:text-[var(--accent)] transition-colors text-sm md:text-base"
|
|
44
44
|
>
|
|
45
45
|
GitHub
|
|
46
46
|
</a>
|
|
@@ -112,6 +112,67 @@ export default function DocsPage() {
|
|
|
112
112
|
</div>
|
|
113
113
|
</section>
|
|
114
114
|
|
|
115
|
+
|
|
116
|
+
{/* Examples */}
|
|
117
|
+
<section className="mb-16">
|
|
118
|
+
<h2 className="text-2xl font-bold mb-6 flex items-center gap-3">
|
|
119
|
+
<span className="text-[var(--accent)]">💡</span> Examples
|
|
120
|
+
</h2>
|
|
121
|
+
|
|
122
|
+
<div className="space-y-6">
|
|
123
|
+
<div className="bg-[var(--surface)] border border-[var(--border)] rounded-xl p-6">
|
|
124
|
+
<h3 className="text-lg font-semibold mb-4">Send an SMS</h3>
|
|
125
|
+
<pre className="bg-[var(--surface-elevated)] border border-[var(--border)] rounded-lg p-4 overflow-x-auto">
|
|
126
|
+
<code className="text-sm">
|
|
127
|
+
<span className="text-[var(--text-muted)]">// Find SMS providers for Sweden</span>{'\n'}
|
|
128
|
+
<span className="text-purple-600 dark:text-purple-400">discover_apis</span>({'{ '}<span className="text-sky-600 dark:text-sky-400">query</span>: <span className="text-emerald-600 dark:text-emerald-400">"send SMS Sweden"</span>{' }'}){'\n\n'}
|
|
129
|
+
<span className="text-[var(--text-muted)]">// Send via direct-call</span>{'\n'}
|
|
130
|
+
<span className="text-purple-600 dark:text-purple-400">call_api</span>({'{\n'}
|
|
131
|
+
{" "}<span className="text-sky-600 dark:text-sky-400">provider</span>: <span className="text-emerald-600 dark:text-emerald-400">"46elks"</span>,{'\n'}
|
|
132
|
+
{" "}<span className="text-sky-600 dark:text-sky-400">endpoint</span>: <span className="text-emerald-600 dark:text-emerald-400">"sms"</span>,{'\n'}
|
|
133
|
+
{" "}<span className="text-sky-600 dark:text-sky-400">params</span>: {'{\n'}
|
|
134
|
+
{" "}<span className="text-sky-600 dark:text-sky-400">to</span>: <span className="text-emerald-600 dark:text-emerald-400">"+46701234567"</span>,{'\n'}
|
|
135
|
+
{" "}<span className="text-sky-600 dark:text-sky-400">message</span>: <span className="text-emerald-600 dark:text-emerald-400">"Hello from APIClaw!"</span>{'\n'}
|
|
136
|
+
{" }"}{'\n'}
|
|
137
|
+
{'}'})
|
|
138
|
+
</code>
|
|
139
|
+
</pre>
|
|
140
|
+
</div>
|
|
141
|
+
|
|
142
|
+
<div className="bg-[var(--surface)] border border-[var(--border)] rounded-xl p-6">
|
|
143
|
+
<h3 className="text-lg font-semibold mb-4">Search the web</h3>
|
|
144
|
+
<pre className="bg-[var(--surface-elevated)] border border-[var(--border)] rounded-lg p-4 overflow-x-auto">
|
|
145
|
+
<code className="text-sm">
|
|
146
|
+
<span className="text-purple-600 dark:text-purple-400">call_api</span>({'{\n'}
|
|
147
|
+
{" "}<span className="text-sky-600 dark:text-sky-400">provider</span>: <span className="text-emerald-600 dark:text-emerald-400">"brave_search"</span>,{'\n'}
|
|
148
|
+
{" "}<span className="text-sky-600 dark:text-sky-400">endpoint</span>: <span className="text-emerald-600 dark:text-emerald-400">"search"</span>,{'\n'}
|
|
149
|
+
{" "}<span className="text-sky-600 dark:text-sky-400">params</span>: {'{ '}<span className="text-sky-600 dark:text-sky-400">query</span>: <span className="text-emerald-600 dark:text-emerald-400">"best MCP servers 2026"</span>{' }'}{'\n'}
|
|
150
|
+
{'}'})
|
|
151
|
+
</code>
|
|
152
|
+
</pre>
|
|
153
|
+
</div>
|
|
154
|
+
|
|
155
|
+
<div className="bg-[var(--surface)] border border-[var(--border)] rounded-xl p-6">
|
|
156
|
+
<h3 className="text-lg font-semibold mb-4">Generate speech</h3>
|
|
157
|
+
<pre className="bg-[var(--surface-elevated)] border border-[var(--border)] rounded-lg p-4 overflow-x-auto">
|
|
158
|
+
<code className="text-sm">
|
|
159
|
+
<span className="text-purple-600 dark:text-purple-400">call_api</span>({'{\n'}
|
|
160
|
+
{" "}<span className="text-sky-600 dark:text-sky-400">provider</span>: <span className="text-emerald-600 dark:text-emerald-400">"elevenlabs"</span>,{'\n'}
|
|
161
|
+
{" "}<span className="text-sky-600 dark:text-sky-400">endpoint</span>: <span className="text-emerald-600 dark:text-emerald-400">"tts"</span>,{'\n'}
|
|
162
|
+
{" "}<span className="text-sky-600 dark:text-sky-400">params</span>: {'{\n'}
|
|
163
|
+
{" "}<span className="text-sky-600 dark:text-sky-400">text</span>: <span className="text-emerald-600 dark:text-emerald-400">"Hello, I am an AI agent!"</span>,{'\n'}
|
|
164
|
+
{" "}<span className="text-sky-600 dark:text-sky-400">voice</span>: <span className="text-emerald-600 dark:text-emerald-400">"adam"</span>{'\n'}
|
|
165
|
+
{" }"}{'\n'}
|
|
166
|
+
{'}'})
|
|
167
|
+
</code>
|
|
168
|
+
</pre>
|
|
169
|
+
</div>
|
|
170
|
+
</div>
|
|
171
|
+
</section>
|
|
172
|
+
|
|
173
|
+
{/* For Providers */}
|
|
174
|
+
<section className="mb-16">
|
|
175
|
+
|
|
115
176
|
{/* Tools Reference */}
|
|
116
177
|
<section className="mb-16">
|
|
117
178
|
<h2 className="text-2xl font-bold mb-6 flex items-center gap-3">
|
|
@@ -143,10 +204,10 @@ export default function DocsPage() {
|
|
|
143
204
|
<div className="mt-4 text-sm text-[var(--text-muted)]">
|
|
144
205
|
<strong className="text-[var(--text-primary)]">Parameters:</strong>
|
|
145
206
|
<ul className="list-disc list-inside mt-2 space-y-1">
|
|
146
|
-
<li><code className="text-[var(--accent)]">query</code>
|
|
147
|
-
<li><code className="text-[var(--accent)]">category</code>
|
|
148
|
-
<li><code className="text-[var(--accent)]">max_results</code>
|
|
149
|
-
<li><code className="text-[var(--accent)]">region</code>
|
|
207
|
+
<li><code className="text-[var(--accent)]">query</code> - Natural language description</li>
|
|
208
|
+
<li><code className="text-[var(--accent)]">category</code> - Filter: communication, search, ai</li>
|
|
209
|
+
<li><code className="text-[var(--accent)]">max_results</code> - Number of results (default: 5)</li>
|
|
210
|
+
<li><code className="text-[var(--accent)]">region</code> - Filter by region (e.g., "sweden")</li>
|
|
150
211
|
</ul>
|
|
151
212
|
</div>
|
|
152
213
|
</div>
|
|
@@ -167,19 +228,19 @@ export default function DocsPage() {
|
|
|
167
228
|
{/* get_connected_providers */}
|
|
168
229
|
<div className="bg-[var(--surface)] border border-[var(--border)] rounded-xl p-6">
|
|
169
230
|
<h3 className="text-lg font-mono text-[var(--accent)] mb-2">get_connected_providers</h3>
|
|
170
|
-
<p className="text-[var(--text-secondary)] mb-4">List all
|
|
231
|
+
<p className="text-[var(--text-secondary)] mb-4">List all direct-call providers (no API key needed).</p>
|
|
171
232
|
<pre className="bg-[var(--surface-elevated)] border border-[var(--border)] rounded-lg p-4 overflow-x-auto">
|
|
172
233
|
<code className="text-sm text-[var(--text-primary)]">get_connected_providers()</code>
|
|
173
234
|
</pre>
|
|
174
235
|
<div className="mt-4 text-sm text-[var(--text-muted)]">
|
|
175
236
|
<strong className="text-[var(--text-primary)]">Currently available:</strong>
|
|
176
237
|
<ul className="list-disc list-inside mt-2 space-y-1">
|
|
177
|
-
<li><code className="text-[var(--accent)]">brave_search</code>
|
|
178
|
-
<li><code className="text-[var(--accent)]">46elks</code>
|
|
179
|
-
<li><code className="text-[var(--accent)]">twilio</code>
|
|
180
|
-
<li><code className="text-[var(--accent)]">resend</code>
|
|
181
|
-
<li><code className="text-[var(--accent)]">openrouter</code>
|
|
182
|
-
<li><code className="text-[var(--accent)]">elevenlabs</code>
|
|
238
|
+
<li><code className="text-[var(--accent)]">brave_search</code> - Web search</li>
|
|
239
|
+
<li><code className="text-[var(--accent)]">46elks</code> - SMS (Sweden)</li>
|
|
240
|
+
<li><code className="text-[var(--accent)]">twilio</code> - SMS (Global)</li>
|
|
241
|
+
<li><code className="text-[var(--accent)]">resend</code> - Email</li>
|
|
242
|
+
<li><code className="text-[var(--accent)]">openrouter</code> - LLM routing</li>
|
|
243
|
+
<li><code className="text-[var(--accent)]">elevenlabs</code> - Text-to-speech</li>
|
|
183
244
|
</ul>
|
|
184
245
|
</div>
|
|
185
246
|
</div>
|
|
@@ -187,7 +248,7 @@ export default function DocsPage() {
|
|
|
187
248
|
{/* call_api */}
|
|
188
249
|
<div className="bg-[var(--surface)] border border-[var(--border)] rounded-xl p-6">
|
|
189
250
|
<h3 className="text-lg font-mono text-[var(--accent)] mb-2">call_api</h3>
|
|
190
|
-
<p className="text-[var(--text-secondary)] mb-4">Execute an API call through an
|
|
251
|
+
<p className="text-[var(--text-secondary)] mb-4">Execute an API call through an direct-call provider.</p>
|
|
191
252
|
<pre className="bg-[var(--surface-elevated)] border border-[var(--border)] rounded-lg p-4 overflow-x-auto">
|
|
192
253
|
<code className="text-sm">
|
|
193
254
|
<span className="text-purple-600 dark:text-purple-400">call_api</span>({'{\n'}
|
|
@@ -209,66 +270,6 @@ export default function DocsPage() {
|
|
|
209
270
|
</div>
|
|
210
271
|
</div>
|
|
211
272
|
</section>
|
|
212
|
-
|
|
213
|
-
{/* Examples */}
|
|
214
|
-
<section className="mb-16">
|
|
215
|
-
<h2 className="text-2xl font-bold mb-6 flex items-center gap-3">
|
|
216
|
-
<span className="text-[var(--accent)]">💡</span> Examples
|
|
217
|
-
</h2>
|
|
218
|
-
|
|
219
|
-
<div className="space-y-6">
|
|
220
|
-
<div className="bg-[var(--surface)] border border-[var(--border)] rounded-xl p-6">
|
|
221
|
-
<h3 className="text-lg font-semibold mb-4">Send an SMS</h3>
|
|
222
|
-
<pre className="bg-[var(--surface-elevated)] border border-[var(--border)] rounded-lg p-4 overflow-x-auto">
|
|
223
|
-
<code className="text-sm">
|
|
224
|
-
<span className="text-[var(--text-muted)]">// Find SMS providers for Sweden</span>{'\n'}
|
|
225
|
-
<span className="text-purple-600 dark:text-purple-400">discover_apis</span>({'{ '}<span className="text-sky-600 dark:text-sky-400">query</span>: <span className="text-emerald-600 dark:text-emerald-400">"send SMS Sweden"</span>{' }'}){'\n\n'}
|
|
226
|
-
<span className="text-[var(--text-muted)]">// Send via instant-connect</span>{'\n'}
|
|
227
|
-
<span className="text-purple-600 dark:text-purple-400">call_api</span>({'{\n'}
|
|
228
|
-
{" "}<span className="text-sky-600 dark:text-sky-400">provider</span>: <span className="text-emerald-600 dark:text-emerald-400">"46elks"</span>,{'\n'}
|
|
229
|
-
{" "}<span className="text-sky-600 dark:text-sky-400">endpoint</span>: <span className="text-emerald-600 dark:text-emerald-400">"sms"</span>,{'\n'}
|
|
230
|
-
{" "}<span className="text-sky-600 dark:text-sky-400">params</span>: {'{\n'}
|
|
231
|
-
{" "}<span className="text-sky-600 dark:text-sky-400">to</span>: <span className="text-emerald-600 dark:text-emerald-400">"+46701234567"</span>,{'\n'}
|
|
232
|
-
{" "}<span className="text-sky-600 dark:text-sky-400">message</span>: <span className="text-emerald-600 dark:text-emerald-400">"Hello from APIClaw!"</span>{'\n'}
|
|
233
|
-
{" }"}{'\n'}
|
|
234
|
-
{'}'})
|
|
235
|
-
</code>
|
|
236
|
-
</pre>
|
|
237
|
-
</div>
|
|
238
|
-
|
|
239
|
-
<div className="bg-[var(--surface)] border border-[var(--border)] rounded-xl p-6">
|
|
240
|
-
<h3 className="text-lg font-semibold mb-4">Search the web</h3>
|
|
241
|
-
<pre className="bg-[var(--surface-elevated)] border border-[var(--border)] rounded-lg p-4 overflow-x-auto">
|
|
242
|
-
<code className="text-sm">
|
|
243
|
-
<span className="text-purple-600 dark:text-purple-400">call_api</span>({'{\n'}
|
|
244
|
-
{" "}<span className="text-sky-600 dark:text-sky-400">provider</span>: <span className="text-emerald-600 dark:text-emerald-400">"brave_search"</span>,{'\n'}
|
|
245
|
-
{" "}<span className="text-sky-600 dark:text-sky-400">endpoint</span>: <span className="text-emerald-600 dark:text-emerald-400">"search"</span>,{'\n'}
|
|
246
|
-
{" "}<span className="text-sky-600 dark:text-sky-400">params</span>: {'{ '}<span className="text-sky-600 dark:text-sky-400">query</span>: <span className="text-emerald-600 dark:text-emerald-400">"best MCP servers 2026"</span>{' }'}{'\n'}
|
|
247
|
-
{'}'})
|
|
248
|
-
</code>
|
|
249
|
-
</pre>
|
|
250
|
-
</div>
|
|
251
|
-
|
|
252
|
-
<div className="bg-[var(--surface)] border border-[var(--border)] rounded-xl p-6">
|
|
253
|
-
<h3 className="text-lg font-semibold mb-4">Generate speech</h3>
|
|
254
|
-
<pre className="bg-[var(--surface-elevated)] border border-[var(--border)] rounded-lg p-4 overflow-x-auto">
|
|
255
|
-
<code className="text-sm">
|
|
256
|
-
<span className="text-purple-600 dark:text-purple-400">call_api</span>({'{\n'}
|
|
257
|
-
{" "}<span className="text-sky-600 dark:text-sky-400">provider</span>: <span className="text-emerald-600 dark:text-emerald-400">"elevenlabs"</span>,{'\n'}
|
|
258
|
-
{" "}<span className="text-sky-600 dark:text-sky-400">endpoint</span>: <span className="text-emerald-600 dark:text-emerald-400">"tts"</span>,{'\n'}
|
|
259
|
-
{" "}<span className="text-sky-600 dark:text-sky-400">params</span>: {'{\n'}
|
|
260
|
-
{" "}<span className="text-sky-600 dark:text-sky-400">text</span>: <span className="text-emerald-600 dark:text-emerald-400">"Hello, I am an AI agent!"</span>,{'\n'}
|
|
261
|
-
{" "}<span className="text-sky-600 dark:text-sky-400">voice</span>: <span className="text-emerald-600 dark:text-emerald-400">"adam"</span>{'\n'}
|
|
262
|
-
{" }"}{'\n'}
|
|
263
|
-
{'}'})
|
|
264
|
-
</code>
|
|
265
|
-
</pre>
|
|
266
|
-
</div>
|
|
267
|
-
</div>
|
|
268
|
-
</section>
|
|
269
|
-
|
|
270
|
-
{/* For Providers */}
|
|
271
|
-
<section className="mb-16">
|
|
272
273
|
<h2 className="text-2xl font-bold mb-6 flex items-center gap-3">
|
|
273
274
|
<span className="text-[var(--accent)]">🤝</span> For API Providers
|
|
274
275
|
</h2>
|
|
@@ -278,8 +279,8 @@ export default function DocsPage() {
|
|
|
278
279
|
</p>
|
|
279
280
|
<ul className="list-disc list-inside text-[var(--text-secondary)] space-y-2 mb-6">
|
|
280
281
|
<li>Get discovered by AI agents searching for your capabilities</li>
|
|
281
|
-
<li>Direct Connect integration
|
|
282
|
-
<li>Analytics dashboard
|
|
282
|
+
<li>Direct Connect integration. Agents use your API instantly</li>
|
|
283
|
+
<li>Analytics dashboard. See how agents use your API</li>
|
|
283
284
|
<li>Revenue share on premium tiers</li>
|
|
284
285
|
</ul>
|
|
285
286
|
<Link
|
|
@@ -73,12 +73,12 @@ export default function EarnPage() {
|
|
|
73
73
|
const [email, setEmail] = useState('');
|
|
74
74
|
const [subscribed, setSubscribed] = useState(false);
|
|
75
75
|
const [totalCredits] = useState(1350); // Demo value
|
|
76
|
-
const [theme, setTheme] = useState<'light' | 'dark'>('
|
|
76
|
+
const [theme, setTheme] = useState<'light' | 'dark'>('light');
|
|
77
77
|
|
|
78
78
|
useEffect(() => {
|
|
79
79
|
const savedTheme = localStorage.getItem('apiclaw-theme') as 'light' | 'dark' | null;
|
|
80
|
-
|
|
81
|
-
const initialTheme = savedTheme ||
|
|
80
|
+
// Default to light
|
|
81
|
+
const initialTheme = savedTheme || 'light';
|
|
82
82
|
setTheme(initialTheme);
|
|
83
83
|
document.documentElement.classList.toggle('dark', initialTheme === 'dark');
|
|
84
84
|
}, []);
|
|
@@ -116,14 +116,14 @@ export default function EarnPage() {
|
|
|
116
116
|
APIClaw
|
|
117
117
|
</span>
|
|
118
118
|
</Link>
|
|
119
|
-
<nav className="flex items-center gap-6">
|
|
120
|
-
<Link href="/" className="text-[var(--text-secondary)] hover:text-[var(--accent)] transition-colors">
|
|
119
|
+
<nav className="flex items-center gap-4 md:gap-6">
|
|
120
|
+
<Link href="/" className="hidden sm:block text-[var(--text-secondary)] hover:text-[var(--accent)] transition-colors text-sm md:text-base">
|
|
121
121
|
Home
|
|
122
122
|
</Link>
|
|
123
|
-
<Link href="/docs" className="text-[var(--text-secondary)] hover:text-[var(--accent)] transition-colors">
|
|
123
|
+
<Link href="/docs" className="text-[var(--text-secondary)] hover:text-[var(--accent)] transition-colors text-sm md:text-base">
|
|
124
124
|
Docs
|
|
125
125
|
</Link>
|
|
126
|
-
<Link href="/providers" className="text-[var(--text-secondary)] hover:text-[var(--accent)] transition-colors">
|
|
126
|
+
<Link href="/providers" className="hidden md:block text-[var(--text-secondary)] hover:text-[var(--accent)] transition-colors text-sm md:text-base">
|
|
127
127
|
Providers
|
|
128
128
|
</Link>
|
|
129
129
|
<button
|
|
@@ -278,7 +278,7 @@ export default function EarnPage() {
|
|
|
278
278
|
</div>
|
|
279
279
|
<h3 className="font-semibold mb-2">Use</h3>
|
|
280
280
|
<p className="text-[var(--text-secondary)] text-sm">
|
|
281
|
-
Spend credits on API calls
|
|
281
|
+
Spend credits on API calls: SMS, search, AI, and more
|
|
282
282
|
</p>
|
|
283
283
|
</div>
|
|
284
284
|
<div className="text-center">
|
package/landing/src/app/page.tsx
CHANGED
|
@@ -29,7 +29,7 @@ const howItWorks = [
|
|
|
29
29
|
{
|
|
30
30
|
step: "1",
|
|
31
31
|
title: "Agent Asks",
|
|
32
|
-
description: "Your agent queries APIClaw for a capability
|
|
32
|
+
description: "Your agent queries APIClaw for a capability. Not a product name.",
|
|
33
33
|
icon: Search,
|
|
34
34
|
codeJsx: (
|
|
35
35
|
<>
|
|
@@ -63,7 +63,7 @@ const howItWorks = [
|
|
|
63
63
|
{
|
|
64
64
|
step: "3",
|
|
65
65
|
title: "Agent Integrates",
|
|
66
|
-
description: "Full specs, auth details, endpoints
|
|
66
|
+
description: "Full specs, auth details, endpoints. Everything to start building.",
|
|
67
67
|
icon: Rocket,
|
|
68
68
|
codeJsx: (
|
|
69
69
|
<>
|
|
@@ -92,7 +92,7 @@ const agentBenefits = [
|
|
|
92
92
|
{
|
|
93
93
|
icon: Database,
|
|
94
94
|
title: "Structured Data",
|
|
95
|
-
description: "JSON responses with pricing, limits, regions, auth
|
|
95
|
+
description: "JSON responses with pricing, limits, regions, auth. Everything an agent needs.",
|
|
96
96
|
},
|
|
97
97
|
{
|
|
98
98
|
icon: Shield,
|
|
@@ -137,12 +137,25 @@ const terminalLines = [
|
|
|
137
137
|
{ type: "accent", text: "→ Add to Claude Desktop: Settings → MCP → Add Server", delay: 0 },
|
|
138
138
|
];
|
|
139
139
|
|
|
140
|
+
const directCallProviders = [
|
|
141
|
+
{ name: "46elks", desc: "SMS (Sweden)" },
|
|
142
|
+
{ name: "Twilio", desc: "SMS (Global)" },
|
|
143
|
+
{ name: "Resend", desc: "Email" },
|
|
144
|
+
{ name: "Brave Search", desc: "Web search" },
|
|
145
|
+
{ name: "OpenRouter", desc: "100+ LLMs" },
|
|
146
|
+
{ name: "ElevenLabs", desc: "Text-to-speech" },
|
|
147
|
+
{ name: "Firecrawl", desc: "Web scraping" },
|
|
148
|
+
{ name: "GitHub", desc: "Repos & Issues" },
|
|
149
|
+
{ name: "Replicate", desc: "1000s of ML models" },
|
|
150
|
+
];
|
|
151
|
+
|
|
140
152
|
export default function Home() {
|
|
141
153
|
const [isDark, setIsDark] = useState(true);
|
|
142
154
|
const [terminalOutput, setTerminalOutput] = useState<typeof terminalLines>([]);
|
|
143
155
|
const [isTyping, setIsTyping] = useState(true);
|
|
144
156
|
const [currentLineIndex, setCurrentLineIndex] = useState(0);
|
|
145
157
|
const [activeSection, setActiveSection] = useState<string>("");
|
|
158
|
+
const [showProvidersModal, setShowProvidersModal] = useState(false);
|
|
146
159
|
const terminalRef = useRef<HTMLDivElement>(null);
|
|
147
160
|
|
|
148
161
|
// Scroll-based active section detection using Intersection Observer
|
|
@@ -289,8 +302,16 @@ export default function Home() {
|
|
|
289
302
|
<div className="grid lg:grid-cols-2 gap-12 lg:gap-16 items-center">
|
|
290
303
|
{/* Left: Copy */}
|
|
291
304
|
<div className="text-center lg:text-left">
|
|
292
|
-
<div className="
|
|
293
|
-
<
|
|
305
|
+
<div className="flex flex-wrap items-center justify-center lg:justify-start gap-3 mb-6">
|
|
306
|
+
<div className="badge badge-live inline-flex">
|
|
307
|
+
<span className="flex items-center gap-2"><span className="w-2 h-2 bg-green-500 rounded-full animate-pulse" />Live • {statsData.apiCount.toLocaleString()} APIs</span>
|
|
308
|
+
</div>
|
|
309
|
+
<button
|
|
310
|
+
onClick={() => setShowProvidersModal(true)}
|
|
311
|
+
className="badge inline-flex bg-accent/10 border-accent/30 text-accent hover:bg-accent/20 transition-colors cursor-pointer"
|
|
312
|
+
>
|
|
313
|
+
<span className="flex items-center gap-2"><Zap className="w-3 h-3" />Direct Call: SMS, Email, Search, AI & more</span>
|
|
314
|
+
</button>
|
|
294
315
|
</div>
|
|
295
316
|
|
|
296
317
|
<h1 className="text-5xl md:text-6xl lg:text-7xl font-black mb-6 leading-[1.05] tracking-tighter">
|
|
@@ -321,15 +342,19 @@ export default function Home() {
|
|
|
321
342
|
<span className="text-xs opacity-70">copy</span>
|
|
322
343
|
</button>
|
|
323
344
|
<a
|
|
324
|
-
href="
|
|
325
|
-
target="_blank"
|
|
326
|
-
rel="noopener noreferrer"
|
|
345
|
+
href="/docs"
|
|
327
346
|
className="btn-secondary"
|
|
328
347
|
>
|
|
329
|
-
|
|
330
|
-
|
|
348
|
+
Get Started
|
|
349
|
+
<ArrowRight className="w-5 h-5" />
|
|
331
350
|
</a>
|
|
332
351
|
</div>
|
|
352
|
+
|
|
353
|
+
{/* Social proof */}
|
|
354
|
+
<p className="text-sm text-text-muted mt-4 flex items-center gap-2">
|
|
355
|
+
<Users className="w-4 h-4" />
|
|
356
|
+
<span>The API layer agent builders are switching to</span>
|
|
357
|
+
</p>
|
|
333
358
|
|
|
334
359
|
</div>
|
|
335
360
|
|
|
@@ -340,7 +365,7 @@ export default function Home() {
|
|
|
340
365
|
<div className="terminal-dot terminal-dot-red" />
|
|
341
366
|
<div className="terminal-dot terminal-dot-yellow" />
|
|
342
367
|
<div className="terminal-dot terminal-dot-green" />
|
|
343
|
-
<span className="terminal-title">apiclaw
|
|
368
|
+
<span className="terminal-title">apiclaw</span>
|
|
344
369
|
</div>
|
|
345
370
|
<div className="terminal-body">
|
|
346
371
|
{terminalOutput.map((line, i) => (
|
|
@@ -392,6 +417,118 @@ export default function Home() {
|
|
|
392
417
|
</div>
|
|
393
418
|
</section>
|
|
394
419
|
|
|
420
|
+
{/* Before/After */}
|
|
421
|
+
<section className="py-12 px-6">
|
|
422
|
+
<div className="max-w-4xl mx-auto">
|
|
423
|
+
<div className="grid md:grid-cols-2 gap-8">
|
|
424
|
+
<div className="p-6 rounded-xl border border-red-500/20 bg-red-500/5">
|
|
425
|
+
<div className="flex items-center gap-2 text-red-400 font-medium mb-4">
|
|
426
|
+
<span className="text-xl">😤</span> Without APIClaw
|
|
427
|
+
</div>
|
|
428
|
+
<ul className="space-y-3 text-text-secondary">
|
|
429
|
+
<li className="flex items-start gap-2">
|
|
430
|
+
<span className="text-red-400 mt-1">✗</span>
|
|
431
|
+
<span>3+ hours searching for the right API</span>
|
|
432
|
+
</li>
|
|
433
|
+
<li className="flex items-start gap-2">
|
|
434
|
+
<span className="text-red-400 mt-1">✗</span>
|
|
435
|
+
<span>Create accounts, manage API keys</span>
|
|
436
|
+
</li>
|
|
437
|
+
<li className="flex items-start gap-2">
|
|
438
|
+
<span className="text-red-400 mt-1">✗</span>
|
|
439
|
+
<span>Read docs, figure out auth, test endpoints</span>
|
|
440
|
+
</li>
|
|
441
|
+
<li className="flex items-start gap-2">
|
|
442
|
+
<span className="text-red-400 mt-1">✗</span>
|
|
443
|
+
<span>Your agent waits... and waits...</span>
|
|
444
|
+
</li>
|
|
445
|
+
</ul>
|
|
446
|
+
</div>
|
|
447
|
+
<div className="p-6 rounded-xl border border-green-500/20 bg-green-500/5">
|
|
448
|
+
<div className="flex items-center gap-2 text-green-400 font-medium mb-4">
|
|
449
|
+
<span className="text-xl">🦞</span> With APIClaw
|
|
450
|
+
</div>
|
|
451
|
+
<ul className="space-y-3 text-text-secondary">
|
|
452
|
+
<li className="flex items-start gap-2">
|
|
453
|
+
<span className="text-green-400 mt-1">✓</span>
|
|
454
|
+
<span><strong>∞ hours saved</strong> per integration</span>
|
|
455
|
+
</li>
|
|
456
|
+
<li className="flex items-start gap-2">
|
|
457
|
+
<span className="text-green-400 mt-1">✓</span>
|
|
458
|
+
<span>No accounts, no API keys needed</span>
|
|
459
|
+
</li>
|
|
460
|
+
<li className="flex items-start gap-2">
|
|
461
|
+
<span className="text-green-400 mt-1">✓</span>
|
|
462
|
+
<span>Direct Call: SMS, Email, AI, and more</span>
|
|
463
|
+
</li>
|
|
464
|
+
<li className="flex items-start gap-2">
|
|
465
|
+
<span className="text-green-400 mt-1">✓</span>
|
|
466
|
+
<span>Your agent ships. Today.</span>
|
|
467
|
+
</li>
|
|
468
|
+
</ul>
|
|
469
|
+
</div>
|
|
470
|
+
</div>
|
|
471
|
+
<p className="text-center text-sm text-text-muted mt-8">
|
|
472
|
+
<Rocket className="w-4 h-4 inline mr-1" />
|
|
473
|
+
New Direct Call providers added weekly
|
|
474
|
+
</p>
|
|
475
|
+
</div>
|
|
476
|
+
</section>
|
|
477
|
+
|
|
478
|
+
{/* Quick Start */}
|
|
479
|
+
<section className="py-16 px-6 bg-surface/50">
|
|
480
|
+
<div className="max-w-3xl mx-auto">
|
|
481
|
+
<div className="text-center mb-8">
|
|
482
|
+
<h2 className="text-2xl md:text-3xl font-bold flex items-center justify-center gap-3">
|
|
483
|
+
<Zap className="w-6 h-6 text-accent" />
|
|
484
|
+
Quick Start
|
|
485
|
+
</h2>
|
|
486
|
+
<p className="text-text-secondary mt-2">Get running in 30 seconds</p>
|
|
487
|
+
</div>
|
|
488
|
+
|
|
489
|
+
<div className="grid md:grid-cols-2 gap-6">
|
|
490
|
+
{/* Install */}
|
|
491
|
+
<div className="code-preview">
|
|
492
|
+
<div className="code-preview-header">
|
|
493
|
+
terminal
|
|
494
|
+
</div>
|
|
495
|
+
<div className="code-preview-body">
|
|
496
|
+
<pre className="text-sm whitespace-pre-wrap">
|
|
497
|
+
<span className="text-gray-500"># Run directly with npx</span>{"\n"}
|
|
498
|
+
<span className="text-green-400">$</span> <span className="text-blue-400">npx</span> @nordsym/apiclaw{"\n\n"}
|
|
499
|
+
<span className="text-gray-500"># Or install globally</span>{"\n"}
|
|
500
|
+
<span className="text-green-400">$</span> <span className="text-blue-400">npm</span> install -g @nordsym/apiclaw{"\n"}
|
|
501
|
+
<span className="text-green-400">$</span> apiclaw
|
|
502
|
+
</pre>
|
|
503
|
+
</div>
|
|
504
|
+
</div>
|
|
505
|
+
|
|
506
|
+
{/* MCP Config */}
|
|
507
|
+
<div className="code-preview">
|
|
508
|
+
<div className="code-preview-header">
|
|
509
|
+
claude_desktop_config.json
|
|
510
|
+
</div>
|
|
511
|
+
<div className="code-preview-body">
|
|
512
|
+
<pre className="text-sm whitespace-pre-wrap">
|
|
513
|
+
<span className="text-gray-500">{"{"}</span>{"\n"}
|
|
514
|
+
{" "}<span className="text-red-400">"mcpServers"</span>: <span className="text-gray-500">{"{"}</span>{"\n"}
|
|
515
|
+
{" "}<span className="text-red-400">"apiclaw"</span>: <span className="text-gray-500">{"{"}</span>{"\n"}
|
|
516
|
+
{" "}<span className="text-red-400">"command"</span>: <span className="text-green-400">"npx"</span>,{"\n"}
|
|
517
|
+
{" "}<span className="text-red-400">"args"</span>: [<span className="text-green-400">"@nordsym/apiclaw"</span>]{"\n"}
|
|
518
|
+
{" "}<span className="text-gray-500">{"}"}</span>{"\n"}
|
|
519
|
+
{" "}<span className="text-gray-500">{"}"}</span>{"\n"}
|
|
520
|
+
<span className="text-gray-500">{"}"}</span>
|
|
521
|
+
</pre>
|
|
522
|
+
</div>
|
|
523
|
+
</div>
|
|
524
|
+
</div>
|
|
525
|
+
|
|
526
|
+
<p className="text-center text-sm text-text-muted mt-6">
|
|
527
|
+
Works with Claude Desktop, Cursor, and any MCP-compatible client
|
|
528
|
+
</p>
|
|
529
|
+
</div>
|
|
530
|
+
</section>
|
|
531
|
+
|
|
395
532
|
<div className="divider" />
|
|
396
533
|
|
|
397
534
|
{/* How It Works */}
|
|
@@ -482,7 +619,7 @@ export default function Home() {
|
|
|
482
619
|
|
|
483
620
|
<div className="code-preview">
|
|
484
621
|
<div className="code-preview-header">
|
|
485
|
-
agent.ts
|
|
622
|
+
agent.ts
|
|
486
623
|
</div>
|
|
487
624
|
<div className="code-preview-body">
|
|
488
625
|
<pre className="text-sm">
|
|
@@ -579,7 +716,7 @@ export default function Home() {
|
|
|
579
716
|
</h2>
|
|
580
717
|
|
|
581
718
|
<p className="text-text-secondary text-lg mb-8 leading-relaxed">
|
|
582
|
-
AI agents are the new developers. They don't browse landing pages
|
|
719
|
+
AI agents are the new developers. They don't browse landing pages.
|
|
583
720
|
they query capabilities. Get your API in front of them.
|
|
584
721
|
</p>
|
|
585
722
|
|
|
@@ -661,9 +798,10 @@ export default function Home() {
|
|
|
661
798
|
</div>
|
|
662
799
|
<h3 className="text-2xl font-bold mb-2">Provisioning</h3>
|
|
663
800
|
<p className="text-text-secondary mb-6">Agent-native credential management</p>
|
|
664
|
-
<div className="text-
|
|
665
|
-
|
|
801
|
+
<div className="text-3xl font-bold mb-2 text-text-muted">
|
|
802
|
+
Free Beta
|
|
666
803
|
</div>
|
|
804
|
+
<p className="text-sm text-text-muted mb-4">Early adopters get extended free access</p>
|
|
667
805
|
<ul className="space-y-4 mb-8">
|
|
668
806
|
<li className="flex items-center gap-3 text-text-muted">
|
|
669
807
|
<Check className="w-5 h-5 flex-shrink-0" />
|
|
@@ -828,6 +966,61 @@ export default function Home() {
|
|
|
828
966
|
<span className="text-text-primary font-medium">Talk to the Clawdbot building this</span>
|
|
829
967
|
</div>
|
|
830
968
|
</a>
|
|
969
|
+
|
|
970
|
+
{/* Direct Call Providers Modal */}
|
|
971
|
+
{showProvidersModal && (
|
|
972
|
+
<div
|
|
973
|
+
className="fixed inset-0 z-[100] flex items-center justify-center p-4 bg-black/60 backdrop-blur-sm"
|
|
974
|
+
onClick={() => setShowProvidersModal(false)}
|
|
975
|
+
>
|
|
976
|
+
<div
|
|
977
|
+
className="bg-background border border-border rounded-2xl shadow-2xl max-w-md w-full max-h-[80vh] overflow-hidden"
|
|
978
|
+
onClick={(e) => e.stopPropagation()}
|
|
979
|
+
>
|
|
980
|
+
<div className="p-6 border-b border-border">
|
|
981
|
+
<div className="flex items-center justify-between">
|
|
982
|
+
<h3 className="text-xl font-bold flex items-center gap-2">
|
|
983
|
+
<Zap className="w-5 h-5 text-accent" />
|
|
984
|
+
Direct Call Providers
|
|
985
|
+
</h3>
|
|
986
|
+
<button
|
|
987
|
+
onClick={() => setShowProvidersModal(false)}
|
|
988
|
+
className="p-2 hover:bg-surface rounded-lg transition-colors"
|
|
989
|
+
>
|
|
990
|
+
<span className="text-xl">×</span>
|
|
991
|
+
</button>
|
|
992
|
+
</div>
|
|
993
|
+
<p className="text-sm text-text-muted mt-1">No API keys needed. Call directly through APIClaw.</p>
|
|
994
|
+
</div>
|
|
995
|
+
|
|
996
|
+
<div className="p-4 max-h-[40vh] overflow-y-auto">
|
|
997
|
+
<div className="grid grid-cols-2 gap-3">
|
|
998
|
+
{directCallProviders.map((provider, i) => (
|
|
999
|
+
<div key={i} className="p-3 rounded-xl bg-surface border border-border">
|
|
1000
|
+
<div className="font-medium text-sm">{provider.name}</div>
|
|
1001
|
+
<div className="text-xs text-text-muted">{provider.desc}</div>
|
|
1002
|
+
</div>
|
|
1003
|
+
))}
|
|
1004
|
+
</div>
|
|
1005
|
+
</div>
|
|
1006
|
+
|
|
1007
|
+
<div className="p-6 border-t border-border bg-surface/50">
|
|
1008
|
+
<p className="text-sm text-text-secondary mb-4 text-center">
|
|
1009
|
+
Want your API here? Get discovered by thousands of AI agents.
|
|
1010
|
+
</p>
|
|
1011
|
+
<a
|
|
1012
|
+
href="https://nordsym.github.io/NordSym-Scheduler/"
|
|
1013
|
+
target="_blank"
|
|
1014
|
+
rel="noopener noreferrer"
|
|
1015
|
+
className="btn-primary w-full justify-center"
|
|
1016
|
+
>
|
|
1017
|
+
<span>Book a Call</span>
|
|
1018
|
+
<ArrowRight className="w-4 h-4" />
|
|
1019
|
+
</a>
|
|
1020
|
+
</div>
|
|
1021
|
+
</div>
|
|
1022
|
+
</div>
|
|
1023
|
+
)}
|
|
831
1024
|
</main>
|
|
832
1025
|
);
|
|
833
1026
|
}
|