> ## Documentation Index
> Fetch the complete documentation index at: https://docs.base44.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Link an existing GitHub repository

> <Info>This API is in beta. Endpoints, fields, and behavior may still change, so avoid depending on it in production.</Info>

Connects an app created with the Base44 CLI to the GitHub repository that already holds its code. Base44 adopts the repository as it is, without creating one or pushing code to it.

The repository's default branch must be `main`, and its `base44/config.jsonc` must name this app. From then on the repository is where the app's code lives. Entities, agents, and functions you deployed with the CLI are replaced by their versions in the repository.

Before the call can succeed, the app's owner needs:

- Their GitHub account connected to Base44. This is done once, in Base44.
- The Base44 GitHub App installed on the repository with write access.

When either is missing, send the user to the link in the error's details, `connect_url` or `install_url`, then repeat the same call. A refused call changes nothing. If a response is lost, check [Get GitHub connection](/api-reference/get-github-connection) before retrying, because a repeat after a successful link is refused.

Base44 imports the repository's code in the background after the call returns. [Pull changes from GitHub](/api-reference/pull-changes-from-github) reports the app as already up to date once the import has finished.



## OpenAPI

````yaml /developers/references/app-management/app-management-openapi.json post /api/apps/{app_id}/github/link-existing
openapi: 3.1.0
info:
  title: Base44 App Management API
  version: 1.0.0
servers:
  - url: https://app.base44.com
security:
  - PersonalAccessTokenAuth: []
paths:
  /api/apps/{app_id}/github/link-existing:
    post:
      summary: Link an existing GitHub repository
      description: >-
        <Info>This API is in beta. Endpoints, fields, and behavior may still
        change, so avoid depending on it in production.</Info>


        Connects an app created with the Base44 CLI to the GitHub repository
        that already holds its code. Base44 adopts the repository as it is,
        without creating one or pushing code to it.


        The repository's default branch must be `main`, and its
        `base44/config.jsonc` must name this app. From then on the repository is
        where the app's code lives. Entities, agents, and functions you deployed
        with the CLI are replaced by their versions in the repository.


        Before the call can succeed, the app's owner needs:


        - Their GitHub account connected to Base44. This is done once, in
        Base44.

        - The Base44 GitHub App installed on the repository with write access.


        When either is missing, send the user to the link in the error's
        details, `connect_url` or `install_url`, then repeat the same call. A
        refused call changes nothing. If a response is lost, check [Get GitHub
        connection](/api-reference/get-github-connection) before retrying,
        because a repeat after a successful link is refused.


        Base44 imports the repository's code in the background after the call
        returns. [Pull changes from
        GitHub](/api-reference/pull-changes-from-github) reports the app as
        already up to date once the import has finished.
      operationId: link_existing_repo_api_apps__app_id__github_link_existing_post
      parameters:
        - name: app_id
          in: path
          required: true
          schema:
            type: string
            description: ID of the app to connect to a GitHub repository.
            title: App Id
          description: ID of the app to connect to a GitHub repository.
          example: 6820f3a4e7b91d003c45a1f2
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LinkExistingRepoRequest'
      responses:
        '200':
          description: The connection Base44 stored for the app.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LinkedRepositoryResponse'
              example:
                connection_id: 6890b1c4f2a7e3105d8a4472
                repo_full_name: acme/lead-tracker
                repo_url: https://github.com/acme/lead-tracker
                default_branch: main
                last_synced_commit: 3f5d19c8cfc920e65313a0c5174e7e052d13bb2c
        '401':
          description: Missing or invalid credentials.
        '403':
          description: >-
            The call was refused before anything changed. The `error.code` says
            why.


            - `owner_required` means you aren't the app's owner.

            - `github_not_connected` means your GitHub account isn't connected
            to Base44. `details.connect_url` is the Base44 page where you
            connect it.

            - `installation_unavailable` means Base44 can't reach the repository
            through your GitHub account, usually because the Base44 GitHub App
            isn't installed on it. `details.install_url` is where to install it
            or add the repository.

            - `push_access_missing` means the Base44 GitHub App is installed
            without write access. `details.install_url` is where to change that.

            - `repository_not_accessible` means your GitHub account can't push
            to the repository, or GitHub refused it access, for example because
            the organization requires SSO.

            - `github_org_not_allowed` means the app's workspace doesn't allow
            this GitHub organization.

            - `workspace_role_required` means your workspace role can't add this
            GitHub organization.

            - `webhook_permission_missing` means the Base44 GitHub App can't add
            webhooks to the repository.


            You also get this when you used a workspace API key. This endpoint
            takes a personal access token.
        '404':
          description: App not found.
        '409':
          description: >-
            The repository or the app isn't in a state to link. The `error.code`
            says why.


            - `already_managed` means the app's code is already managed in
            Base44.

            - `app_already_processing` means the app is busy with another GitHub
            operation. Try again shortly.

            - `default_branch_not_main` means the repository's default branch
            isn't `main`.

            - `config_not_found` means the repository has no readable
            `base44/config.jsonc` with a project name.

            - `name_mismatch` means the project name in `base44/config.jsonc`
            isn't this app's name.

            - `repository_already_linked` means the repository is already
            connected to a Base44 app.
        '422':
          description: >-
            `repo_full_name` isn't in `owner/repo` form, or GitHub refused to
            add the repository's webhook with `webhook_creation_refused`, for
            example because the repository has too many webhooks.
        '429':
          description: >-
            Rate limit exceeded. The base limit is 10 requests per minute. See
            [Rate
            limits](/developers/references/apps-api/get-started/rate-limits) for
            the multiplier your plan gets. GitHub limiting Base44's requests
            also lands here, with `github_rate_limited`. Nothing was changed.
            Wait for the `Retry-After` header's number of seconds before
            retrying.
        '502':
          description: >-
            GitHub couldn't be reached, with `github_unavailable`, or didn't
            accept the repository's webhook, with `webhook_creation_failed`.
            Nothing was changed.
      security:
        - PersonalAccessTokenAuth:
            - full_access
