Get your dream built 10x faster

How to integrate GitHub API with OpenClaw

We build custom applications 5x faster and cheaper 🚀

Book a Free Consultation
4.9
Clutch rating 🌟
600+
Happy partners
17+
Countries served
190+
Team members
Matt Graham, CEO of Rapid Developers

Book a call with an Expert

Stuck on an error? Book a 30-minute call with an engineer and get a direct fix + next steps. No pressure, no commitment.

How to integrate GitHub API with OpenClaw

OpenClaw can integrate with GitHub by treating GitHub as an external service: register an OAuth app or use a personal/access token on GitHub, configure those credentials as secrets for your OpenClaw skill in ClawHub, implement the OAuth token exchange or token storage on a reliable external service (web server or secret store), receive GitHub webhooks on an external HTTPS endpoint (validate signatures), and have the OpenClaw agent call GitHub’s REST APIs (authenticated requests) for operations like creating issues, commenting, or triggering workflows. Keep persistent/stateful pieces (webhook receiver, OAuth redirect handler, token refresh/storage, job queues) outside the agent runtime; use the agent to run short, authenticated API calls and business logic only after confirming credentials and scopes.

 

High-level components

 
  • GitHub side: OAuth App (client_id/client_secret) or Personal Access Token (PAT); webhook configuration for repository or org events; API endpoints (REST: api.github.com).
  • Secrets & configuration: store client_id, client_secret, webhook secret, and tokens in ClawHub secret storage or a secure environment variable store used by your skill.
  • External services (must be external): HTTPS webhook receiver + OAuth redirect handler, a small web server or function to persist tokens (database or secret store), and any scheduler/queue for long-running work.
  • OpenClaw skill: code that, when invoked by an agent, uses stored credentials (or an access token passed in) to call the GitHub REST API. It should not be relied on for long-term uptime or persistent web endpoints.

 

Step-by-step integration (practical)

 
  • Register a GitHub OAuth App (or create PAT)
    • GitHub OAuth App: set application name, homepage URL, and an OAuth callback URL hosted on a reliable HTTPS server you control (this handles the code→token exchange).
    • Or: create a Personal Access Token (PAT) if single-user automation suffices. Prefer OAuth for multi-user or user-scoped access.
  • Decide where to host stateful endpoints
    • Webhook receiver and OAuth redirect endpoints must be externally reachable over HTTPS. The agent runtime should not be expected to reliably receive webhooks—use a separate web server (Heroku, AWS Lambda/API Gateway, Cloud Run, etc.).
  • Configure ClawHub/OpenClaw skill
    • Create a skill in ClawHub and configure required environment variables or secret keys: GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, WEBHOOK\_SECRET, and any service account tokens. Use the secure secret storage ClawHub provides (or a vault) rather than embedding secrets in code.
    • Define the skill’s inputs/outputs (what the agent will call it with) and required permissions. Keep the skill’s runtime responsibilities minimal: authenticate and call GitHub APIs, return results, and emit logs/errors.
  • Implement OAuth flow and token storage
    • User is redirected to GitHub authorization URL:
      https://github.com/login/oauth/authorize?client_id=<CLIENT_ID>&scope=repo,workflow&state=<RANDOM>
      // include scopes you need (e.g., repo, workflow, repo:status, read:org)
    • On redirect to your callback, exchange the code for a token:
      POST https://github.com/login/oauth/access\_token
      Accept: application/json
      
      

      {
      "client_id":"<CLIENT_ID>",
      "client_secret":"<CLIENT_SECRET>",
      "code":"<CODE>"
      }


      // GitHub returns access_token in JSON when Accept: application/json is set
    • Persist the access\_token in a secure store (DB or secret manager) and associate it with the user or installation ID. The OpenClaw agent should fetch tokens from that store when it needs to call GitHub.
  • Set up webhooks
    • Configure a webhook in the target GitHub repo/org pointing to your external webhook URL. Set a Webhook Secret to validate payloads.
    • In your webhook receiver, verify signature with HMAC SHA-256 against the X-Hub-Signature-256 header before processing events.
  • Agent runtime behavior
    • Agent/skill receives a request from your conversation or workflow that needs a GitHub action (for example: "Create issue"). The skill retrieves the right token from the secret store, constructs an HTTP request to GitHub API, adds Authorization: Bearer <token> (or token <token>), and executes the call synchronously. Return the API response or normalized result to the caller.
    • For event-driven flows, the webhook receiver (external) can call into OpenClaw via the ClawHub skill invocation API or push the event to a queue that the agent processes. Don’t rely on the agent to receive webhooks directly.

 

