Skip to main content

GitHub PR API

Create pull requests programmatically via Jetty's GitHub App integration.

Endpoint

POST /api/github/pr

Base URL: https://launch.jetty.io

Authentication

Requires Clerk authentication. The request must include a valid Clerk session cookie.

Request Body

{
// Repository identification (provide ONE of these)
"owner": "jettyio", // GitHub username/org
"repo": "my-repo", // Repository name
// OR
"repositoryId": "123456789", // GitHub repository ID

// Branch configuration
"headBranch": "feature/my-changes", // REQUIRED: Branch to create
"baseBranch": "main", // Optional: Target branch (defaults to repo default)

// PR metadata
"title": "My PR Title", // REQUIRED
"body": "## Summary\n...", // REQUIRED: PR description (markdown)
"draft": false, // Optional: Create as draft PR

// File changes
"files": [ // REQUIRED: At least one file
{
"path": "src/file.ts", // REQUIRED: File path
"content": "file contents...", // REQUIRED: File content
"encoding": "utf-8" // Optional: "utf-8" or "base64" (default: utf-8)
}
]
}

Response

Success (200)

{
"success": true,
"pr": {
"number": 42,
"url": "https://github.com/owner/repo/pull/42",
"branch": "feature/my-changes"
}
}

Error Responses

CodeMeaningResolution
401Not authenticated with ClerkEnsure valid session cookie
404User, installation, repo, or branch not foundCheck GitHub App installation and repo access
400Invalid request bodyCheck required fields and file format
500Internal server errorRetry or contact support

Examples

curl

curl -X POST https://launch.jetty.io/api/github/pr \
-H "Content-Type: application/json" \
-H "Cookie: __session=your-clerk-session-token" \
-d '{
"owner": "jettyio",
"repo": "my-repo",
"headBranch": "optimize/caching",
"title": "Add caching layer",
"body": "## Summary\n\nAdds Redis caching for API responses.",
"files": [
{
"path": "src/lib/cache.ts",
"content": "// Cache implementation\nexport const cache = ...",
"encoding": "utf-8"
}
]
}'

TypeScript

const response = await fetch('/api/github/pr', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
owner: 'jettyio',
repo: 'my-repo',
headBranch: 'optimize/caching',
title: 'Add caching layer',
body: '## Summary\n\nAdds Redis caching for API responses.',
files: [
{
path: 'src/lib/cache.ts',
content: '// Cache implementation\nexport const cache = ...',
},
],
}),
});

const result = await response.json();
if (result.success) {
console.log(`PR created: ${result.pr.url}`);
}

Workflow

  1. Authentication — Request authenticated via Clerk session
  2. Authorization — Verifies user has a GitHub App installation
  3. Repository Access — Fetches repository and verifies access permissions
  4. Branch Creation — Creates a new branch from the base branch
  5. File Updates — Creates/updates files in the new branch
  6. PR Creation — Creates the pull request

Limitations

  • User must have an active GitHub App installation
  • Repository must be accessible via the user's installation
  • Branch name must be unique (fails if branch already exists)
  • Total request size limited to ~4.5MB

Security

  • All GitHub API calls use installation access tokens scoped to specific repos
  • No GitHub API keys are exposed to clients
  • Rate limiting follows GitHub's API limits
  • Users can only create PRs in repositories they've granted access to via the GitHub App

See Also