# GitCaddy API Reference
Complete technical reference for developers integrating with or using GitCaddy, a self-hosted Git repository management platform.
## Table of Contents
- [Introduction](#introduction)
- [Authentication](#authentication)
- [Personal Access Tokens](#personal-access-tokens)
- [OAuth2 Authentication](#oauth2-authentication)
- [WebAuthn (Passkeys)](#webauthn-passkeys)
- [REST API Endpoints](#rest-api-endpoints)
- [Repository APIs](#repository-apis)
- [Issue APIs](#issue-apis)
- [Pull Request APIs](#pull-request-apis)
- [Organization APIs](#organization-apis)
- [User APIs](#user-apis)
- [Package Registry APIs](#package-registry-apis)
- [Actions APIs](#actions-apis)
- [Vault APIs](#vault-apis)
- [Git Protocol](#git-protocol)
- [WebSocket APIs](#websocket-apis)
- [Frontend JavaScript APIs](#frontend-javascript-apis)
- [Core Utilities](#core-utilities)
- [DOM Manipulation](#dom-manipulation)
- [Web Components](#web-components)
- [Vue Components](#vue-components)
- [Error Codes](#error-codes)
- [Rate Limiting](#rate-limiting)
- [Webhooks](#webhooks)
- [Code Examples](#code-examples)
## Introduction
GitCaddy provides comprehensive REST APIs for repository management, collaboration tools, CI/CD workflows, package registry, and enterprise features. All API endpoints are accessible at:
```
https://your-gitcaddy-instance.com/api/v1/
```
**Base URL Format:**
```
https://{instance}/api/v1/{endpoint}
```
**Content Type:**
All requests and responses use `application/json` unless otherwise specified.
**API Versioning:**
Current stable version: `v1`
## Authentication
GitCaddy supports multiple authentication methods for API access.
### Personal Access Tokens
Personal access tokens (PATs) provide programmatic access to the GitCaddy API.
**Creating a Token:**
1. Navigate to User Settings → Applications → Manage Access Tokens
2. Click "Generate New Token"
3. Set token name and scopes
4. Copy the generated token (shown only once)
**Using Tokens:**
Include the token in the `Authorization` header:
```http
Authorization: token YOUR_ACCESS_TOKEN
```
**Example Request:**
```bash
curl -H "Authorization: token abc123def456" \
https://gitcaddy.example.com/api/v1/user
```
**Token Scopes:**
| Scope | Description |
|-------|-------------|
| `repo` | Full access to repositories |
| `repo:status` | Read-only access to repository status |
| `public_repo` | Access to public repositories only |
| `admin:org` | Full organization administration |
| `write:org` | Write access to organizations |
| `read:org` | Read-only organization access |
| `admin:public_key` | Manage public SSH keys |
| `admin:repo_hook` | Manage repository webhooks |
| `admin:org_hook` | Manage organization webhooks |
| `notification` | Access notifications |
| `user` | Full user profile access |
| `read:user` | Read-only user profile access |
| `user:email` | Access user email addresses |
| `delete_repo` | Delete repositories |
| `package` | Access package registry |
| `admin:gpg_key` | Manage GPG keys |
| `admin:application` | Manage OAuth applications |
### OAuth2 Authentication
GitCaddy supports OAuth2 for third-party application integration.
**OAuth2 Flow:**
1. **Register Application:**
- User Settings → Applications → OAuth2 Applications
- Create new OAuth2 application
- Note `client_id` and `client_secret`
2. **Authorization Request:**
```http
GET /login/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_type=code&state={state}
```
3. **Token Exchange:**
```http
POST /login/oauth/access_token
Content-Type: application/json
{
"client_id": "your_client_id",
"client_secret": "your_client_secret",
"code": "authorization_code",
"grant_type": "authorization_code",
"redirect_uri": "https://your-app.com/callback"
}
```
**Response:**
```json
{
"access_token": "gho_16C7e42F292c6912E7710c838347Ae178B4a",
"token_type": "bearer",
"scope": "repo,user"
}
```
4. **Using Access Token:**
```http
Authorization: Bearer gho_16C7e42F292c6912E7710c838347Ae178B4a
```
**Supported OAuth2 Providers:**
GitCaddy can authenticate users via external OAuth2 providers:
- GitHub
- GitLab
- Bitbucket
- Google
- Microsoft Azure AD
- Custom OpenID Connect providers
### WebAuthn (Passkeys)
GitCaddy supports WebAuthn for passwordless authentication and two-factor authentication.
**Registration API:**
```javascript
// Client-side registration
const response = await fetch('/user/settings/security/webauthn/register', {
method: 'GET',
credentials: 'include'
});
const options = await response.json();
// Create credential
const credential = await navigator.credentials.create({
publicKey: options
});
// Send credential to server
await fetch('/user/settings/security/webauthn/register', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'My Security Key',
credential: credential
})
});
```
**Authentication API:**
```javascript
// Get authentication challenge
const response = await fetch('/user/webauthn/assertion', {
method: 'GET'
});
const options = await response.json();
// Get credential
const assertion = await navigator.credentials.get({
publicKey: options
});
// Verify assertion
await fetch('/user/webauthn/assertion', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(assertion)
});
```
## REST API Endpoints
### Repository APIs
#### List User Repositories
```http
GET /api/v1/user/repos
```
**Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `page` | integer | No | Page number (default: 1) |
| `limit` | integer | No | Page size (default: 10, max: 50) |
| `type` | string | No | Filter by type: `owner`, `collaborator`, `member` |
**Response:**
```json
[
{
"id": 1,
"owner": {
"id": 1,
"login": "username",
"full_name": "User Name",
"avatar_url": "https://gitcaddy.example.com/avatars/1"
},
"name": "my-repo",
"full_name": "username/my-repo",
"description": "Repository description",
"private": false,
"fork": false,
"parent": null,
"empty": false,
"mirror": false,
"size": 1024,
"html_url": "https://gitcaddy.example.com/username/my-repo",
"ssh_url": "git@gitcaddy.example.com:username/my-repo.git",
"clone_url": "https://gitcaddy.example.com/username/my-repo.git",
"website": "",
"stars_count": 5,
"forks_count": 2,
"watchers_count": 3,
"open_issues_count": 1,
"default_branch": "main",
"archived": false,
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-15T12:30:00Z",
"permissions": {
"admin": true,
"push": true,
"pull": true
}
}
]
```
#### Create Repository
```http
POST /api/v1/user/repos
```
**Request Body:**
```json
{
"name": "new-repo",
"description": "My new repository",
"private": false,
"auto_init": true,
"gitignores": "Go",
"license": "MIT",
"readme": "Default",
"default_branch": "main"
}
```
**Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `name` | string | Yes | Repository name |
| `description` | string | No | Repository description |
| `private` | boolean | No | Create as private (default: false) |
| `auto_init` | boolean | No | Initialize with README (default: false) |
| `gitignores` | string | No | .gitignore template name |
| `license` | string | No | License template (MIT, Apache-2.0, GPL-3.0, etc.) |
| `readme` | string | No | README template |
| `default_branch` | string | No | Default branch name (default: main) |
| `trust_model` | string | No | Trust model: `default`, `collaborator`, `committer`, `collaboratorcommitter` |
**Response:** `201 Created`
```json
{
"id": 2,
"name": "new-repo",
"full_name": "username/new-repo",
"private": false,
"html_url": "https://gitcaddy.example.com/username/new-repo",
"clone_url": "https://gitcaddy.example.com/username/new-repo.git",
"created_at": "2024-01-20T10:00:00Z"
}
```
#### Get Repository
```http
GET /api/v1/repos/{owner}/{repo}
```
**Response:**
```json
{
"id": 1,
"owner": {
"id": 1,
"login": "username",
"full_name": "User Name"
},
"name": "my-repo",
"full_name": "username/my-repo",
"description": "Repository description",
"private": false,
"default_branch": "main",
"permissions": {
"admin": true,
"push": true,
"pull": true
}
}
```
#### Delete Repository
```http
DELETE /api/v1/repos/{owner}/{repo}
```
**Response:** `204 No Content`
#### List Repository Branches
```http
GET /api/v1/repos/{owner}/{repo}/branches
```
**Response:**
```json
[
{
"name": "main",
"commit": {
"id": "abc123def456",
"message": "Initial commit",
"url": "https://gitcaddy.example.com/username/my-repo/commit/abc123def456"
},
"protected": true,
"user_can_push": true,
"user_can_merge": true
}
]
```
#### Create Branch
```http
POST /api/v1/repos/{owner}/{repo}/branches
```
**Request Body:**
```json
{
"new_branch_name": "feature-branch",
"old_branch_name": "main"
}
```
#### Get Branch Protection
```http
GET /api/v1/repos/{owner}/{repo}/branch_protections/{branch}
```
**Response:**
```json
{
"branch_name": "main",
"enable_push": false,
"enable_push_whitelist": true,
"push_whitelist_usernames": ["admin"],
"push_whitelist_teams": ["core-team"],
"push_whitelist_deploy_keys": false,
"enable_merge_whitelist": true,
"merge_whitelist_usernames": ["maintainer"],
"merge_whitelist_teams": ["reviewers"],
"enable_status_check": true,
"status_check_contexts": ["ci/tests", "ci/lint"],
"required_approvals": 2,
"enable_approvals_whitelist": false,
"block_on_rejected_reviews": true,
"dismiss_stale_approvals": true,
"require_signed_commits": true,
"protected_file_patterns": "*.lock",
"unprotected_file_patterns": "docs/*"
}
```
#### List Repository Tags
```http
GET /api/v1/repos/{owner}/{repo}/tags
```
**Response:**
```json
[
{
"name": "v1.0.0",
"commit": {
"sha": "abc123def456",
"url": "https://gitcaddy.example.com/username/my-repo/commit/abc123def456"
},
"zipball_url": "https://gitcaddy.example.com/username/my-repo/archive/v1.0.0.zip",
"tarball_url": "https://gitcaddy.example.com/username/my-repo/archive/v1.0.0.tar.gz"
}
]
```
#### Get File Contents
```http
GET /api/v1/repos/{owner}/{repo}/contents/{filepath}?ref={branch}
```
**Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `ref` | string | No | Branch, tag, or commit SHA (default: default branch) |
**Response:**
```json
{
"name": "README.md",
"path": "README.md",
"sha": "abc123",
"type": "file",
"size": 1024,
"encoding": "base64",
"content": "IyBNeVJlcG8KClRoaXMgaXMgYSBSRUFETUUgZmlsZS4=",
"target": null,
"url": "https://gitcaddy.example.com/api/v1/repos/username/my-repo/contents/README.md",
"html_url": "https://gitcaddy.example.com/username/my-repo/src/branch/main/README.md",
"git_url": "https://gitcaddy.example.com/api/v1/repos/username/my-repo/git/blobs/abc123",
"download_url": "https://gitcaddy.example.com/username/my-repo/raw/branch/main/README.md"
}
```
#### Create/Update File
```http
POST /api/v1/repos/{owner}/{repo}/contents/{filepath}
```
**Request Body:**
```json
{
"content": "base64_encoded_content",
"message": "Create README.md",
"branch": "main",
"sha": "abc123def456",
"author": {
"name": "Author Name",
"email": "author@example.com"
},
"committer": {
"name": "Committer Name",
"email": "committer@example.com"
},
"dates": {
"author": "2024-01-20T10:00:00Z",
"committer": "2024-01-20T10:00:00Z"
},
"signoff": false,
"new_branch": "feature-branch"
}
```
**Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `content` | string | Yes | Base64-encoded file content |
| `message` | string | Yes | Commit message |
| `branch` | string | No | Branch name (default: default branch) |
| `sha` | string | No | Blob SHA for update (required when updating) |
| `new_branch` | string | No | Create new branch for commit |
#### Delete File
```http
DELETE /api/v1/repos/{owner}/{repo}/contents/{filepath}
```
**Request Body:**
```json
{
"message": "Delete file",
"sha": "abc123def456",
"branch": "main"
}
```
#### Fork Repository
```http
POST /api/v1/repos/{owner}/{repo}/forks
```
**Request Body:**
```json
{
"organization": "my-org",
"name": "forked-repo"
}
```
#### List Forks
```http
GET /api/v1/repos/{owner}/{repo}/forks
```
#### Mirror Repository
```http
POST /api/v1/repos/migrate
```
**Request Body:**
```json
{
"clone_addr": "https://github.com/user/repo.git",
"auth_username": "username",
"auth_password": "password_or_token",
"uid": 1,
"repo_name": "mirrored-repo",
"mirror": true,
"private": false,
"description": "Mirrored repository"
}
```
### Issue APIs
#### List Repository Issues
```http
GET /api/v1/repos/{owner}/{repo}/issues
```
**Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `state` | string | No | Filter by state: `open`, `closed`, `all` (default: open) |
| `labels` | string | No | Comma-separated label IDs or names |
| `q` | string | No | Search query |
| `type` | string | No | Filter by type: `issues`, `pulls` |
| `milestones` | string | No | Comma-separated milestone names |
| `since` | string | No | Only issues updated after this time (ISO 8601) |
| `before` | string | No | Only issues updated before this time (ISO 8601) |
| `created_by` | string | No | Filter by creator username |
| `assigned_by` | string | No | Filter by assignee username |
| `mentioned_by` | string | No | Filter by mentioned username |
| `page` | integer | No | Page number |
| `limit` | integer | No | Page size |
**Response:**
```json
[
{
"id": 1,
"url": "https://gitcaddy.example.com/api/v1/repos/username/my-repo/issues/1",
"html_url": "https://gitcaddy.example.com/username/my-repo/issues/1",
"number": 1,
"user": {
"id": 1,
"login": "username",
"full_name": "User Name"
},
"title": "Bug: Application crashes on startup",
"body": "Detailed description of the issue...",
"labels": [
{
"id": 1,
"name": "bug",
"color": "#ee0701",
"description": "Something isn't working"
}
],
"milestone": {
"id": 1,
"title": "v1.0",
"description": "First release",
"state": "open",
"due_on": "2024-12-31T23:59:59Z"
},
"assignees": [
{
"id": 2,
"login": "developer"
}
],
"state": "open",
"is_locked": false,
"comments": 3,
"created_at": "2024-01-15T10:00:00Z",
"updated_at": "2024-01-16T14:30:00Z",
"closed_at": null,
"due_date": null,
"pull_request": null
}
]
```
#### Create Issue
```http
POST /api/v1/repos/{owner}/{repo}/issues
```
**Request Body:**
```json
{
"title": "New issue title",
"body": "Issue description with **markdown** support",
"assignees": ["developer1", "developer2"],
"labels": [1, 2],
"milestone": 1,
"closed": false,
"due_date": "2024-12-31T23:59:59Z",
"ref": "main"
}
```
**Response:** `201 Created`
#### Get Issue
```http
GET /api/v1/repos/{owner}/{repo}/issues/{index}
```
#### Update Issue
```http
PATCH /api/v1/repos/{owner}/{repo}/issues/{index}
```
**Request Body:**
```json
{
"title": "Updated title",
"body": "Updated description",
"state": "closed",
"assignees": ["user1"],
"labels": [1, 3],
"milestone": 2,
"due_date": "2024-12-31T23:59:59Z",
"unset_due_date": false
}
```
#### List Issue Comments
```http
GET /api/v1/repos/{owner}/{repo}/issues/{index}/comments
```
**Response:**
```json
[
{
"id": 1,
"html_url": "https://gitcaddy.example.com/username/my-repo/issues/1#issuecomment-1",
"pull_request_url": "",
"issue_url": "https://gitcaddy.example.com/api/v1/repos/username/my-repo/issues/1",
"user": {
"id": 1,
"login": "username"
},
"original_author": "",
"original_author_id": 0,
"body": "This is a comment on the issue",
"created_at": "2024-01-15T11:00:00Z",
"updated_at": "2024-01-15T11:00:00Z"
}
]
```
#### Create Issue Comment
```http
POST /api/v1/repos/{owner}/{repo}/issues/{index}/comments
```
**Request Body:**
```json
{
"body": "Comment text with **markdown** support"
}
```
#### Edit Issue Comment
```http
PATCH /api/v1/repos/{owner}/{repo}/issues/comments/{id}
```
#### Delete Issue Comment
```http
DELETE /api/v1/repos/{owner}/{repo}/issues/comments/{id}
```
#### List Issue Labels
```http
GET /api/v1/repos/{owner}/{repo}/labels
```
**Response:**
```json
[
{
"id": 1,
"name": "bug",
"color": "#ee0701",
"description": "Something isn't working",
"url": "https://gitcaddy.example.com/api/v1/repos/username/my-repo/labels/1"
}
]
```
#### Create Label
```http
POST /api/v1/repos/{owner}/{repo}/labels
```
**Request Body:**
```json
{
"name": "enhancement",
"color": "#a2eeef",
"description": "New feature or request"
}
```
#### Track Time on Issue
```http
POST /api/v1/repos/{owner}/{repo}/issues/{index}/times
```
**Request Body:**
```json
{
"time": 3600,
"created": "2024-01-15T10:00:00Z",
"user_name": "username"
}
```
**Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `time` | integer | Yes | Time in seconds |
| `created` | string | No | Timestamp (ISO 8601) |
| `user_name` | string | No | Username (admin only) |
#### List Tracked Times
```http
GET /api/v1/repos/{owner}/{repo}/issues/{index}/times
```
### Pull Request APIs
#### List Pull Requests
```http
GET /api/v1/repos/{owner}/{repo}/pulls
```
**Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `state` | string | No | Filter by state: `open`, `closed`, `all` |
| `sort` | string | No | Sort by: `oldest`, `recentupdate`, `leastupdate`, `mostcomment`, `leastcomment`, `priority` |
| `milestone` | integer | No | Filter by milestone ID |
| `labels` | string | No | Comma-separated label IDs |
| `page` | integer | No | Page number |
| `limit` | integer | No | Page size |
**Response:**
```json
[
{
"id": 1,
"url": "https://gitcaddy.example.com/api/v1/repos/username/my-repo/pulls/1",
"number": 1,
"user": {
"id": 1,
"login": "contributor"
},
"title": "Add new feature",
"body": "This PR adds a new feature...",
"labels": [],
"milestone": null,
"assignees": [],
"state": "open",
"is_locked": false,
"comments": 2,
"html_url": "https://gitcaddy.example.com/username/my-repo/pulls/1",
"diff_url": "https://gitcaddy.example.com/username/my-repo/pulls/1.diff",
"patch_url": "https://gitcaddy.example.com/username/my-repo/pulls/1.patch",
"mergeable": true,
"merged": false,
"merged_at": null,
"merge_commit_sha": null,
"merged_by": null,
"base": {
"label": "main",
"ref": "main",
"sha": "abc123",
"repo_id": 1,
"repo": {
"id": 1,
"name": "my-repo",
"full_name": "username/my-repo"
}
},
"head": {
"label": "contributor:feature-branch",
"ref": "feature-branch",
"sha": "def456",
"repo_id": 2,
"repo": {
"id": 2,
"name": "my-repo",
"full_name": "contributor/my-repo"
}
},
"merge_base": "abc123",
"due_date": null,
"created_at": "2024-01-15T10:00:00Z",
"updated_at": "2024-01-16T14:30:00Z",
"closed_at": null
}
]
```
#### Create Pull Request
```http
POST /api/v1/repos/{owner}/{repo}/pulls
```
**Request Body:**
```json
{
"title": "Add new feature",
"body": "Detailed description of changes",
"head": "feature-branch",
"base": "main",
"assignees": ["reviewer1"],
"labels": [1],
"milestone": 1,
"due_date": "2024-12-31T23:59:59Z"
}
```
**Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `title` | string | Yes | PR title |
| `body` | string | No | PR description |
| `head` | string | Yes | Branch containing changes |
| `base` | string | Yes | Branch to merge into |
| `assignees` | array | No | Array of usernames |
| `labels` | array | No | Array of label IDs |
| `milestone` | integer | No | Milestone ID |
#### Get Pull Request
```http
GET /api/v1/repos/{owner}/{repo}/pulls/{index}
```
#### Update Pull Request
```http
PATCH /api/v1/repos/{owner}/{repo}/pulls/{index}
```
**Request Body:**
```json
{
"title": "Updated title",
"body": "Updated description",
"base": "main",
"assignees": ["reviewer1", "reviewer2"],
"labels": [1, 2],
"milestone": 1,
"state": "closed",
"due_date": "2024-12-31T23:59:59Z"
}
```
#### Merge Pull Request
```http
POST /api/v1/repos/{owner}/{repo}/pulls/{index}/merge
```
**Request Body:**
```json
{
"Do": "merge",
"MergeMessageField": "Merge pull request #1",
"MergeTitleField": "Add new feature",
"delete_branch_after_merge": true,
"force_merge": false,
"head_commit_id": "def456",
"merge_when_checks_succeed": false
}
```
**Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `Do` | string | Yes | Merge method: `merge`, `rebase`, `rebase-merge`, `squash`, `manually-merged` |
| `MergeMessageField` | string | No | Merge commit message |
| `MergeTitleField` | string | No | Merge commit title |
| `delete_branch_after_merge` | boolean | No | Delete head branch after merge |
| `force_merge` | boolean | No | Force merge even if checks fail |
| `head_commit_id` | string | No | Expected head commit SHA |
#### List PR Reviews
```http
GET /api/v1/repos/{owner}/{repo}/pulls/{index}/reviews
```
**Response:**
```json
[
{
"id": 1,
"user": {
"id": 2,
"login": "reviewer"
},
"body": "Looks good to me!",
"commit_id": "def456",
"state": "APPROVED",
"html_url": "https://gitcaddy.example.com/username/my-repo/pulls/1#pullrequestreview-1",
"submitted_at": "2024-01-16T10:00:00Z"
}
]
```
#### Create PR Review
```http
POST /api/v1/repos/{owner}/{repo}/pulls/{index}/reviews
```
**Request Body:**
```json
{
"body": "Review comment",
"event": "APPROVED",
"comments": [
{
"path": "src/main.go",
"body": "Consider refactoring this function",
"old_position": 0,
"new_position": 42
}
]
}
```
**Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `body` | string | No | Overall review comment |
| `event` | string | Yes | Review state: `APPROVED`, `REQUEST_CHANGES`, `COMMENT` |
| `comments` | array | No | Array of line comments |
#### Submit PR Review
```http
POST /api/v1/repos/{owner}/{repo}/pulls/{index}/reviews/{id}
```
#### Dismiss PR Review
```http
POST /api/v1/repos/{owner}/{repo}/pulls/{index}/reviews/{id}/dismissals
```
**Request Body:**
```json
{
"message": "Outdated review"
}
```
#### Request AI Code Review
```http
POST /api/v1/repos/{owner}/{repo}/pulls/{index}/ai-review
```
**Request Body:**
```json
{
"provider": "openai",
"model": "gpt-4"
}
```
**Response:**
```json
{
"review_id": 42,
"status": "pending",
"message": "AI review requested. Results will be posted as comments."
}
```
### Organization APIs
#### List Organizations
```http
GET /api/v1/orgs
```
**Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `page` | integer | No | Page number |
| `limit` | integer | No | Page size |
#### Get Organization
```http
GET /api/v1/orgs/{org}
```
**Response:**
```json
{
"id": 1,
"username": "my-org",
"full_name": "My Organization",
"avatar_url": "https://gitcaddy.example.com/avatars/1",
"description": "Organization description",
"website": "https://example.com",
"location": "San Francisco, CA",
"visibility": "public",
"repo_admin_change_team_access": false,
"username": "my-org"
}
```
#### Create Organization
```http
POST /api/v1/orgs
```
**Request Body:**
```json
{
"username": "new-org",
"full_name": "New Organization",
"description": "Organization description",
"website": "https://example.com",
"location": "San Francisco, CA",
"visibility": "public",
"repo_admin_change_team_access": false
}
```
**Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `username` | string | Yes | Organization username |
| `full_name` | string | No | Display name |
| `description` | string | No | Organization description |
| `website` | string | No | Website URL |
| `location` | string | No | Location |
| `visibility` | string | No | Visibility: `public`, `limited`, `private` |
#### Edit Organization
```http
PATCH /api/v1/orgs/{org}
```
#### Delete Organization
```http
DELETE /api/v1/orgs/{org}
```
#### List Organization Teams
```http
GET /api/v1/orgs/{org}/teams
```
**Response:**
```json
[
{
"id": 1,
"name": "core-team",
"description": "Core development team",
"organization": {
"id": 1,
"username": "my-org",
"full_name": "My Organization"
},
"permission": "admin",
"can_create_org_repo": true,
"includes_all_repositories": false,
"units": [
"repo.code",
"repo.issues",
"repo.pulls",
"repo.releases",
"repo.wiki"
]
}
]
```
#### Create Team
```http
POST /api/v1/orgs/{org}/teams
```
**Request Body:**
```json
{
"name": "new-team",
"description": "Team description",
"permission": "write",
"can_create_org_repo": false,
"includes_all_repositories": false,
"units": [
"repo.code",
"repo.issues",
"repo.pulls"
]
}
```
**Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `name` | string | Yes | Team name |
| `description` | string | No | Team description |
| `permission` | string | No | Permission level: `read`, `write`, `admin` |
| `units` | array | No | Repository unit permissions |
#### List Team Members
```http
GET /api/v1/teams/{id}/members
```
#### Add Team Member
```http
PUT /api/v1/teams/{id}/members/{username}
```
#### Remove Team Member
```http
DELETE /api/v1/teams/{id}/members/{username}
```
#### List Team Repositories
```http
GET /api/v1/teams/{id}/repos
```
#### Add Team Repository
```http
PUT /api/v1/teams/{id}/repos/{org}/{repo}
```
### User APIs
#### Get Authenticated User
```http
GET /api/v1/user
```
**Response:**
```json
{
"id": 1,
"login": "username",
"full_name": "User Name",
"email": "user@example.com",
"avatar_url": "https://gitcaddy.example.com/avatars/1",
"language": "en-US",
"is_admin": false,
"last_login": "2024-01-20T10:00:00Z",
"created": "2023-01-01T00:00:00Z",
"restricted": false,
"active": true,
"prohibit_login": false,
"location": "San Francisco",
"website": "https://example.com",
"description": "User bio",
"visibility": "public",
"followers_count": 10,
"following_count": 5,
"starred_repos_count": 20
}
```
#### Get User
```http
GET /api/v1/users/{username}
```
#### List User Emails
```http
GET /api/v1/user/emails
```
**Response:**
```json
[
{
"email": "user@example.com",
"verified": true,
"primary": true
},
{
"email": "alternate@example.com",
"verified": false,
"primary": false
}
]
```
#### Add Email
```http
POST /api/v1/user/emails
```
**Request Body:**
```json
{
"emails": ["new@example.com"]
}
```
#### Delete Email
```http
DELETE /api/v1/user/emails
```
**Request Body:**
```json
{
"emails": ["old@example.com"]
}
```
#### List SSH Keys
```http
GET /api/v1/user/keys
```
**Response:**
```json
[
{
"id": 1,
"key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...",
"url": "https://gitcaddy.example.com/api/v1/user/keys/1",
"title": "Work Laptop",
"fingerprint": "SHA256:abc123def456",
"created_at": "2024-01-01T00:00:00Z",
"read_only": false
}
]
```
#### Add SSH Key
```http
POST /api/v1/user/keys
```
**Request Body:**
```json
{
"title": "My Key",
"key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC...",
"read_only": false
}
```
#### Delete SSH Key
```http
DELETE /api/v1/user/keys/{id}
```
#### List GPG Keys
```http
GET /api/v1/user/gpg_keys
```
**Response:**
```json
[
{
"id": 1,
"primary_key_id": "",
"key_id": "ABC123DEF456",
"public_key": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n...",
"emails": [
{
"email": "user@example.com",
"verified": true
}
],
"subkeys": [],
"can_sign": true,
"can_encrypt_comms": true,
"can_encrypt_storage": true,
"can_certify": true,
"created_at": "2024-01-01T00:00:00Z",
"expires_at": "2025-01-01T00:00:00Z"
}
]
```
#### Add GPG Key
```http
POST /api/v1/user/gpg_keys
```
**Request Body:**
```json
{
"armored_public_key": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n..."
}
```
#### List Starred Repositories
```http
GET /api/v1/user/starred
```
#### Star Repository
```http
PUT /api/v1/user/starred/{owner}/{repo}
```
#### Unstar Repository
```http
DELETE /api/v1/user/starred/{owner}/{repo}
```
#### List Watched Repositories
```http
GET /api/v1/user/subscriptions
```
#### Watch Repository
```http
PUT /api/v1/repos/{owner}/{repo}/subscription
```
#### Unwatch Repository
```http
DELETE /api/v1/repos/{owner}/{repo}/subscription
```
### Package Registry APIs
GitCaddy supports multiple package formats with dedicated API endpoints.
#### List Packages
```http
GET /api/v1/packages/{owner}
```
**Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `type` | string | No | Package type: `npm`, `maven`, `docker`, `pypi`, `alpine`, etc. |
| `q` | string | No | Search query |
| `page` | integer | No | Page number |
| `limit` | integer | No | Page size |
**Response:**
```json
[
{
"id": 1,
"name": "my-package",
"version": "1.0.0",
"type": "npm",
"owner": {
"id": 1,
"login": "username"
},
"repository": {
"id": 1,
"name": "my-repo",
"full_name": "username/my-repo"
},
"creator": {
"id": 1,
"login": "username"
},
"html_url": "https://gitcaddy.example.com/username/-/packages/npm/my-package/1.0.0",
"created_at": "2024-01-15T10:00:00Z"
}
]
```
#### Get Package
```http
GET /api/v1/packages/{owner}/{type}/{name}/{version}
```
#### Delete Package
```http
DELETE /api/v1/packages/{owner}/{type}/{name}/{version}
```
#### NPM Package API
**Configure npm registry:**
```bash
npm config set registry https://gitcaddy.example.com/api/packages/{owner}/npm/
npm config set //gitcaddy.example.com/api/packages/{owner}/npm/:_authToken {token}
```
**Publish package:**
```bash
npm publish
```
**Install package:**
```bash
npm install @{owner}/{package}
```
#### Docker Registry API
**Login:**
```bash
docker login gitcaddy.example.com
```
**Tag and push:**
```bash
docker tag myimage gitcaddy.example.com/{owner}/{image}:{tag}
docker push gitcaddy.example.com/{owner}/{image}:{tag}
```
**Pull:**
```bash
docker pull gitcaddy.example.com/{owner}/{image}:{tag}
```
#### Maven Package API
**Configure in `pom.xml`:**
```xml