Docs /api-reference/rest-endpoints

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:

  1. Client initiates sign-in
  2. Better Auth returns GitHub OAuth URL
  3. User redirected to GitHub
  4. GitHub redirects back to /api/auth/callback/github
  5. Better Auth creates session
  6. 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 commits
  • pull_request - Run tests on PR
  • release - 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

Reading this with an agent? /docs/api-reference/rest-endpoints.md serves the raw markdown.

All docs