Val Town Code SearchReturn to Val Town

API Access

You can access search results via JSON API by adding format=json to your query:

https://codesearch.val.run/image-url.jpg%20%22Image%20title%22?q=api&page=88&format=json

For typeahead suggestions, use the /typeahead endpoint:

https://codesearch.val.run/typeahead?q=api

Returns an array of strings in format "username" or "username/projectName"

Found 25397 results for "api"(3720ms)

glimpse2-runbook-test07-save.md14 matches

@lightweightUpdated 1 week ago
10 Before implementing, identify which pattern to use:
11
12- Data API Pattern (/api/_, /views/_): Controllers return data objects, routes handle HTTP
13- Webhook Handler Pattern (/tasks/\*): Controllers handle HTTP requests/responses directly
14
27
28- Controller function (handles HTTP directly)
29- Service function (if new Notion API calls needed)
30- Route definition
31- Documentation updates
35### Step 1: Extend the Service Layer (if needed)
36
37If new external API calls are required:
38
391. **Location:** /backend/services/notion.service.ts
401. **Pattern:** Add pure API functions that return {success, data/error, timestamp} format
411. **Example:** updatePageUrl(pageId, url) function
421. **Responsibilities:** Only handle external API calls, no business logic
43
44### Step 2: Create the Controller
68
69- Add endpoint to "Webhooks (Notion Integration)" section
70- Follow format: `POST /tasks/url` - Description (requires `X-API-KEY` header)
71
72**Route README** `(/backend/routes/tasks/README.md)`:
91
92- All `/tasks/*` routes automatically use webhook authentication
93- Requires X-API-KEY header with NOTION_WEBHOOK_SECRET value
94- No additional auth setup needed in route
95
1691. Test with missing page ID (expect 400)
1701. Test with missing host header (expect 400)
1711. Test with Notion API failures (expect 500)
172
173### Add Test Endpoint (optional)
174
175Create a test endpoint that simulates the logic without calling external APIs:
176
177```
178app.post("/test-url", async (c) => {
179 // Same logic but return test response instead of calling Notion API
180});
181```
183## Common Pitfalls to Avoid
184
1851. Don't mix patterns: /tasks/\_ routes should use webhook handler pattern, not data API pattern
1861. Don't forget authentication: All /tasks/\_ routes are automatically protected
1871. Don't skip logging: Webhook endpoints need comprehensive logging for debugging
1881. Don't forget documentation: Update all relevant README files
1891. Don't hardcode hosts: Always extract host from request headers
1901. Don't forget error cases: Handle missing data, API failures, etc.
1911. Don't skip the catch-all update: Add new endpoints to available endpoints list
192
211- The webhook authentication middleware handles all security automatically
212- Focus on business logic and proper HTTP handling in the controller
213- Keep service functions pure (no business logic, just API calls)
214- Document the architectural decision when mixing patterns
215- Test thoroughly but remember authentication will block test requests without proper keys
231 1. Copy the webhook URL and paste it into the `URL` field
232 1. Click the `custom header` link under the URL field
233 1. For the key add `X-API-KEY` and for the value add the `NOTION_WEBHOOK_SECRET` environment variable from `vars.env` file
234 1. Save the automation
235 1. Click the `Save URL` button

glimpse2-runbook-test04-view.md11 matches