Working code examples

 
  • Webhook receiver (Node.js + Express) — verify signature
    const express = require('express');
    const crypto = require('crypto');
    const app = express();
    app.use(express.raw({type: '_/_'})); 
    // Use raw body to compute signature exactly as GitHub sends
    
    

    const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET;

    function verifySignature(req) {
    const signature = req.headers['x-hub-signature-256'] || '';
    const hmac = crypto.createHmac('sha256', WEBHOOK_SECRET);
    hmac.update(req.body);
    const digest = 'sha256=' + hmac.digest('hex');
    const sigBuffer = Buffer.from(signature);
    const digestBuffer = Buffer.from(digest);
    if (sigBuffer.length !== digestBuffer.length) {
    return false;
    }
    return crypto.timingSafeEqual(sigBuffer, digestBuffer);
    }

    app.post('/webhook', (req, res) => {
    if (!verifySignature(req)) {
    return res.status(401).send('invalid signature');
    }
    const event = req.headers['x-github-event'];
    const payload = JSON.parse(req.body.toString());
    // Process event: persist or enqueue for agent processing
    console.log('received event', event, payload.repository && payload.repository.full_name);
    res.status(200).send('ok');
    });

    app.listen(3000);

  • Create an issue via GitHub REST API (Node.js + axios)
    const axios = require('axios');
    
    

    async function createIssue(token, owner, repo, title, body) {
    const url = https://api.github.com/repos/${owner}/${repo}/issues;
    const resp = await axios.post(url, {
    title,
    body
    }, {
    headers: {
    'Authorization': token ${token},
    'Accept': 'application/vnd.github+json',
    'User-Agent': 'openclaw-integration'
    }
    });
    return resp.data;
    }

    /* usage:
    const token = process.env.GH_TOKEN;
    createIssue(token, 'owner', 'repo', 'Issue title', 'Body text')
    .then(i => console.log('Created', i.html_url))
    .catch(e => console.error(e.response && e.response.data || e));
    */

  • OAuth token exchange (cURL)
    curl -X POST "https://github.com/login/oauth/access\_token" \\
      -H "Accept: application/json" \\
      -d client_id="<CLIENT_ID>" \\
      -d client_secret="<CLIENT_SECRET>" \\
      -d code="<CODE>"

 

Security and permission notes

 
  • Scopes: request the least privilege set of scopes for your skill (e.g., repo for repo operations, workflow to trigger workflows). If you only need read-only access, choose read-only scopes.
  • Webhook secret: always validate X-Hub-Signature-256. Never act on webhook payloads unless signature verification passes.
  • Token storage: use encrypted secret storage (ClawHub secrets or a dedicated vault) and rotate tokens periodically. Do not embed secrets in agent code or in client-side code.
  • Rate limits: GitHub enforces rate limits per token and per IP. Handle 403/429 responses gracefully and inspect X-RateLimit-\* headers.

 

Where to place responsibilities (agent vs external)

 
  • Agent/skill (OpenClaw)
    • Short-lived API calls to GitHub using an access token obtained from secure storage.
    • Business logic that can run within the agent’s execution time limits.
    • Returning structured results to the conversation or workflow that invoked the skill.
  • External systems (required)
    • Webhook receiver and signature validation (must be HTTPS endpoint).
    • OAuth redirect/callback handler and secure token persistence (DB/vault).
    • Long-running jobs, retries, task queues, and anything requiring high uptime.

 

