JavaScript
    rest-api

    JavaScript GitHub REST API Example with Personal Access Token

    Step-by-step JavaScript GitHub REST API example using fetch and personal access tokens. Learn authentication, pagination, error handling, and rate limit best practices with Apicurl.

    0 views
    Updated 2/23/2026

    Ready to test this code?

    Load this example into the app

    Code Example

    Copy and run
    const GITHUB_TOKEN = process.env.GITHUB_TOKEN || "ghp_your_personal_access_token_here";
    
    async function listReposForUser(username) {
      const url = new URL(`https://api.github.com/users/${username}/repos`);
      url.searchParams.set("per_page", "10");
      url.searchParams.set("sort", "updated");
    
      const response = await fetch(url, {
        headers: {
          "Authorization": `Bearer ${GITHUB_TOKEN}`,
          "Accept": "application/vnd.github+json",
          "User-Agent": "apicurl-github-api-example"
        }
      });
    
      if (!response.ok) {
        console.error("Failed to fetch repositories", response.status, await response.text());
        throw new Error(`Failed to fetch repositories for ${username}`);
      }
    
      const repos = await response.json();
      for (const repo of repos) {
        console.log(`- ${repo.full_name} (⭐ ${repo.stargazers_count})`);
      }
    }
    
    listReposForUser("vercel").catch(console.error);

    Overview

    JavaScript GitHub REST API Example with Personal Access Token

    GitHub's REST API is one of the most widely used APIs in the developer ecosystem. Whether you're building internal tooling, dashboards, CI pipelines, or automation scripts, knowing how to call the GitHub API securely from JavaScript is a fundamental skill.

    In this example, you'll learn how to:

    • Authenticate with the GitHub REST API using a personal access token (PAT)
    • Call common endpoints using the modern fetch API
    • Handle JSON responses, errors, and status codes correctly
    • Implement basic pagination for endpoints that return lists
    • Apply production-ready best practices for security and performance
    • Use the same request inside Apicurl to test and debug your GitHub integrations

    This guide uses a read-only scenario: fetching repositories and issues for a GitHub user or organization. The patterns are the same for more advanced operations such as creating issues, comments, or pull requests.

    Prerequisites

    Before you start, make sure you have:

    • A GitHub account
    • A GitHub personal access token (PAT) with at least repo read permissions
    • Node.js or a browser environment that supports the fetch API
    • Apicurl opened at /app if you want to test the request interactively

    1. Create a GitHub Personal Access Token

    1. Sign in to GitHub.
    2. Go to Settings → Developer settings → Personal access tokens.
    3. Create a new token with scopes like:
      • repo (read access is enough for most examples)
      • read:user if you want to access profile data
    4. Copy the generated token. It will look like:
    ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    

    Never commit real tokens to Git, code samples, or client-side JavaScript that ships to end users. In production, load tokens from environment variables or a secure secrets store.

    For this tutorial and in Apicurl, you can use a placeholder like:

    GITHUB_TOKEN=ghp_your_personal_access_token_here
    

    2. Base GitHub REST API Request

    Most GitHub REST endpoints are available under:

    https://api.github.com
    

    When authenticating with a personal access token, you typically:

    • Send the token in the Authorization header as Bearer <token>
    • Send an explicit User-Agent header (GitHub recommends this)

    Here is a minimal JavaScript example that fetches your own user profile:

    const GITHUB_TOKEN = process.env.GITHUB_TOKEN || "ghp_your_personal_access_token_here";
    
    async function getCurrentUser() {
      const response = await fetch("https://api.github.com/user", {
        method: "GET",
        headers: {
          "Authorization": `Bearer ${GITHUB_TOKEN}`,
          "Accept": "application/vnd.github+json",
          "User-Agent": "apicurl-github-api-example"
        }
      });
    
      if (!response.ok) {
        console.error("GitHub API error", response.status, await response.text());
        throw new Error(`GitHub API request failed with status ${response.status}`);
      }
    
      const data = await response.json();
      console.log("Authenticated as:", data.login);
    }
    
    getCurrentUser().catch(console.error);
    

    3. List Repositories for a User or Organization

    A very common use case is listing repositories for a given user or organization. This can power dashboards, internal tooling, or integration tests that validate repository metadata.

    async function listReposForUser(username) {
      const url = new URL(`https://api.github.com/users/${username}/repos`);
      url.searchParams.set("per_page", "10");
      url.searchParams.set("sort", "updated");
    
      const response = await fetch(url, {
        headers: {
          "Authorization": `Bearer ${GITHUB_TOKEN}`,
          "Accept": "application/vnd.github+json",
          "User-Agent": "apicurl-github-api-example"
        }
      });
    
      if (!response.ok) {
        console.error("Failed to fetch repositories", response.status, await response.text());
        throw new Error(`Failed to fetch repositories for ${username}`);
      }
    
      const repos = await response.json();
      for (const repo of repos) {
        console.log(`- ${repo.full_name} (⭐ ${repo.stargazers_count})`);
      }
    }
    
    listReposForUser("vercel").catch(console.error);
    

    This pattern is reusable for many GitHub list endpoints: you build a URL object, configure query parameters, and handle the JSON response.

    4. Handling Pagination Properly

    GitHub paginates most list endpoints. To access additional pages, you can:

    • Read the Link header from the response
    • Follow the rel="next" URL if present
    function parseLinkHeader(linkHeader) {
      if (!linkHeader) return {};
      const links = {};
      for (const part of linkHeader.split(",")) {
        const section = part.split(";");
        if (section.length !== 2) continue;
        const url = section[0].trim().replace(/<|>/g, "");
        const nameMatch = section[1].match(/rel="(.*)"/);
        const name = nameMatch && nameMatch[1];
        if (name) links[name] = url;
      }
      return links;
    }
    
    async function listAllRepos(username) {
      let url = `https://api.github.com/users/${username}/repos?per_page=50`;
    
      while (url) {
        const response = await fetch(url, {
          headers: {
            "Authorization": `Bearer ${GITHUB_TOKEN}`,
            "Accept": "application/vnd.github+json",
            "User-Agent": "apicurl-github-api-example"
          }
        });
    
        if (!response.ok) {
          console.error("Error while paging repos", response.status, await response.text());
          break;
        }
    
        const repos = await response.json();
        repos.forEach((repo) => console.log(repo.full_name));
    
        const links = parseLinkHeader(response.headers.get("Link"));
        url = links.next || "";
      }
    }
    
    listAllRepos("vercel").catch(console.error);
    

    This implementation respects GitHub's pagination model and can be reused for issues, pull requests, and other list resources.

    5. Handling Errors and Rate Limits

    When integrating with GitHub in production, you must handle:

    • Authentication failures (401): invalid or missing token
    • Authorization failures (403): insufficient scopes
    • Rate limiting (403 with specific rate-limit headers)
    • Not found (404): wrong user, repo, or endpoint

    GitHub provides headers such as X-RateLimit-Remaining and X-RateLimit-Reset. You can log these values to understand when you are approaching limits.

    async function safeGitHubRequest(url, options = {}) {
      const response = await fetch(url, {
        ...options,
        headers: {
          "Authorization": `Bearer ${GITHUB_TOKEN}`,
          "Accept": "application/vnd.github+json",
          "User-Agent": "apicurl-github-api-example",
          ...(options.headers || {})
        }
      });
    
      const remaining = response.headers.get("X-RateLimit-Remaining");
      const resetAt = response.headers.get("X-RateLimit-Reset");
    
      if (!response.ok) {
        console.error("GitHub request failed", {
          status: response.status,
          remaining,
          resetAt
        });
        throw new Error(`GitHub request failed with status ${response.status}`);
      }
    
      return response.json();
    }
    

    You can now reuse safeGitHubRequest for all your GitHub calls.

    6. Using This Example in Apicurl

    Apicurl makes it easy to convert your GitHub API calls into reusable requests and share them across your team:

    1. Open /examples/javascript/rest-api/javascript-github-rest-api.
    2. Click "Try It in Apicurl".
    3. The example request will load into the Apicurl app.
    4. Replace the placeholder token value with your real GitHub PAT.
    5. Send the request and inspect headers, JSON responses, and error cases.

    From there you can:

    • Save the request into a collection for any GitHub repository you manage.
    • Duplicate the request to test different endpoints (issues, pulls, workflows).
    • Generate code for other languages (Python, Go, PHP) directly from the saved request.

    7. Best Practices Recap

    When calling the GitHub REST API from JavaScript:

    • Always use HTTPS and authenticate with a personal access token.
    • Store tokens in environment variables or secrets, not in version control.
    • Use a dedicated User-Agent header to identify your integration.
    • Handle errors and rate limits proactively.
    • Paginate list endpoints using the Link header.
    • Use tools like Apicurl to test, debug, and share GitHub API requests.

    By following these patterns, you get a robust, production-ready GitHub integration that is easy to maintain and safe to run at scale.

    Related Topics

    javascript
    github api
    rest api
    fetch
    personal access token
    api authentication
    api integration
    api testing
    apicurl

    Ready to test APIs like a pro?

    Apicurl is a free, powerful API testing tool.