REST API Endpoints
REST endpoints available in the Izri platform (non-tRPC).
📋 Overview
While the primary API uses tRPC for type-safe communication, some endpoints are exposed as traditional REST APIs for:
- Health checks
- Better Auth authentication flows
- External webhooks (planned)
- Public API access (planned)
Base URL:
- API:
http://localhost:4000(dev) - Production:
https://api.yourdomain.com
🏥 Health Check
GET /health
Simple health check endpoint to verify API is running.
Authentication: None
Request:
curl http://localhost:4000/health
Response (200 OK):
{
"ok": true
}
Use Cases:
- Load balancer health checks
- Monitoring systems
- Container orchestration (Docker, Kubernetes)
- CI/CD pipeline verification
🔐 Better Auth Endpoints
All Better Auth endpoints are mounted at /api/auth/**.
POST /api/auth/sign-in/social
Initiate OAuth sign-in flow (GitHub).
Authentication: None
Request:
curl -X POST http://localhost:4000/api/auth/sign-in/social \
-H "Content-Type: application/json" \
-d '{
"provider": "github",
"callbackURL": "http://localhost:5173/dashboard"
}'
Response (200 OK):
{
"url": "https://github.com/login/oauth/authorize?client_id=...",
"redirect": true
}
Flow:
- Client initiates sign-in
- Better Auth returns GitHub OAuth URL
- User redirected to GitHub
- GitHub redirects back to
/api/auth/callback/github - Better Auth creates session
- User redirected to callbackURL
GET /api/auth/callback/github
GitHub OAuth callback endpoint (handled by Better Auth).
Authentication: OAuth state parameter
Request:
GET /api/auth/callback/github?code=abc123&state=xyz789
Response: Redirect to callbackURL with session cookie
Cookies Set:
better-auth.session_token=<token>; HttpOnly; Secure; SameSite=Lax
Note: This endpoint is called by GitHub, not directly by clients.
GET /api/auth/get-session
Get current session information.
Authentication: Session cookie
Request:
curl http://localhost:4000/api/auth/get-session \
-H "Cookie: better-auth.session_token=<token>"
Response (200 OK):
{
"session": {
"id": "session_abc123",
"userId": "user_xyz789",
"expiresAt": "2024-12-31T23:59:59.999Z",
"createdAt": "2024-01-01T00:00:00.000Z"
},
"user": {
"id": "user_xyz789",
"email": "user@example.com",
"name": "John Doe",
"avatar": "https://avatars.githubusercontent.com/...",
"emailVerified": true,
"createdAt": "2024-01-01T00:00:00.000Z"
}
}
Response (401 Unauthorized - no session):
{
"session": null,
"user": null
}
POST /api/auth/sign-out
Sign out current session.
Authentication: Session cookie
Request:
curl -X POST http://localhost:4000/api/auth/sign-out \
-H "Cookie: better-auth.session_token=<token>"
Response (200 OK):
{
"success": true
}
Side Effects:
- Session invalidated in database
- Session cookie cleared
POST /api/auth/revoke-session
Revoke a specific session.
Authentication: Session cookie
Request:
curl -X POST http://localhost:4000/api/auth/revoke-session \
-H "Cookie: better-auth.session_token=<token>" \
-H "Content-Type: application/json" \
-d '{
"token": "session_to_revoke"
}'
Response (200 OK):
{
"success": true
}
GET /api/auth/list-sessions
List all active sessions for current user.
Authentication: Session cookie
Request:
curl http://localhost:4000/api/auth/list-sessions \
-H "Cookie: better-auth.session_token=<token>"
Response (200 OK):
{
"sessions": [
{
"id": "session_current",
"userId": "user_xyz",
"expiresAt": "2024-12-31T23:59:59.999Z",
"createdAt": "2024-01-01T00:00:00.000Z",
"ipAddress": "192.168.1.1",
"userAgent": "Mozilla/5.0..."
},
{
"id": "session_mobile",
"userId": "user_xyz",
"expiresAt": "2024-12-30T23:59:59.999Z",
"createdAt": "2023-12-15T00:00:00.000Z",
"ipAddress": "10.0.0.1",
"userAgent": "Mobile Safari..."
}
]
}
🔑 API Token Authentication (Planned)
REST API access using API tokens for CI/CD and automation.
Authorization Header
curl http://localhost:4000/api/v1/projects \
-H "Authorization: Bearer izri_v1_k7n9p2q5r8t1u4v7w0x3y6z9_c4a8"
Token Format:
- Prefix:
izri_ - Version:
v1 - Random: 32 characters
- Checksum: 4 characters
See API Keys Feature for details.
📥 Webhook Endpoints (Planned)
Receive webhooks from external services.
POST /webhooks/github
Receive GitHub webhook events.
Authentication: GitHub webhook signature
Headers:
X-GitHub-Event: push
X-GitHub-Delivery: abc-123-def
X-Hub-Signature-256: sha256=abc123...
Content-Type: application/json
Request Body: GitHub webhook payload
Response (200 OK):
{
"received": true,
"processedAt": "2024-01-01T00:00:00.000Z"
}
Events Supported:
push- Trigger test run on new commitspull_request- Run tests on PRrelease- Trigger on release creation
Signature Verification:
import crypto from 'node:crypto'
function verifyGitHubSignature(payload: string, signature: string, secret: string): boolean {
const hmac = crypto.createHmac('sha256', secret)
const digest = `sha256=${hmac.update(payload).digest('hex')}`
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(digest))
}
📤 Public API v1 (Planned)
REST API for external integrations.
GET /api/v1/projects
List projects (requires API token).
Authentication: Bearer token
Request:
curl http://localhost:4000/api/v1/projects \
-H "Authorization: Bearer izri_v1_..."
Response (200 OK):
{
"projects": [
{
"id": "proj_123",
"name": "My App",
"repository": "https://github.com/user/repo",
"language": "typescript",
"framework": "react"
}
],
"pagination": {
"total": 1,
"page": 1,
"pageSize": 50
}
}
GET /api/v1/projects/:id
Get single project.
Authentication: Bearer token
Request:
curl http://localhost:4000/api/v1/projects/proj_123 \
-H "Authorization: Bearer izri_v1_..."
Response (200 OK):
{
"project": {
"id": "proj_123",
"name": "My App",
"repository": "https://github.com/user/repo",
"branch": "main",
"language": "typescript",
"framework": "react",
"testRuns": [
{
"id": "run_456",
"status": "completed",
"passedTests": 45,
"totalTests": 50,
"createdAt": "2024-01-01T00:00:00.000Z"
}
]
}
}
POST /api/v1/projects/:id/analyze
Trigger repository analysis.
Authentication: Bearer token
Request:
curl -X POST http://localhost:4000/api/v1/projects/proj_123/analyze \
-H "Authorization: Bearer izri_v1_..." \
-H "Content-Type: application/json" \
-d '{
"branch": "main"
}'
Response (202 Accepted):
{
"analysisId": "analysis_789",
"status": "pending",
"message": "Analysis started"
}
🔒 CORS Configuration
Allowed Origins (development):
http://localhost:5173 (Vite dev server)
http://localhost:3000
Allowed Methods:
GET, POST, PUT, DELETE, OPTIONS
Credentials: Enabled (allows cookies)
Production Configuration:
app.use('*', cors({
origin: [
'https://yourdomain.com',
'https://www.yourdomain.com'
],
credentials: true
}))
📊 Rate Limiting (Planned)
Default Limits:
- 100 requests per minute per IP
- 1000 requests per hour per API token
Headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640000000
Response (429 Too Many Requests):
{
"error": "Rate limit exceeded",
"retryAfter": 60
}
🚨 Error Responses
All REST endpoints return consistent error format:
Response (400 Bad Request):
{
"error": "Invalid request",
"message": "Missing required field: name",
"code": "VALIDATION_ERROR"
}
Response (401 Unauthorized):
{
"error": "Unauthorized",
"message": "Invalid or expired session token",
"code": "UNAUTHORIZED"
}
Response (403 Forbidden):
{
"error": "Forbidden",
"message": "Insufficient permissions",
"code": "FORBIDDEN"
}
Response (404 Not Found):
{
"error": "Not found",
"message": "Resource not found",
"code": "NOT_FOUND"
}
Response (500 Internal Server Error):
{
"error": "Internal server error",
"message": "An unexpected error occurred",
"code": "INTERNAL_ERROR",
"requestId": "req_abc123"
}
🔧 Request/Response Examples
cURL Examples
Health Check:
curl -i http://localhost:4000/health
Get Session:
curl http://localhost:4000/api/auth/get-session \
--cookie-jar cookies.txt \
--cookie cookies.txt
Sign Out:
curl -X POST http://localhost:4000/api/auth/sign-out \
--cookie cookies.txt
JavaScript/Fetch Examples
Check Health:
const response = await fetch('http://localhost:4000/health')
const data = await response.json()
console.log(data) // { ok: true }
Get Session:
const response = await fetch('http://localhost:4000/api/auth/get-session', {
credentials: 'include'
})
const data = await response.json()
console.log(data.user)
Sign Out:
const response = await fetch('http://localhost:4000/api/auth/sign-out', {
method: 'POST',
credentials: 'include'
})
const data = await response.json()
🔗 Related Documentation
- tRPC Routers - Primary API (type-safe)
- Authentication API - Auth flows
- Webhooks API - Webhook details
- Error Codes - Error reference
- Backend - Hono Setup - Server configuration