components:
  schemas:
    LinkExistingRepoRequest:
      properties:
        repo_full_name:
          type: string
          maxLength: 200
          minLength: 3
          pattern: ^[A-Za-z0-9-]+/[A-Za-z0-9._-]+$
          title: Repo Full Name
          description: >-
            Repository to link, as `owner/repo`. Its `base44/config.jsonc`
            project name must equal the app's name.
          example: acme/lead-tracker
      type: object
      required:
        - repo_full_name
      title: LinkExistingRepoRequest
      description: Request to link the app to a repository that already holds its code.
    LinkedRepositoryResponse:
      properties:
        connection_id:
          type: string
          title: Connection Id
          description: ID of the connection Base44 stored for this app.
          example: 6890b1c4f2a7e3105d8a4472
        repo_full_name:
          type: string
          title: Repo Full Name
          description: Full repository name, as `owner/repo`.
          example: acme/lead-tracker
        repo_url:
          type: string
          title: Repo Url
          description: URL of the repository on GitHub.
          example: https://github.com/acme/lead-tracker
        default_branch:
          type: string
          title: Default Branch
          description: Branch Base44 syncs with. Always `main`.
          example: main
        last_synced_commit:
          type: string
          title: Last Synced Commit
          description: Head commit of `main` the app was linked at.
          example: 3f5d19c8cfc920e65313a0c5174e7e052d13bb2c
      type: object
      required:
        - connection_id
        - repo_full_name
        - repo_url
        - default_branch
        - last_synced_commit
      title: LinkedRepositoryResponse
      description: Result of linking an app to the repository that already holds its code.
  securitySchemes:
    PersonalAccessTokenAuth:
      type: http
      scheme: bearer
      description: >-
        Personal access token, sent as `Authorization: Bearer <token>`. Each
        operation lists the permission it needs: `read_only` or `full_access`. A
        full-access token can call every operation. A read-only token can call
        only the operations that list `read_only`; anything else returns 403
        `read_only_credential_route_not_allowed`.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.