Complete reference for all API endpoints in the NH Emerging Technologies Caucus website.
- Development:
http://localhost:3000/api - Production:
https://emergingtechnh.org/api
Admin endpoints require authentication via JWT token stored in cookies.
POST /api/auth/login
Content-Type: application/json
{
"password": "your-admin-password"
}Response:
{
"success": true
}Sets admin-token cookie for subsequent requests.
GET /api/auth/verifyResponse:
{
"authenticated": true,
"role": "admin"
}GET /api/events?limit=5&admin=falseQuery Parameters:
limit(optional): Number of events to returnadmin(optional): Set totrueto get all events including hidden ones (requires auth)
Response:
{
"success": true,
"data": [
{
"_id": "507f1f77bcf86cd799439011",
"date": "2025-03-15T12:00:00.000Z",
"time": "10:00 AM ET",
"presenter": "Dr. Jane Smith",
"presenterUrl": "https://example.com/jane",
"topic": "The Future of AI in Healthcare",
"location": "Online/Teams",
"locationUrl": "https://teams.microsoft.com/...",
"presentations": [
{
"filename": "ai-healthcare.pdf",
"contentType": "application/pdf",
"size": 1024000,
"uploadedAt": "2025-03-01T10:00:00.000Z"
}
],
"isVisible": true,
"content": "# Event Details\n\nMarkdown content here...",
"createdAt": "2025-03-01T10:00:00.000Z",
"updatedAt": "2025-03-01T10:00:00.000Z"
}
],
"total": 15
}Cache: 5 minutes (public requests)
GET /api/events/[id]?admin=falseResponse:
{
"success": true,
"data": {
"_id": "507f1f77bcf86cd799439011",
"date": "2025-03-15T12:00:00.000Z",
"time": "10:00 AM ET",
"topic": "The Future of AI",
...
}
}POST /api/events
Content-Type: multipart/form-data
date: 2025-03-15
time: 10:00 AM
timezone: ET
presenter: Dr. Jane Smith
presenterUrl: https://example.com/jane
topic: The Future of AI
location: Online/Teams
locationUrl: https://teams.microsoft.com/...
isVisible: true
content: # Markdown content
presentations: [file1.pdf, file2.pdf]Response:
{
"success": true,
"data": { /* created event */ }
}PUT /api/events/[id]
Content-Type: multipart/form-data
[Same fields as create]
keepPresentations: [filename1.pdf, filename2.pdf]DELETE /api/events/[id]Response:
{
"success": true,
"data": { /* deleted event */ }
}GET /api/events/[id]/presentationDownloads the first presentation file for the event.
GET /api/events/[id]/presentations/[index]Downloads presentation at specified index (0-based).
GET /api/resources?featured=true&limit=10&admin=falseQuery Parameters:
featured(optional): Filter for featured resources onlylimit(optional): Number of resources to returnadmin(optional): Include hidden resources (requires auth)
Response:
{
"success": true,
"data": [
{
"_id": "507f1f77bcf86cd799439012",
"title": "AI Ethics Guidelines",
"url": "https://example.com/ai-ethics",
"description": "Comprehensive guidelines for ethical AI development",
"thumbnail": "https://example.com/thumb.jpg",
"featured": true,
"order": 1,
"isVisible": true,
"createdAt": "2025-01-01T00:00:00.000Z",
"updatedAt": "2025-01-01T00:00:00.000Z"
}
],
"total": 25
}Cache: 5 minutes (public requests)
GET /api/resources/[id]POST /api/resources
Content-Type: application/json
{
"title": "Resource Title",
"url": "https://example.com",
"description": "Resource description",
"thumbnail": "https://example.com/thumb.jpg",
"featured": false,
"order": 0,
"isVisible": true
}PUT /api/resources/[id]
Content-Type: application/json
{
"title": "Updated Title",
"order": 5
}DELETE /api/resources/[id]GET /api/tech-list?admin=falseQuery Parameters:
admin(optional): Include hidden items and sort alphabetically (requires auth)
Response:
{
"success": true,
"data": [
{
"_id": "507f1f77bcf86cd799439013",
"name": "Artificial Intelligence",
"url": "https://en.wikipedia.org/wiki/Artificial_intelligence",
"isVisible": true,
"createdAt": "2025-01-01T00:00:00.000Z",
"updatedAt": "2025-01-01T00:00:00.000Z"
}
]
}Cache: 10 minutes (public requests)
GET /api/tech-list/[id]POST /api/tech-list
Content-Type: application/json
{
"name": "Quantum Computing",
"url": "https://example.com",
"isVisible": true
}PUT /api/tech-list/[id]
Content-Type: application/json
{
"name": "Updated Name",
"isVisible": false
}DELETE /api/tech-list/[id]POST /api/upload
Content-Type: multipart/form-data
file: [binary file data]Response:
{
"success": true,
"url": "/uploads/filename.pdf"
}All endpoints return errors in this format:
{
"success": false,
"error": "Error message description"
}Common Status Codes:
200- Success201- Created400- Bad Request401- Unauthorized (authentication required)404- Not Found500- Internal Server Error
Public endpoints are cached to reduce load:
- Events: 5 minute cache
- Resources: 5 minute cache
- Tech List: 10 minute cache
Admin endpoints have no caching for real-time updates.
const response = await fetch('/api/events?limit=5');
const { success, data, total } = await response.json();
if (success) {
console.log(`Showing ${data.length} of ${total} events`);
data.forEach(event => {
console.log(`${event.topic} - ${event.date}`);
});
}const formData = new FormData();
formData.append('date', '2025-03-15');
formData.append('time', '10:00 AM');
formData.append('timezone', 'ET');
formData.append('topic', 'Future of AI');
formData.append('location', 'Online');
formData.append('isVisible', 'true');
formData.append('presentations', pdfFile);
const response = await fetch('/api/events', {
method: 'POST',
body: formData
});
const { success, data } = await response.json();const response = await fetch(`/api/resources/${resourceId}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ order: 3 })
});TypeScript types are available in lib/types/api.ts:
import type {
Event,
Resource,
TechItem,
ApiResponse
} from '@/lib/types/api';- All admin endpoints require authentication
- JWT tokens expire after 24 hours
- Passwords are hashed with bcrypt
- Security headers are set on all responses
- CORS is configured for same-origin only