Gogs — API Surface#

API types#

Gogs exposes four distinct surfaces: a REST HTTP API (versioned at /api/v1), a Web UI (HTML pages served over HTTP), a Git protocol layer (HTTP smart protocol + SSH), and a CLI (for operators/server management). There is no gRPC or WebSocket API.


REST/HTTP API#

  • Router: gopkg.in/macaron.v1 — same router instance used by the web UI

  • Route registration: apiv1.RegisterRoutes(m *macaron.Macaron) called from cmd/gogs/web.go:636. All API routes are defined inside internal/route/api/v1/api.go under the /api/v1 group. Route definitions and handler functions live in separate files named by resource (e.g., repo_issue.go, repo_branch.go).

  • Middleware chain:

    1. Outer Macaron middleware (session, CSRF, context.Contexter) — inherited from parent group
    2. context.APIContexter() — builds *context.APIContext (wraps *context.Context, adds c.Org, c.Repo.AccessMode)
    3. Per-route auth guards: reqToken(), reqBasicAuth(), reqAdmin(), reqRepoWriter(), reqRepoAdmin(), reqRepoOwner()
    4. repoAssignment() — resolves :username/:reponame URL params, loads repo, checks read access
    5. orgAssignment() — resolves :orgname/:teamid URL params
  • Authentication:

    • Access token: reqToken() checks c.IsTokenAuth (token passed via Authorization: token <sha1> or query param)
    • HTTP Basic: reqBasicAuth() checks c.IsBasicAuth
    • Site admin: reqAdmin() checks c.User.IsAdmin
    • No OAuth2 server (Gogs can use GitHub OAuth as login provider but does not act as an OAuth2 server)
    • Token creation requires Basic Auth (/users/:username/tokens guarded by reqBasicAuth())
  • Key endpoints (all prefixed /api/v1):

    CategoryMethodPathDescription
    MiscPOST/markdownRender Markdown to HTML
    MiscPOST/markdown/rawRender raw Markdown
    UsersGET/users/searchSearch users
    UsersGET/users/:usernameGet user profile
    UsersGET/POST/users/:username/tokensList / create access tokens (requires Basic Auth)
    UsersGET/users/:username/keysList public keys
    UsersGET/userGet authenticated user
    UsersGET/POST/DELETE/user/emailsManage emails
    UsersGET/PUT/DELETE/user/following/:usernameFollow / unfollow
    UsersGET/POST/user/keysList / create SSH keys
    UsersGET/user/issuesList authenticated user’s issues
    ReposGET/users/:username/reposList user repositories
    ReposGET/orgs/:org/reposList org repositories
    ReposGET/POST/user/reposList / create repos for auth user
    ReposPOST/org/:org/reposCreate org repository
    ReposGET/repos/searchSearch repositories
    ReposGET/repos/:username/:reponameGet repository info
    ReposDELETE/repos/:username/:reponameDelete repository
    ReposPOST/repos/migrateMigrate external repository
    ReposGET/repos/:u/:r/releasesList releases
    ReposGET/POST/repos/:u/:r/hooksList / create webhooks
    ReposPATCH/DELETE/repos/:u/:r/hooks/:idEdit / delete webhook
    ReposGET/PUT/DELETE/repos/:u/:r/collaborators/:cManage collaborators
    ReposGET/repos/:u/:r/raw/*Get raw file content
    ReposGET/PUT/repos/:u/:r/contents/*Get / create/update file contents
    ReposGET/repos/:u/:r/archive/*Download archive (zip/tar.gz)
    ReposGET/repos/:u/:r/git/trees/:shaGet git tree
    ReposGET/repos/:u/:r/git/blobs/:shaGet git blob
    ReposGET/repos/:u/:r/forksList forks
    ReposGET/repos/:u/:r/tagsList tags
    ReposGET/repos/:u/:r/branchesList branches
    ReposGET/repos/:u/:r/branches/*Get single branch
    ReposGET/repos/:u/:r/commits/:shaGet single commit
    ReposGET/repos/:u/:r/commitsList all commits
    ReposGET/POST/repos/:u/:r/keysList / create deploy keys
    IssuesGET/POST/repos/:u/:r/issuesList / create issues
    IssuesGET/PATCH/repos/:u/:r/issues/:indexGet / edit issue
    IssuesGET/POST/repos/:u/:r/issues/:index/commentsList / create comments
    IssuesPATCH/DELETE/repos/:u/:r/issues/comments/:idEdit / delete comment
    IssuesGET/POST/PUT/DELETE/repos/:u/:r/issues/:index/labelsManage issue labels
    LabelsGET/POST/repos/:u/:r/labelsList / create labels
    LabelsPATCH/DELETE/repos/:u/:r/labels/:idEdit / delete label
    MilestonesGET/POST/repos/:u/:r/milestonesList / create milestones
    MilestonesPATCH/DELETE/repos/:u/:r/milestones/:idEdit / delete milestone
    Repos (misc)PATCH/repos/:u/:r/issue-trackerEdit issue tracker settings
    Repos (misc)PATCH/repos/:u/:r/wikiEdit wiki settings
    Repos (misc)POST/repos/:u/:r/mirror-syncTrigger mirror sync
    Repos (misc)GET/repos/:u/:r/editorconfig/:filenameGet EditorConfig
    OrgsGET/users/:username/orgsList user orgs
    OrgsGET/POST/user/orgsList / create orgs for auth user
    OrgsGET/PATCH/orgs/:orgnameGet / edit org
    OrgsGET/orgs/:orgname/teamsList org teams
    AdminPOST/admin/usersCreate user (admin only)
    AdminPATCH/DELETE/admin/users/:usernameEdit / delete user
    AdminPOST/admin/users/:username/keysAdd public key for user
    AdminPOST/admin/users/:username/orgsCreate org for user
    AdminPOST/admin/users/:username/reposCreate repo for user
    AdminPOST/admin/orgs/:orgname/teamsCreate org team
    AdminGET/admin/teams/:teamid/membersList team members
    AdminPUT/DELETE/admin/teams/:teamid/members/:usernameAdd / remove team member
    AdminPUT/DELETE/admin/teams/:teamid/repos/:reponameAdd / remove team repository
  • API compatibility: Gogs deliberately mirrors the Gitea/GitHub API v3 surface for the core resources (users, repos, issues, webhooks). This enables tooling that targets GitHub’s API to work with Gogs with minimal changes. There is no formal versioning strategy beyond /v1 in the path; no deprecation headers or changelog tracking is visible.


Git protocol API#

Git HTTP smart protocol#

  • Routes: /:username/:reponame/* (GET, POST, OPTIONS), registered outside the session/CSRF middleware group in cmd/gogs/web.go:671
  • Middleware: repo.HTTPContexter(repo.NewStore()) — authenticates HTTP Git requests (Basic Auth or token), loads repo, checks permissions
  • Handler: repo.HTTP — proxies the authenticated request to the system git http-backend subprocess via os/exec
  • Go-Get support: context.ServeGoGet() middleware on the same group handles ?go-get=1 requests for go get

Git LFS API#

  • Routes: /:username/:reponame/info/lfs/... (Git LFS Batch + Basic APIs)
  • Spec: Implements Git LFS v1.0 protocol
  • Endpoints:
    • POST /objects/batch — batch object download/upload requests
    • GET /objects/basic/:oid — download single LFS object
    • PUT /objects/basic/:oid — upload single LFS object
    • POST /objects/basic/verify — verify uploaded object
  • Auth: HTTP Basic Auth or access token; users with 2FA are blocked from LFS via username/password
  • Storage backends: Local filesystem only (lfsx.StorageLocal); config-driven via conf.LFS.Storage
  • Registration: lfs.RegisterRoutes(m.Router) in cmd/gogs/web.go:668

Git SSH protocol#

  • Not HTTP-based — handled by internal/ssh (a built-in SSH server listening on a separate port)
  • Flow: SSH connection → public key lookup in database → exec gogs serv <key_id> subprocess → permission check → exec git-receive-pack / git-upload-pack
  • No Go API surface — the SSH protocol boundary is at the OS process level

Web UI#

  • Router: Macaron with full middleware stack (session, CSRF, i18n, cache, captcha, toolbox)

  • Auth guards: reqSignIn (requires login), ignSignIn (optional login — required if AUTH_REQUIRED is on), reqSignOut (login page redirect), reqAdmin, reqRepoAdmin, reqRepoWriter

  • Form binding: binding.BindIgnErr — Macaron’s form binding with silent validation errors

  • Key route groups:

    • / — home feed (requires ignSignIn)
    • /explore/repos, /explore/users, /explore/organizations — public discovery
    • /install — first-run installer
    • /user/login, /user/sign_up, /user/reset_password — auth flows
    • /user/settings/... — profile, avatar, emails, password, SSH keys, 2FA, applications (tokens), repos, orgs
    • /admin/... — admin dashboard, users, orgs, repos, auth sources, notices
    • /org/... — organization management, teams
    • /repo/create, /repo/migrate, /repo/fork/:repoid — repo creation
    • /:username/:reponame/... — repo views, issues, PRs, releases, wiki, settings, webhooks, branches, commits, diffs, editor, download
  • Webhook types supported: gogs (generic HTTP POST), Slack, Discord, Dingtalk


Internal API#

  • GET /-/metrics — Prometheus metrics endpoint (guarded by app.MetricsFilter())
  • POST /-/api/sanitize_ipynb — Sanitizes a Jupyter Notebook JSON payload (strips unsafe HTML before rendering)

CLI#

  • Framework: github.com/urfave/cli/v3

  • Command structure:

    CommandSubcommandsPurpose
    gogs webStart the web server (primary command)
    gogs servSSH shell entry point (called by built-in SSH server per connection)
    gogs hookpre-receive, update, post-receiveGit hook entry points (called by git)
    gogs admincreate-user, delete-inactivate-users, delete-repository-archives, delete-missing-repositories, git-gc-repos, rewrite-authorized-keys, sync-repository-hooks, reinit-missing-repositoriesOperational maintenance tasks
    gogs importImport repositories from a local path
    gogs backupBackup Gogs data to a zip archive
    gogs restoreRestore Gogs data from a backup archive
  • Flag patterns: Global --config / -c flag shared across all subcommands via configFromLineage() (walks cli.Command.Lineage() because urfave/cli v3 doesn’t automatically propagate parent flags to subcommands). Each subcommand defines its own flags. No environment variable binding.

  • gogs serv and gogs hook are not operator-facing — they are called internally by the SSH server and the git process respectively. They perform access control and webhook delivery trigger respectively.


Plugin / Extension system#

Gogs has no formal plugin system. Extension points are:

  1. Auth providers (internal/auth/{github,ldap,pam,smtp}) — new providers can be added by implementing the auth provider interface, but this requires a source code change and recompilation, not runtime loading.
  2. Webhook targets — operators can configure any HTTP endpoint as a webhook receiver; the supported sender types (gogs, Slack, Discord, Dingtalk) are hardcoded.
  3. Git hooks — operators can configure server-side git hooks via the web UI (/settings/hooks/git) if the feature is enabled. These are arbitrary shell scripts executed by git, not Go code.
  4. Custom templates and static files — the custom/ directory can override any bundled template or static asset. This is a filesystem-level customization, not a Go API.