- name
- github
- description
- |
- compatibility
- Requires network access and valid Maton API key
- metadata
- author
- maton
- version
- 1.0
- clawdbot
- emoji
- 🧠
- requires
- env
GitHub
Access the GitHub REST API with managed OAuth authentication. Manage repositories, issues, pull requests, commits, branches, users, and more.
Quick Start
# Get authenticated user
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/github/user')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFBase URL
https://api.maton.ai/github/{native-api-path}Maton proxies requests to api.github.com and automatically injects your OAuth token.
Authentication
All requests require the Maton API key in the Authorization header:
Authorization: Bearer $MATON_API_KEYEnvironment Variable: Set your API key as MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"Getting Your API Key
- Sign in or create an account at maton.ai
- Go to maton.ai/settings
- Copy your API key
Connection Management
Manage your GitHub OAuth connections at https://api.maton.ai.
List Connections
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections?app=github&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFCreate Connection
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'github'}).encode()
req = urllib.request.Request('https://api.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFGet Connection
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFResponse:
{
"connection": {
"connection_id": "{connection_id}",
"status": "ACTIVE",
"creation_time": "2026-02-06T03:00:43.860014Z",
"last_updated_time": "2026-02-06T03:01:06.027323Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "github",
"metadata": {}
}
}Open the returned url in a browser to complete OAuth authorization.
Delete Connection
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFSpecifying Connection
If you have multiple GitHub connections, specify which one to use with the Maton-Connection header:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/github/user')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '{connection_id}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFIf you have multiple connections, always include this header to ensure requests go to the intended account.
Security & Permissions
- Access is scoped to repositories, issues, pull requests, commits, branches, and users within the connected GitHub account.
- All write operations require explicit user approval. Before executing any create, update, or delete call, confirm the target resource and intended effect with the user.
API Reference
Users
Get Authenticated User
GET /github/userGet User by Username
GET /github/users/{username}List Users
GET /github/users?since={user_id}&per_page=30Repositories
List User Repositories
GET /github/user/repos?per_page=30&sort=updatedQuery parameters: type (all, owner, public, private, member), sort (created, updated, pushed, full_name), direction (asc, desc), per_page, page
List Organization Repositories
GET /github/orgs/{org}/repos?per_page=30Get Repository
GET /github/repos/{owner}/{repo}Create Repository (User)
POST /github/user/repos
Content-Type: application/json
{
"name": "my-new-repo",
"description": "A new repository",
"private": true,
"auto_init": true
}Create Repository (Organization)
POST /github/orgs/{org}/repos
Content-Type: application/json
{
"name": "my-new-repo",
"description": "A new repository",
"private": true
}Update Repository
PATCH /github/repos/{owner}/{repo}
Content-Type: application/json
{
"description": "Updated description",
"has_issues": true,
"has_wiki": false
}Delete Repository
DELETE /github/repos/{owner}/{repo}Repository Contents
List Contents
GET /github/repos/{owner}/{repo}/contents/{path}Get File Contents
GET /github/repos/{owner}/{repo}/contents/{path}?ref={branch}Create or Update File
PUT /github/repos/{owner}/{repo}/contents/{path}
Content-Type: application/json
{
"message": "Create new file",
"content": "SGVsbG8gV29ybGQh",
"branch": "main"
}Note: content must be Base64 encoded.
Delete File
DELETE /github/repos/{owner}/{repo}/contents/{path}
Content-Type: application/json
{
"message": "Delete file",
"sha": "{file_sha}",
"branch": "main"
}Branches
List Branches
GET /github/repos/{owner}/{repo}/branches?per_page=30Get Branch
GET /github/repos/{owner}/{repo}/branches/{branch}Rename Branch
POST /github/repos/{owner}/{repo}/branches/{branch}/rename
Content-Type: application/json
{
"new_name": "new-branch-name"
}Merge Branches
POST /github/repos/{owner}/{repo}/merges
Content-Type: application/json
{
"base": "main",
"head": "feature-branch",
"commit_message": "Merge feature branch"
}Commits
List Commits
GET /github/repos/{owner}/{repo}/commits?per_page=30Query parameters: sha (branch name or commit SHA), path (file path), author, committer, since, until, per_page, page
Get Commit
GET /github/repos/{owner}/{repo}/commits/{ref}Compare Two Commits
GET /github/repos/{owner}/{repo}/compare/{base}...{head}Issues
List Repository Issues
GET /github/repos/{owner}/{repo}/issues?state=open&per_page=30Query parameters: state (open, closed, all), labels, assignee, creator, mentioned, sort, direction, since, per_page, page
Get Issue
GET /github/repos/{owner}/{repo}/issues/{issue_number}Create Issue
POST /github/repos/{owner}/{repo}/issues
Content-Type: application/json
{
"title": "Found a bug",
"body": "Bug description here",
"labels": ["bug"],
"assignees": ["username"]
}Update Issue
PATCH /github/repos/{owner}/{repo}/issues/{issue_number}
Content-Type: application/json
{
"state": "closed",
"state_reason": "completed"
}Lock Issue
PUT /github/repos/{owner}/{repo}/issues/{issue_number}/lock
Content-Type: application/json
{
"lock_reason": "resolved"
}Unlock Issue
DELETE /github/repos/{owner}/{repo}/issues/{issue_number}/lockIssue Comments
List Issue Comments
GET /github/repos/{owner}/{repo}/issues/{issue_number}/comments?per_page=30Create Issue Comment
POST /github/repos/{owner}/{repo}/issues/{issue_number}/comments
Content-Type: application/json
{
"body": "This is a comment"
}Update Issue Comment
PATCH /github/repos/{owner}/{repo}/issues/comments/{comment_id}
Content-Type: application/json
{
"body": "Updated comment"
}Delete Issue Comment
DELETE /github/repos/{owner}/{repo}/issues/comments/{comment_id}Labels
List Labels
GET /github/repos/{owner}/{repo}/labels?per_page=30Create Label
POST /github/repos/{owner}/{repo}/labels
Content-Type: application/json
{
"name": "priority:high",
"color": "ff0000",
"description": "High priority issues"
}Milestones
List Milestones
GET /github/repos/{owner}/{repo}/milestones?state=open&per_page=30Create Milestone
POST /github/repos/{owner}/{repo}/milestones
Content-Type: application/json
{
"title": "v1.0",
"state": "open",
"description": "First release",
"due_on": "2026-03-01T00:00:00Z"
}Pull Requests
List Pull Requests
GET /github/repos/{owner}/{repo}/pulls?state=open&per_page=30Query parameters: state (open, closed, all), head, base, sort, direction, per_page, page
Get Pull Request
GET /github/repos/{owner}/{repo}/pulls/{pull_number}Create Pull Request
POST /github/repos/{owner}/{repo}/pulls
Content-Type: application/json
{
"title": "New feature",
"body": "Description of changes",
"head": "feature-branch",
"base": "main",
"draft": false
}Update Pull Request
PATCH /github/repos/{owner}/{repo}/pulls/{pull_number}
Content-Type: application/json
{
"title": "Updated title",
"state": "closed"
}List Pull Request Commits
GET /github/repos/{owner}/{repo}/pulls/{pull_number}/commits?per_page=30List Pull Request Files
GET /github/repos/{owner}/{repo}/pulls/{pull_number}/files?per_page=30Check If Merged
GET /github/repos/{owner}/{repo}/pulls/{pull_number}/mergeMerge Pull Request
PUT /github/repos/{owner}/{repo}/pulls/{pull_number}/merge
Content-Type: application/json
{
"commit_title": "Merge pull request",
"merge_method": "squash"
}Merge methods: merge, squash, rebase
Pull Request Reviews
List Reviews
GET /github/repos/{owner}/{repo}/pulls/{pull_number}/reviews?per_page=30Create Review
POST /github/repos/{owner}/{repo}/pulls/{pull_number}/reviews
Content-Type: application/json
{
"body": "Looks good!",
"event": "APPROVE"
}Events: APPROVE, REQUEST_CHANGES, COMMENT
Search
Search Repositories
GET /github/search/repositories?q={query}&per_page=30Example queries:
tetris+language:python- Repositories with "tetris" in Pythonreact+stars:>10000- Repositories with "react" and 10k+ stars
Search Issues
GET /github/search/issues?q={query}&per_page=30Example queries:
bug+is:open+is:issue- Open issues containing "bug"author:username+is:pr- Pull requests by author
Search Code
GET /github/search/code?q={query}&per_page=30Example queries:
addClass+repo:facebook/react- Search for "addClass" in a specific repofunction+extension:js- JavaScript functions
Note: Code search may timeout on broad queries.
Search Users
GET /github/search/users?q={query}&per_page=30Organizations
List User Organizations
GET /github/user/orgs?per_page=30Note: Requires read:org scope.
Get Organization
GET /github/orgs/{org}List Organization Members
GET /github/orgs/{org}/members?per_page=30Rate Limit
Get Rate Limit
GET /github/rate_limitResponse:
{
"rate": {
"limit": 5000,
"remaining": 4979,
"reset": 1707200000
},
"resources": {
"core": { "limit": 5000, "remaining": 4979 },
"search": { "limit": 30, "remaining": 28 }
}
}Pagination
GitHub uses page-based and link-based pagination:
GET /github/repos/{owner}/{repo}/issues?per_page=30&page=2Response headers include pagination links:
Link: <url>; rel="next", <url>; rel="last"
Common pagination parameters:
per_page: Results per page (max 100, default 30)page: Page number (default 1)
Some endpoints use cursor-based pagination with since parameter (e.g., listing users).
Code Examples
JavaScript
const response = await fetch(
'https://api.maton.ai/github/repos/owner/repo/issues?state=open&per_page=10',
{
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
}
}
);
const issues = await response.json();Python
import os
import requests
response = requests.get(
'https://api.maton.ai/github/repos/owner/repo/issues',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'},
params={'state': 'open', 'per_page': 10}
)
issues = response.json()Notes
- Repository names are case-insensitive but the API preserves case
- Issue numbers and PR numbers share the same sequence per repository
- Content must be Base64 encoded when creating/updating files
- Rate limits: 5000 requests/hour for authenticated users, 30 searches/minute
- Search queries may timeout on very broad patterns
- Some endpoints require specific OAuth scopes (e.g.,
read:orgfor organization operations). If you receive a scope error, contact Maton support at support@maton.ai with the specific operations/APIs you need and your use-case - IMPORTANT: When using curl commands, use
curl -gwhen URLs contain brackets to disable glob parsing - IMPORTANT: When piping curl output to
jqor other commands, environment variables like$MATON_API_KEYmay not expand correctly in some shell environments
Error Handling
| Status | Meaning |
|---|---|
| 400 | Missing GitHub connection |
| 401 | Invalid or missing Maton API key |
| 403 | Forbidden - insufficient permissions or scope |
| 404 | Resource not found |
| 408 | Request timeout (common for complex searches) |
| 422 | Validation failed |
| 429 | Rate limited |
| 4xx/5xx | Passthrough error from GitHub API |
Troubleshooting: API Key Issues
- Check that the
MATON_API_KEYenvironment variable is set:
echo $MATON_API_KEY- Verify the API key is valid by listing connections:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFTroubleshooting: Invalid App Name
- Ensure your URL path starts with
github. For example:
- Correct:
https://api.maton.ai/github/user - Incorrect:
https://api.maton.ai/api.github.com/user