@lightweightUpdated 1 week ago
140- Single Responsibility: Controller handles HTTP concerns + minimal data cleanup
141- Thin Layer: Minimal processing, focused on improving data consumption
142- Useful Filtering: Remove UI elements that don't belong in data APIs
143- Consistent Error Handling: Standard error response format
144
145✅ Service Layer:
146
147- Data Access: Handle all Notion API interactions
148- Consistent Response Format: Always return {success, data/error, timestamp}
149- Raw Data: Return unfiltered data from external APIs
150
151✅ Separation of Concerns:
152
153- Controller: HTTP validation, routing, error responses, basic data cleanup
154- Service: External API calls, data retrieval
155- Client: Complex data processing, extraction, formatting
156
193 }
194
195### 11b. Add Demo API Endpoints Section to Dashboard HTML
196
197Add this section after the webhook section closes, before the main content div
199
200 <div class="webhook-section">
201 <h3>🔍 Demo API Endpoints</h3>
202
203 ${demoDatabaseId ? `
246- Controller Logic: Keep minimal but include useful data cleanup
247- Property Filtering: Remove UI-specific elements (buttons) that don't belong in
248 data APIs
249- Error Handling: Consistent service response pattern
250
264## 13\. Benefits of This Approach
265
266- Clean Data: Removes UI clutter from data API responses
267- Maintainable: Clear separation between layers with focused responsibilities
268- Flexible: Client can still extract any business data from Notion response
301
3021. Briefly summarize the work that was just completed and why it's important
3032. Provide the URL to the dashboard where users can see the live demo API
304 endpoint links. Tell the user that they can copy and paste that URL into a
305 new tab to see it live.
310
311- Users get real Notion page IDs for testing (not fake `/test-id`)
312- One-click access to live API responses from the dashboard
313- Self-documenting API with automatically updated demo links
314- Proper architectural separation maintained
315
7Place authentication middleware in the following order:
8
91. **Notion webhook auth middleware** (X-API-KEY for `/tasks/*`)
102. **Global user auth middleware** (for other protected routes)
113. **Route handlers**
21
22- Create `/backend/routes/webhookAuthCheck.ts`
23- Extract X-API-KEY header from incoming requests
24- Compare against NOTION_WEBHOOK_SECRET environment variable
25- Use constant-time comparison to prevent timing attacks
54
55// 2. User auth - for ALL routes EXCEPT /tasks/*
56app.use("/api/*", authCheck);
57app.use("/views/*", authCheck);
58app.use("/", authCheck);
77
78```
79app.use("/api/*", authCheck); // Applied to API routes
80app.use("/views/*", authCheck); // Applied to view routes
81app.use("/", authCheck); // Applied to root route
84**This ensures:**
85
86✅ `/` (root) still requires user authentication ✅ `/api/*` routes still
87require user authentication ✅ `/views/*` routes still require user
88authentication ✅ `/tasks/*` routes only use webhook authentication (no user
94### Flow Logic
95
96- Request to /tasks/\* → Check X-API-KEY → If valid, proceed to route handler
97 (skip global auth)
98- Request to /tasks/\* → Check X-API-KEY → If invalid, return 401 (never reaches
99 global auth)
100- Request to other routes → Skip webhook auth → Go to global auth → Then route
1111. **Test with wrong key** (should fail):
112
113POST /tasks/test Headers: {"X-API-KEY": "wrong-key"} Expected: 403
114"Authentication failed"
115
117
118POST /tasks/test\
119Headers: {"X-API-KEY": "your-configured-secret-value"} Expected: 200 (reaches
120your route handler)
121
188Test with:
189
190POST /tasks/notion-webhook Headers: {"X-API-KEY":
191"your-configured-secret-value"} Body: {"test": "data"} Expected: 200 {"success":
192true}
269 cursor: not-allowed;
270 }
271 .api-key-input {
272 padding: 6px 10px;
273 border: 1px solid #ced4da;
307 <p><strong>To test:</strong> Get the <code>NOTION_WEBHOOK_SECRET</code> value from your <code>vars.env</code> file (provided by your administrator)</p>
308 <form class="test-controls" onsubmit="testWebhook(event)">
309 <input type="text" class="api-key-input" id="customApiKey" placeholder="Enter webhook secret" required>
310 <button type="submit" class="test-btn">Test Webhook</button>
311 </form>
324
325 const resultDiv = document.getElementById('testResult');
326 const customKeyInput = document.getElementById('customApiKey');
327
328 // Clear previous result
338 }
339
340 const headers = { 'X-API-KEY': customKey };
341
342 const response = await fetch('/tasks/test', {
378Make sure these are true:
379
380- Webhook endpoints only accessible with correct X-API-KEY
381- User authentication preserved for non-webhook routes
382- Dashboard provides clean, simplified webhook testing interface
397
398- /tasks/\* → Webhook auth required (Notion POSTs)
399- /api/\* → User auth required (if applicable)
400- /\* → Public routes (static files, etc.)
401

glimpse2-runbook-test02-auth.md5 matches

@lightweightUpdated 1 week ago
64- `import dashboardRoute from "./backend/routes/views/dashboard.tsx";`
65- **Mount in main.tsx**: `app.get("/", dashboardRoute)`
66- **Note**: Dashboard is placed in `/routes/views/` because it's a user-facing view, not an API endpoint
67
68This approach:
70- Keeps `main.tsx` focused on app setup and middleware
71- Makes the dashboard logic easier to maintain and test
72- Follows the modular architecture pattern with views separated from API routes
73- Places user-facing interfaces in `/routes/views/` for better organization
74- Allows for easier dashboard enhancements without touching core routing
77
78- Display user information (email from `c.get("userEmail")`)
79- Display the `/api/health` endpoint results as raw JSON in a <pre> tag; e.g., JSON.stringify(data, null, 2)
80- Include logout functionality via `/auth/logout`
81- Show a simple and professional welcome interface with minimal styling
106- Add a `PUBLIC_ROUTES` array at the top for routes that should be accessible without authentication
107- **Don't include `/auth/logout`** in the whitelist (LastLogin handles it before your middleware runs)
108- Use for truly public routes like: `/demo/:id`, `/api/health`, static assets, etc.
109
110If you encounter problems loading the React button, try this simple approach for authCheck.ts:
115 // Add public routes here as needed
116 // '/demo/:id', // Example: public demo viewing
117 // '/api/public', // Example: public API endpoints
118];
119
15**Services** (/backend/services/):
16
17- Single-purpose functions that make direct API calls to external systems
18- Pure functions that handle HTTP transport layer (response.ok)
19- Example: getDatabaseById(id), searchNotionDatabases()
43**Layer 1: HTTP Transport Layer** (response.ok)
44
45- Used when checking responses from external APIs (Notion, etc.)
46- Validates HTTP request succeeded (status 200-299)
47- Handles network failures, auth issues, server errors
62- /backend - directory for backend code
63 - /routes - HTTP route handlers organized by functionality
64 - /api - JSON API endpoints for frontend/backend communication
65 - /tasks - Webhook handlers for Notion integrations
66 - /views - Server-side rendered views for frontend
67 - /services - External API integrations (pure API calls only)
68 - /controllers - Business logic coordination between routes and services
69 - /crons - Scheduled task handlers
90
91// Import route modules
92import apiRoutes from "./backend/routes/api/\_api.routes.ts";
93import taskRoutes from "./backend/routes/tasks/\_tasks.routes.ts";
94import viewRoutes from "./backend/routes/views/\_views.routes.ts";
102
103// Mount route modules
104app.route("/api", apiRoutes);
105app.route("/tasks", taskRoutes);
106app.route("/views", viewRoutes);
128---
129
130### Step 3: Create Service Layer (API Calls Only)
131
132Create /backend/services/notion.service.ts with ONLY direct Notion API calls:
133
134**Notion Service Requirements:**
135
136- Import Notion: `import { Client } from "npm:@notionhq/client";`
137- Initialize: `const notion = new Client({ auth: Deno.env.get("NOTION_API_KEY") });`
138- Create these functions (API calls only, no business logic):
139 - `getDatabases()` - search for all databases
140 - `getDatabaseById(databaseId: string)` - retrieve specific database
185
186- `getConfiguredDatabases()` - Check all configured databases using environment variables
187- `getHealthStatus()` - Generate formatted health response for API
188
189**Controller Function Pattern:**
230**Add Health Endpoint**
231
232In /backend/routes/api/\_api.routes.ts:
233
234```
267Before proceeding, verify your implementation follows the architecture:
268
269- Services only make direct API calls (no environment variables, no orchestration)
270- Controllers handle business logic and coordinate services
271- Routes only handle HTTP concerns and call controllers

glimpse2-runbook-test00-setup.md4 matches

@lightweightUpdated 1 week ago
33The most important thing to understand about them is that they are required to connect val.town to Notion, and to connect this Val's code to the Notion databases that hold the demo content.
34
35- `NOTION_API_KEY` - Your Notion integration API key
36- `NOTION_WEBHOOK_SECRET` - Matches the X-API-KEY custom header coming from Notion webhooks to /tasks/\* endpoint(s)
37- `GLANCE_DEMOS_DB_ID` - Your Notion database ID for demos, which are personalized to prospects and have unique URLs
38- `GLANCE_CONTENT_DB_ID` - Your Notion database ID for demo page content, which are compiled into demos
1791. In Notion, add a button to the Glimpse Demos database
1801. Edit the automation on that button: add the URL fromj step 1 and then append `/tasks/notion-webhook` to it
1811. Click the 'custom header' link under the webhook URL field and add this key and value: **Key**: `X-API-KEY`, **Value**: `<x-api-key value>`. (Find the value in the `NOTION_WEBHOOK_SECRET` key in `vars.env`)
1821. Click the save button
1831. Click the automation button in the Notion database row
2021. In Notion, add a button to a database row in the Glimpse Demos database called "Staging: set URL"
2031. Edit the automation on that button to be a webhook that hits `https://<branch subdomain url>/tasks/url`
2041. Add the custom header for webhook auth: **Key**: `X-API-KEY` and **Value**: `<custom header value>`. (Find the value in the `NOTION_WEBHOOK_SECRET` key in `vars.env`)
2051. Save the button automation
2061. Click the button in Notion

untitled-1993main.tsx14 matches

@n4k0m3Updated 1 week ago
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <title>Probador de API de Grist</title>
8 <script src="https://cdn.tailwindcss.com"></script>
9 <style>
32 <div class="max-w-4xl mx-auto bg-white p-8 rounded-xl shadow-lg">
33 <h1 class="text-3xl font-bold text-center mb-6 text-gray-800">
34 Probador de API de Grist
35 </h1>
36 <p class="text-center text-gray-600 mb-8">
37 Una herramienta para explorar y probar los endpoints de la API de Grist.
38 </p>
39
40 <div class="mb-6 space-y-4">
41 <div class="bg-gray-100 p-4 rounded-lg flex items-center shadow-sm">
42 <label for="apiKey" class="font-medium text-gray-700 w-32">API Key:</label>
43 <input
44 type="text"
45 id="apiKey"
46 class="flex-1 p-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500"
47 placeholder="Ingresa tu API Key (Bearer Token)"
48 >
49 </div>
324 </div>
325
326 <script src="./api.js"></script>
327 <script>
328 const output = document.getElementById("responseOutput");
346
347 async function testMethod(methodName, ...args) {
348 const apiKey = document.getElementById("apiKey").value;
349 const docId = document.getElementById("docId").value;
350 const tableId = document.getElementById("tableId").value;
351
352 if (
353 !apiKey ||
354 (!docId && methodName.includes("Records") ||
355 !tableId && methodName.includes("Records"))
357 printToOutput({
358 error:
359 "Falta la API Key, el ID de Documento o el ID de Tabla",
360 });
361 return;
362 }
363
364 // Verificar si GristAPIClient existe
365 if (typeof GristAPIClient === 'undefined') {
366 printToOutput({
367 error: "GristAPIClient no está disponible. Asegúrate de que api.js esté cargado correctamente.",
368 });
369 return;
370 }
371
372 const client = new GristAPIClient(apiKey);
373
374 try {

untitled-1993main.tsx16 matches

@n4k0m3Updated 1 week ago
1class GristAPIClient {
2 constructor(apiKey) {
3 if (!apiKey) {
4 throw new Error("API key is required.");
5 }
6 this.apiKey = apiKey;
7 this.baseUrl = "https://docs.getgrist.com/api";
8 this.headers = {
9 "Authorization": `Bearer ${this.apiKey}`,
10 "accept": "application/json",
11 };
33 const errorText = await response.text();
34 throw new Error(
35 `API Error: ${response.status} ${response.statusText} - ${errorText}`,
36 );
37 }
242 const errorText = await response.text();
243 throw new Error(
244 `API Error: ${response.status} ${response.statusText} - ${errorText}`,
245 );
246 }
260 const errorText = await response.text();
261 throw new Error(
262 `API Error: ${response.status} ${response.statusText} - ${errorText}`,
263 );
264 }
307
308// Gestión de Organizaciones y Documentos
309const apiKey = "1ba558aa677ec970087702df8535483d418805b3";
310const grist = new GristAPIClient(apiKey);
311const orgId = "3Y96qZCVZSpaiVHdoGgasY";
312const workspaceId = 143221; // Reemplaza con tu ID de workspace
336/*
337// Peticiones de Tablas y Registros
338const apiKey = 'YOUR_API_KEY';
339const grist = new GristAPIClient(apiKey);
340const docId = '3Y96qZCVZSpaiVHdoGgasY';
341const tableId = 'Table1';
367/*
368// Peticiones de SQL y Columnas
369const apiKey = 'YOUR_API_KEY';
370const grist = new GristAPIClient(apiKey);
371const docId = '3Y96qZCVZSpaiVHdoGgasY';
372const tableId = 'Pets';
13 }
14
15 const youtubeApiKey = process.env.YOUTUBE_API_KEY;
16 const geminiApiKey = process.env.GEMINI_API_KEY;
17
18 if (!youtubeApiKey || !geminiApiKey) {
19 return new Response(
20 JSON.stringify({
21 error: "API keys not configured",
22 required: {
23 YOUTUBE_API_KEY: youtubeApiKey ? "✓ Configured" : "❌ Missing",
24 GEMINI_API_KEY: geminiApiKey ? "✓ Configured" : "❌ Missing",
25 },
26 setup: "Contact administrator to configure API keys",
27 }),
28 {
37
38 const [videoDetails, comments] = await Promise.all([
39 fetchVideoDetailsWithRetry(videoId, youtubeApiKey),
40 fetchYouTubeCommentsWithRetry(videoId, youtubeApiKey),
41 ]);
42
48 comments,
49 videoDetails,
50 geminiApiKey,
51 );
52
116// ========================================
117
118async function enhancedMultiPassAnalysis(comments, videoDetails, geminiApiKey) {
119 try {
120 console.log("🚀 Starting Enhanced Multi-Pass AI Analysis...");
123 const [teacherAnalysis, learningAnalysis, behaviorAnalysis] = await Promise
124 .all([
125 deepTeacherAnalysis(comments, videoDetails, geminiApiKey),
126 comprehensiveLearningAnalysis(comments, videoDetails, geminiApiKey),
127 studentBehaviorAnalysis(comments, videoDetails, geminiApiKey),
128 ]);
129
130 // Additional passes
131 const [contentAnalysis, predictiveAnalysis] = await Promise.all([
132 contentEffectivenessAnalysis(comments, videoDetails, geminiApiKey),
133 predictiveAnalyticsGeneration(comments, videoDetails, geminiApiKey),
134 ]);
135
156// ========================================
157
158async function deepTeacherAnalysis(comments, videoDetails, geminiApiKey) {
159 const teacherComments = comments.slice(0, 60).map((c) => ({
160 text: c.textOriginal,
229Be extremely detailed. Provide evidence for every claim.`;
230
231 return await processGeminiRequest(teacherPrompt, geminiApiKey);
232}
233
235 comments,
236 videoDetails,
237 geminiApiKey,
238) {
239 const learningComments = comments.slice(0, 50).map((c) => ({
278}`;
279
280 return await processGeminiRequest(learningPrompt, geminiApiKey);
281}
282
283async function studentBehaviorAnalysis(comments, videoDetails, geminiApiKey) {
284 const behaviorComments = comments.slice(0, 40).map((c) => ({
285 text: c.textOriginal,
326}`;
327
328 return await processGeminiRequest(behaviorPrompt, geminiApiKey);
329}
330
332 comments,
333 videoDetails,
334 geminiApiKey,
335) {
336 const contentComments = comments.slice(0, 30).map((c) => ({
360}`;
361
362 return await processGeminiRequest(contentPrompt, geminiApiKey);
363}
364
366 comments,
367 videoDetails,
368 geminiApiKey,
369) {
370 const predictiveComments = comments.slice(0, 25).map((c) => ({
392}`;
393
394 return await processGeminiRequest(predictivePrompt, geminiApiKey);
395}
396
397async function processGeminiRequest(prompt, geminiApiKey) {
398 const enhancedPrompt = `
399CONTEXT: You are analyzing educational YouTube comments with 20+ years of expertise.
418 try {
419 const response = await fetch(
420 `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-pro:generateContent?key=${geminiApiKey}`,
421 {
422 method: "POST",
454 return { error: "No valid response from AI", rawResponse: data };
455 } catch (error) {
456 console.error("Gemini API error:", error);
457 return { error: "API request failed", details: error.message };
458 }
459}
602}
603
604async function fetchYouTubeCommentsWithRetry(videoId, apiKey, maxRetries = 3) {
605 for (let attempt = 1; attempt <= maxRetries; attempt++) {
606 try {
607 return await fetchYouTubeComments(videoId, apiKey);
608 } catch (error) {
609 if (attempt === maxRetries) throw error;
613}
614
615async function fetchVideoDetailsWithRetry(videoId, apiKey, maxRetries = 3) {
616 for (let attempt = 1; attempt <= maxRetries; attempt++) {
617 try {
618 return await fetchVideoDetails(videoId, apiKey);
619 } catch (error) {
620 if (attempt === maxRetries) throw error;
624}
625
626async function fetchYouTubeComments(videoId, apiKey) {
627 const comments = [];
628 const maxCommentsLimit = 1000;
631 const timeComments = await fetchCommentsByOrder(
632 videoId,
633 apiKey,
634 "time",
635 500,
640 const relevanceComments = await fetchCommentsByOrder(
641 videoId,
642 apiKey,
643 "relevance",
644 maxCommentsLimit - comments.length,
663}
664
665async function fetchCommentsByOrder(videoId, apiKey, order, remainingLimit) {
666 const comments = [];
667 let nextPageToken = "";
674
675 const url =
676 `https://www.googleapis.com/youtube/v3/commentThreads?part=snippet,replies&videoId=${videoId}&key=${apiKey}&maxResults=100&order=${order}${
677 nextPageToken ? `&pageToken=${nextPageToken}` : ""
678 }`;
738}
739
740async function fetchVideoDetails(videoId, apiKey) {
741 const url =
742 `https://www.googleapis.com/youtube/v3/videos?part=snippet,statistics&id=${videoId}&key=${apiKey}`;
743 const response = await fetch(url);
744 const data = await response.json();
745
746 if (data.error) throw new Error(`YouTube API Error: ${data.error.message}`);
747 if (!data.items || data.items.length === 0) {
748 throw new Error("Video not found");
1522
1523function generateQuotaErrorHTML() {
1524 return `<!DOCTYPE html><html><body><h2>API Quota Exceeded</h2><p>Please try again later.</p></body></html>`;
1525}

R2-Backup-SystemREADME.md5 matches

@toowiredUpdated 1 week ago
11## Hono
12
13This app uses [Hono](https://hono.dev/) as the API framework. You can think of
14Hono as a replacement for [ExpressJS](https://expressjs.com/) that works in
15serverless environments like Val Town or Cloudflare Workers. If you come from
29### `index.html`
30
31The most complicated part of this backend API is serving index.html. In this app
32(like most apps) we serve it at the root, ie `GET /`.
33
37for client-side rendered apps.
38
39## CRUD API Routes
40
41This app has two CRUD API routes: for reading and inserting into the messages
42table. They both speak JSON, which is standard. They import their functions from
43`/backend/database/queries.ts`. These routes are called from the React app to
46## Errors
47
48Hono and other API frameworks have a habit of swallowing up Errors. We turn off
49this default behavior by re-throwing errors, because we think most of the time
50you'll want to see the full stack trace instead of merely "Internal Server

PixelPixelApiMonitor1 file match

@selfire1Updated 18 mins ago
Regularly polls the API and messages on an error.

weatherApp1 file match

@dcm31Updated 6 hours ago
A simple weather app with dropdown cities using Open-Meteo API
fapian
<("<) <(")> (>")>
Kapil01