Skip to main content

Introduction

The Repolyze API provides programmatic access to repository analysis capabilities. All endpoints return JSON responses and support real-time streaming for the analyze endpoint.

Base URL

https://repolyze.ossium.live/api
For local development:
http://localhost:3000/api

Authentication

The Repolyze API does not require authentication for public repositories. API requests are rate-limited based on client IP address.

Rate Limits

Repolyze implements two types of rate limiting:

Per-Minute Rate Limit (Burst Protection)

  • Limit: 10 requests per minute per IP
  • Window: 60 seconds rolling window
  • Applies to: All API endpoints
  • Response: 429 Too Many Requests with Retry-After: 60 header

Daily Analysis Limits (Tiered)

The /api/analyze endpoint has additional daily limits based on user tier:
TierDaily LimitDescription
Anonymous1 analysis/dayUnauthenticated users (IP-based)
Free3 analyses/daySigned-in users
Pro44 analyses/dayPro subscription users

Daily Limit Response

{
  "error": "Daily limit reached. Sign in to get more analyses.",
  "code": "DAILY_LIMIT_REACHED",
  "limit": 1,
  "remaining": 0,
  "tier": "anonymous"
}

Response Headers

All API responses include rate limit information:
X-RateLimit-Remaining: 8
Content-Type: application/json
Cache-Control: public, s-maxage=300, stale-while-revalidate=600

Streaming Responses

The /api/analyze endpoint uses Server-Sent Events (SSE) for real-time streaming:
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
Each event is formatted as:
data: {"type":"metadata","data":{...}}

data: {"type":"content","data":"..."}

data: {"type":"scores","data":{...}}

data: {"type":"done"}

Error Handling

All errors follow a consistent format:
{
  "error": "Error message describing what went wrong"
}
For detailed error codes and responses, see Error Responses.

Available Endpoints

Analyze Repository

Perform comprehensive AI-powered analysis of a GitHub repository

Get Branches

Retrieve all available branches for a repository

GitHub Info

Get repository metadata and statistics

Authentication & Account

Manage user accounts and check usage limits

Quick Start

cURL Example

curl -X POST https://repolyze.ossium.live/api/analyze \
  -H "Content-Type: application/json" \
  -d '{"url": "https://github.com/vercel/next.js"}'

JavaScript/TypeScript Example

const response = await fetch('https://repolyze.ossium.live/api/analyze', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    url: 'https://github.com/vercel/next.js',
    branch: 'canary'
  })
});

// Handle streaming response
const reader = response.body?.getReader();
const decoder = new TextDecoder();

while (true) {
  const { done, value } = await reader!.read();
  if (done) break;
  
  const chunk = decoder.decode(value);
  const lines = chunk.split('\n');
  
  for (const line of lines) {
    if (line.startsWith('data: ')) {
      const event = JSON.parse(line.slice(6));
      console.log(event.type, event.data);
    }
  }
}

Python Example

import requests
import json

url = 'https://repolyze.ossium.live/api/analyze'
data = {'url': 'https://github.com/vercel/next.js'}

response = requests.post(url, json=data, stream=True)

for line in response.iter_lines():
    if line.startswith(b'data: '):
        event = json.loads(line[6:])
        print(event['type'], event.get('data'))

Request Size Limits

  • Maximum request body size: 10 KB (10,240 bytes)
  • Content-Length header: Checked before parsing
  • Response: 413 Payload Too Large

Caching

Repolyze implements multiple layers of caching for optimal performance:

Analysis Result Cache

  • Duration: In-memory cache for recently analyzed repositories
  • Key: {owner}/{repo}:{branch}
  • Behavior: Instant response for cached results (no AI call)

GitHub Data Cache

  • Metadata: Server-side cached
  • Branches: 5 minutes (300 seconds) with stale-while-revalidate
  • Repository tree: Cached per branch

In-Flight Request Deduplication

If the same repository is being analyzed by multiple requests simultaneously, subsequent requests wait for the first analysis to complete and receive the cached result.

Status Codes

CodeStatusDescription
200OKRequest successful
400Bad RequestInvalid request parameters
404Not FoundRepository or branch not found
413Payload Too LargeRequest body exceeds 10 KB
429Too Many RequestsRate limit exceeded
500Internal Server ErrorServer error during analysis
503Service UnavailableServer not properly configured

Health Check

You can check the API health status:
curl https://repolyze.ossium.live/api/analyze
Response:
{
  "status": "ok",
  "timestamp": "2026-03-03T10:30:00.000Z",
  "services": {
    "openrouter": "configured",
    "github": "configured"
  }
}

Best Practices

Always check the X-RateLimit-Remaining header and implement exponential backoff when you receive 429 responses.
async function analyzeWithRetry(url: string, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    const response = await fetch('/api/analyze', {
      method: 'POST',
      body: JSON.stringify({ url })
    });
    
    if (response.status !== 429) return response;
    
    const retryAfter = response.headers.get('Retry-After');
    await new Promise(resolve => 
      setTimeout(resolve, (parseInt(retryAfter || '60')) * 1000)
    );
  }
  throw new Error('Max retries exceeded');
}
The analyze endpoint streams multiple event types. Handle each type appropriately:
  • metadata: Initial repository information
  • scores: Quality scores and metrics
  • content: AI-generated analysis text
  • automations: Suggested improvements
  • refactors: Refactoring suggestions
  • tier: User tier information
  • done: Analysis complete
  • error: Error occurred
Always validate GitHub URLs before sending requests:
function validateGitHubUrl(url: string): boolean {
  const pattern = /^https:\/\/github\.com\/[\w.-]+\/[\w.-]+\/?$/;
  return pattern.test(url);
}
If you need to analyze a specific branch, fetch available branches first to ensure it exists:
// 1. Get available branches
const branchesResponse = await fetch('/api/branches', {
  method: 'POST',
  body: JSON.stringify({ url })
});
const { branches, defaultBranch } = await branchesResponse.json();

// 2. Analyze with validated branch
const targetBranch = branches.find(b => b.name === 'develop') 
  ? 'develop' 
  : defaultBranch;
  
await fetch('/api/analyze', {
  method: 'POST',
  body: JSON.stringify({ url, branch: targetBranch })
});

Need Help?

If you encounter issues or have questions:

Build docs developers (and LLMs) love