Debugging checklist

 
  • Check webhook deliveries in the GitHub repo/org webhook settings for response codes and payloads.
  • Verify webhook signature calculation and that the WEBHOOK\_SECRET used matches GitHub’s configured secret.
  • Inspect API responses (status code and body). GitHub returns helpful error messages in JSON (e.g., scope missing, rate-limited, validation failed).
  • Confirm the token in use has the correct scopes: make an introspection call like GET /user or GET /rate\_limit and check headers.
  • Examine ClawHub/OpenClaw skill logs for errors, missing environment variables, or failed secret fetches.
  • Try a manual API call with curl and the same token to isolate whether the failure is in the agent code or GitHub side.
  • Watch for rate limit headers: X-RateLimit-Remaining, X-RateLimit-Reset.

 

Common actions and API endpoints (examples)

 
  • Create an issue: POST /repos/{owner}/{repo}/issues
  • Comment on issue: POST /repos/{owner}/{repo}/issues/{issue\_number}/comments
  • Trigger workflow: POST /repos/{owner}/{repo}/actions/workflows/{workflow\_id}/dispatches with {ref}
  • List repos: GET /user/repos or GET /orgs/{org}/repos

Book Your Free 30‑Minute Migration Call

Speak one‑on‑one with a senior engineer about your no‑code app, migration goals, and budget. In just half an hour you’ll leave with clear, actionable next steps—no strings attached.

Book a Free Consultation

Troubleshooting GitHub API and OpenClaw Integration

1

Fix GitHub webhook signature mismatch in OpenClaw webhook receiver

Short answer: confirm the GitHub webhook secret stored in your GitHub repo matches the secret your OpenClaw webhook receiver (skill) uses, compute the HMAC-SHA256 over the raw HTTP request body and compare it to the X-Hub-Signature-256 header using a constant-time compare, and ensure your runtime delivers the raw body to the skill (disable JSON body-parsing that consumes the stream).

 

Steps to fix

 
  • Verify secret: put the same secret in GitHub webhook settings and as an environment variable for the skill (ClawHub/agent runtime).
  • Use raw body: configure the webhook receiver to access the raw request bytes before any JSON parser; proxies or middleware often change the body.
  • Compute and compare: compute HMAC-SHA256(raw_body, secret), prefix with sha256=, and constant-time compare to X-Hub-Signature-256.
  • Check headers & proxies: ensure the header reaches the runtime unchanged and HTTPS termination doesn’t alter payload.
  • Logging: log the header, computed signature (safe truncation), and whether verification passed to debug; don’t leak secrets.

2

Configure GitHub App authentication for OpenClaw GitHub connector (App ID, Installation ID, private key/JWT) to avoid 401

Start by ensuring your connector uses three authenticated pieces: the GitHub App ID, the Installation ID, and a JWT signed with the App private key. Generate a short-lived JWT (RS256) from the private key, POST it to GitHub’s /app/installations/{installation_id}/access_tokens to get an installation access token, then use that token in Authorization: Bearer for API calls. Store App ID, Installation ID and private key in environment variables and refresh tokens before expiry to avoid 401s.

 

Concrete steps

 

Keep env vars: APP_ID, INSTALLATION_ID, PRIVATE_KEY. Ensure JWT iat/exp within clock skew and exp ≤10min. Exchange JWT for installation token and use that token for connector requests.

  • Validate private key PEM formatting and newlines
```javascript const jwt = require('jsonwebtoken'); const fetch = require('node-fetch'); // // create JWT const now = Math.floor(Date.now()/1000); const token = jwt.sign({iat: now, exp: now+600, iss: process.env.APP_ID}, process.env.PRIVATE_KEY, {algorithm:'RS256'}); // // exchange for installation token const res = await fetch(`https://api.github.com/app/installations/${process.env.INSTALLATION_ID}/access_tokens`, {method:'POST', headers:{Authorization:`Bearer ${token}`, Accept:'application/vnd.github+json'}}); const body = await res.json(); ```

3

Resolve GitHub API rate limit (403 or secondary rate limit) errors in OpenClaw sync jobs/GitHub connector

Short answer: detect GitHub 403/secondary-rate-limit responses in your OpenClaw sync job, read headers (Retry-After, X-RateLimit-Reset, X-RateLimit-Remaining), apply exponential backoff with jitter, switch to conditional requests (ETag/If-None-Match), prefer webhooks/incremental syncs, and use GitHub App installation tokens to raise limits. Log and surface rate-limit metadata so the runtime can delay or reschedule jobs.

 

