Overview
The branches endpoint fetches all available branches for a GitHub repository along with branch metadata. This is useful for displaying branch selection UI or validating branch names before analysis.
Endpoint
Request
Body Parameters
Full GitHub repository URL Format: https://github.com/{owner}/{repo}Example: https://github.com/vercel/next.js
Example Request
curl -X POST https://repolyze.ossium.live/api/branches \
-H "Content-Type: application/json" \
-d '{"url": "https://github.com/vercel/next.js"}'
Response
Success Response (200)
Array of branch objects Branch name (e.g., "main", "develop", "canary")
Latest commit information GitHub API URL for the commit
Whether the branch is protected
Whether this is the repository’s default branch
Name of the repository’s default branch
Content-Type : application/json
Cache-Control : public, s-maxage=300, stale-while-revalidate=600
Example Response
{
"branches" : [
{
"name" : "canary" ,
"commit" : {
"sha" : "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0" ,
"url" : "https://api.github.com/repos/vercel/next.js/commits/a1b2c3d4"
},
"protected" : true ,
"isDefault" : true
},
{
"name" : "main" ,
"commit" : {
"sha" : "b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1" ,
"url" : "https://api.github.com/repos/vercel/next.js/commits/b2c3d4e5"
},
"protected" : true ,
"isDefault" : false
},
{
"name" : "develop" ,
"commit" : {
"sha" : "c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2" ,
"url" : "https://api.github.com/repos/vercel/next.js/commits/c3d4e5f6"
},
"protected" : false ,
"isDefault" : false
}
],
"defaultBranch" : "canary"
}
Error Responses
400 Bad Request
Returned when the request is invalid.
{
"error" : "URL is required"
}
or
{
"error" : "Invalid GitHub URL format. Expected: https://github.com/owner/repo"
}
404 Not Found
Returned when the repository doesn’t exist or is not accessible.
{
"error" : "Repository not found or not accessible"
}
429 Too Many Requests
Returned when rate limit is exceeded.
{
"error" : "Too many requests. Please try again later."
}
Response Headers:
500 Internal Server Error
Returned when an unexpected error occurs.
{
"error" : "Failed to fetch branches"
}
Code Examples
JavaScript/TypeScript
interface BranchInfo {
name : string ;
commit : {
sha : string ;
url : string ;
};
protected : boolean ;
isDefault : boolean ;
}
interface BranchesResponse {
branches : BranchInfo [];
defaultBranch : string ;
}
async function fetchBranches ( repoUrl : string ) : Promise < BranchesResponse > {
const response = await fetch ( 'https://repolyze.ossium.live/api/branches' , {
method: 'POST' ,
headers: {
'Content-Type' : 'application/json'
},
body: JSON . stringify ({ url: repoUrl })
});
if ( ! response . ok ) {
const error = await response . json ();
throw new Error ( error . error || 'Failed to fetch branches' );
}
return await response . json ();
}
// Usage
try {
const { branches , defaultBranch } = await fetchBranches (
'https://github.com/vercel/next.js'
);
console . log ( 'Default branch:' , defaultBranch );
console . log ( 'All branches:' , branches . map ( b => b . name ));
console . log ( 'Protected branches:' , branches . filter ( b => b . protected ). map ( b => b . name ));
} catch ( error ) {
console . error ( 'Error:' , error . message );
}
React Hook Example
import { useState , useEffect } from 'react' ;
function useBranches ( repoUrl : string | null ) {
const [ branches , setBranches ] = useState < BranchInfo []>([]);
const [ defaultBranch , setDefaultBranch ] = useState < string >( '' );
const [ loading , setLoading ] = useState ( false );
const [ error , setError ] = useState < string | null >( null );
useEffect (() => {
if ( ! repoUrl ) return ;
const fetchBranches = async () => {
setLoading ( true );
setError ( null );
try {
const response = await fetch ( '/api/branches' , {
method: 'POST' ,
headers: { 'Content-Type' : 'application/json' },
body: JSON . stringify ({ url: repoUrl })
});
if ( ! response . ok ) {
const errorData = await response . json ();
throw new Error ( errorData . error );
}
const data = await response . json ();
setBranches ( data . branches );
setDefaultBranch ( data . defaultBranch );
} catch ( err ) {
setError ( err instanceof Error ? err . message : 'Unknown error' );
} finally {
setLoading ( false );
}
};
fetchBranches ();
}, [ repoUrl ]);
return { branches , defaultBranch , loading , error };
}
// Usage in component
function BranchSelector ({ repoUrl } : { repoUrl : string }) {
const { branches , defaultBranch , loading , error } = useBranches ( repoUrl );
const [ selectedBranch , setSelectedBranch ] = useState ( '' );
useEffect (() => {
if ( defaultBranch ) {
setSelectedBranch ( defaultBranch );
}
}, [ defaultBranch ]);
if ( loading ) return < div > Loading branches ...</ div > ;
if ( error ) return < div > Error : { error } </ div > ;
return (
< select value = { selectedBranch } onChange = {(e) => setSelectedBranch (e.target.value)} >
{ branches . map (( branch ) => (
< option key = {branch. name } value = {branch. name } >
{ branch . name }
{ branch . isDefault && ' ( default )'}
{ branch . protected && ' 🔒'}
</ option >
))}
</ select >
);
}
Python
import requests
from typing import List, Dict, Any
def fetch_branches ( repo_url : str ) -> Dict[ str , Any]:
"""
Fetch all branches for a GitHub repository.
Args:
repo_url: Full GitHub repository URL
Returns:
Dictionary with 'branches' and 'defaultBranch' keys
Raises:
Exception: If the request fails
"""
endpoint = 'https://repolyze.ossium.live/api/branches'
response = requests.post(
endpoint,
json = { 'url' : repo_url},
headers = { 'Content-Type' : 'application/json' }
)
if response.status_code != 200 :
error_data = response.json()
raise Exception (error_data.get( 'error' , 'Failed to fetch branches' ))
return response.json()
# Usage
try :
result = fetch_branches( 'https://github.com/vercel/next.js' )
branches = result[ 'branches' ]
default_branch = result[ 'defaultBranch' ]
print ( f "Default branch: { default_branch } " )
print ( f "Total branches: { len (branches) } " )
# Print protected branches
protected = [b[ 'name' ] for b in branches if b[ 'protected' ]]
print ( f "Protected branches: { ', ' .join(protected) } " )
# Print all branch names
for branch in branches:
prefix = '🔒' if branch[ 'protected' ] else ' '
suffix = ' (default)' if branch[ 'isDefault' ] else ''
print ( f " { prefix } { branch[ 'name' ] }{ suffix } " )
except Exception as e:
print ( f "Error: { e } " )
cURL
# Basic request
curl -X POST https://repolyze.ossium.live/api/branches \
-H "Content-Type: application/json" \
-d '{"url": "https://github.com/vercel/next.js"}'
# Pretty print with jq
curl -X POST https://repolyze.ossium.live/api/branches \
-H "Content-Type: application/json" \
-d '{"url": "https://github.com/vercel/next.js"}' \
| jq '.'
# Get only branch names
curl -s -X POST https://repolyze.ossium.live/api/branches \
-H "Content-Type: application/json" \
-d '{"url": "https://github.com/vercel/next.js"}' \
| jq -r '.branches[].name'
# Get default branch
curl -s -X POST https://repolyze.ossium.live/api/branches \
-H "Content-Type: application/json" \
-d '{"url": "https://github.com/vercel/next.js"}' \
| jq -r '.defaultBranch'
Caching
The branches endpoint implements HTTP caching:
Cache-Control: public, s-maxage=300, stale-while-revalidate=600
Duration: 5 minutes (300 seconds)
Stale-while-revalidate: 10 minutes (600 seconds)
This means:
Fresh responses are served from cache for 5 minutes
Stale responses can be served for up to 10 additional minutes while revalidating in the background
Total potential cache duration: 15 minutes
Rate Limiting
The branches endpoint is subject to the same rate limits as other API endpoints:
Per-minute limit: 10 requests per IP
Window: 60-second rolling window
Response code: 429 Too Many Requests
Retry-After header: 60 seconds
See API Overview - Rate Limits for details.
Use Cases
1. Branch Selection UI
Fetch branches before analysis to allow users to select which branch to analyze:
// Step 1: Fetch branches
const { branches , defaultBranch } = await fetchBranches ( repoUrl );
// Step 2: Display branch selector
// User selects a branch
// Step 3: Analyze selected branch
const analysis = await analyzeRepository ( repoUrl , selectedBranch );
2. Branch Validation
Validate that a branch exists before attempting analysis:
async function analyzeWithValidation ( repoUrl : string , branchName : string ) {
const { branches } = await fetchBranches ( repoUrl );
const branchExists = branches . some ( b => b . name === branchName );
if ( ! branchExists ) {
throw new Error ( `Branch " ${ branchName } " not found` );
}
return analyzeRepository ( repoUrl , branchName );
}
3. Default Branch Detection
Use the default branch when no specific branch is requested:
async function analyzeDefaultBranch ( repoUrl : string ) {
const { defaultBranch } = await fetchBranches ( repoUrl );
return analyzeRepository ( repoUrl , defaultBranch );
}
4. Protected Branch Filtering
Filter and display only protected branches:
const { branches } = await fetchBranches ( repoUrl );
const protectedBranches = branches . filter ( b => b . protected );
console . log ( 'Protected branches:' , protectedBranches . map ( b => b . name ));
Best Practices
Cache locally: Store branch data in your application state to avoid redundant requests when users navigate between views.
Handle errors gracefully: Always provide fallback UI when branch fetching fails. The default branch from repository metadata can be used as a fallback.
Pre-fetch branches: Fetch branches immediately after URL validation but before the user needs to select a branch. This provides instant branch selection UI.
Don’t poll unnecessarily: Branches don’t change frequently. Rely on the HTTP cache headers and avoid polling for updates.