Practical steps

 

Actions to implement in the connector/skill:

  • Read headers and honor Retry-After/X-RateLimit-Reset.
  • Backoff with jitter and capped retries; set job delay in the runtime.
  • Use ETags to avoid full fetches.
  • Prefer webhooks or incremental syncs over polling.
  • Use GitHub App tokens (installation tokens) when possible.
  • Aggregate requests and surface metrics/logs for debugging.
// Minimal retry example
async function fetchWithRateLimit(url, opts, attempt=0){
  const res = await fetch(url, opts);
  if(res.status===403 || res.status===429){
    const ra = res.headers.get('Retry-After') || (res.headers.get('X-RateLimit-Reset')? (parseInt(res.headers.get('X-RateLimit-Reset'))-Date.now()/1000):null);
    const wait = ra ? Math.max(1, parseInt(ra)) : Math.min(60, 2**attempt + Math.random());
    // schedule retry via OpenClaw job delay or setTimeout
    throw {type:'rate_limited', wait};
  }
  return res;
}

4

Required GitHub App permissions and repository scopes for OpenClaw to sync PRs, issues, labels, and manage webhooks

 

Direct answer

 

Grant the GitHub App these repository permissions: Issues (Read & Write) to sync issues and labels; Pull requests (Read & Write) to sync PRs; Contents (Read) to read refs/files; Checks / Commit statuses (Read & Write) to report status; Repository hooks (Read & Write) to install/manage webhooks; and Metadata (Read) to discover accessible repos. For OAuth/PAT fallbacks grant repo, repo:status, and admin:repo_hook.

 

Why these matter

 

  • Issues lets OpenClaw read/create/update issue bodies and labels.
  • Pull requests lets it read PRs, post comments and merge actions.
  • Contents is minimal file access needed for diffs or checks.
  • Repository hooks is necessary so the app can create and validate webhooks for event delivery.
  • Use least privilege and install only to needed repos; prefer GitHub App install over PATs for finer control.
Book a Free Consultation

Still stuck?
Copy this prompt into ChatGPT and get a clear, personalized explanation.

This prompt helps an AI assistant understand your setup and guide you through the fix step by step, without assuming technical knowledge.

AI AI Prompt


Recognized by the best

Trusted by 600+ businesses globally

From startups to enterprises and everything in between, see for yourself our incredible impact.

RapidDev was an exceptional project management organization and the best development collaborators I've had the pleasure of working with.

They do complex work on extremely fast timelines and effectively manage the testing and pre-launch process to deliver the best possible product. I'm extremely impressed with their execution ability.

Arkady
CPO, Praction
Working with Matt was comparable to having another co-founder on the team, but without the commitment or cost.

He has a strategic mindset and willing to change the scope of the project in real time based on the needs of the client. A true strategic thought partner!

Donald Muir
Co-Founder, Arc
RapidDev are 10/10, excellent communicators - the best I've ever encountered in the tech dev space.

They always go the extra mile, they genuinely care, they respond quickly, they're flexible, adaptable and their enthusiasm is amazing.

Mat Westergreen-Thorne
Co-CEO, Grantify
RapidDev is an excellent developer for custom-code solutions.

We’ve had great success since launching the platform in November 2023. In a few months, we’ve gained over 1,000 new active users. We’ve also secured several dozen bookings on the platform and seen about 70% new user month-over-month growth since the launch.

Emmanuel Brown
Co-Founder, Church Real Estate Marketplace
Matt’s dedication to executing our vision and his commitment to the project deadline were impressive. 

This was such a specific project, and Matt really delivered. We worked with a really fast turnaround, and he always delivered. The site was a perfect prop for us!

Samantha Fekete
Production Manager, Media Production Company
The pSEO strategy executed by RapidDev is clearly driving meaningful results.

Working with RapidDev has delivered measurable, year-over-year growth. Comparing the same period, clicks increased by 129%, impressions grew by 196%, and average position improved by 14.6%. Most importantly, qualified contact form submissions rose 350%, excluding spam.

Appreciation as well to Matt Graham for championing the collaboration!

Michael W. Hammond
Principal Owner, OCD Tech

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We’ll discuss your project and provide a custom quote at no cost.Â