> ## 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.

# Reconnect a GitHub repository

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

Reconnects the app to the GitHub repository it was disconnected from.

Only the app's owner can reconnect, and the workspace plan has to include the GitHub integration. There's something to reconnect only after a user disconnected the app, so check `previous_repository` in [Get GitHub connection](/api-reference/get-github-connection) first.

Base44 compares the app's history with the repository's default branch and brings whichever side is behind up to date:
- When they match, nothing moves.
- When the app has newer commits, Base44 pushes them to the repository.
- When the repository has newer commits, Base44 pulls them into the app.

When both sides have new commits, or their histories are unrelated, the reconnect is refused and the app stays disconnected. A successful reconnect also turns automatic sync back on and copies the app's open [branches](/developers/references/app-management/get-started/concepts#branches) to the repository.

Reinstalling the webhook that tells Base44 about new commits can fail without failing the reconnect, so check `webhook_active` in [Get GitHub connection](/api-reference/get-github-connection) afterwards. Check the same call before you retry a reconnect whose response you lost. One that already succeeded answers a retry with `no_previous_repository`.

A refused reconnect leaves the app disconnected, and its body is `{"error": {"code", "message", "details"}}`. Branch on `code`, whose values are listed with each error response.

A pull that fails after the reconnect is reported in `sync` rather than as an error. The repository is connected by then, so retry the pull with [Pull changes from GitHub](/api-reference/pull-changes-from-github).

<Warning>The response includes fields beyond the ones documented here. Don't rely on undocumented response fields, as they can change at any time.</Warning>



## OpenAPI

````yaml /developers/references/app-management/app-management-openapi.json post /api/apps/{app_id}/github/reconnect
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/reconnect:
    post:
      summary: Reconnect a GitHub repository
      description: >-
        <Info>This API is in beta. Endpoints, fields, and behavior may still
        change, so avoid depending on it in production.</Info>


        Reconnects the app to the GitHub repository it was disconnected from.


        Only the app's owner can reconnect, and the workspace plan has to
        include the GitHub integration. There's something to reconnect only
        after a user disconnected the app, so check `previous_repository` in
        [Get GitHub connection](/api-reference/get-github-connection) first.


        Base44 compares the app's history with the repository's default branch
        and brings whichever side is behind up to date:

        - When they match, nothing moves.

        - When the app has newer commits, Base44 pushes them to the repository.

        - When the repository has newer commits, Base44 pulls them into the app.


        When both sides have new commits, or their histories are unrelated, the
        reconnect is refused and the app stays disconnected. A successful
        reconnect also turns automatic sync back on and copies the app's open
        [branches](/developers/references/app-management/get-started/concepts#branches)
        to the repository.


        Reinstalling the webhook that tells Base44 about new commits can fail
        without failing the reconnect, so check `webhook_active` in [Get GitHub
        connection](/api-reference/get-github-connection) afterwards. Check the
        same call before you retry a reconnect whose response you lost. One that
        already succeeded answers a retry with `no_previous_repository`.


        A refused reconnect leaves the app disconnected, and its body is
        `{"error": {"code", "message", "details"}}`. Branch on `code`, whose
        values are listed with each error response.


        A pull that fails after the reconnect is reported in `sync` rather than
        as an error. The repository is connected by then, so retry the pull with
        [Pull changes from GitHub](/api-reference/pull-changes-from-github).


        <Warning>The response includes fields beyond the ones documented here.
        Don't rely on undocumented response fields, as they can change at any
        time.</Warning>
      operationId: reconnect_repository_api_apps__app_id__github_reconnect_post
      parameters:
        - name: app_id
          in: path
          required: true
          schema:
            type: string
            description: >-
              ID of the app to reconnect to the GitHub repository it was
              disconnected from.
            title: App Id
          description: >-
            ID of the app to reconnect to the GitHub repository it was
            disconnected from.
          example: 6820f3a4e7b91d003c45a1f2
      responses:
        '200':
          description: The app is connected to its repository again.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GitHubReconnectResult'
        '400':
          description: >-
            The app has nothing to reconnect to, because it's connected already,
            a user never disconnected it, or its repository was deleted on
            GitHub. The `code` is `no_previous_repository`.
        '401':
          description: Missing or invalid credentials.
        '402':
          description: >-
            The app's workspace plan doesn't include the GitHub integration. The
            `code` is `capability_required`.
        '403':
          description: >-
            You don't have access to this app, or you used a workspace API key.
            The other refusals carry a `code`:

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

            - `installation_unavailable` or `push_access_missing` when the
            Base44 GitHub App can't write to the repository any more.

            - `github_org_not_allowed` when the app's workspace doesn't approve
            the repository's GitHub organization.
        '404':
          description: >-
            App not found, or the repository no longer exists under the name it
            was connected as. Only the second carries a `code`, which is
            `repository_not_found`.
        '409':
          description: >-
            The reconnect was refused, and `code` says why:

            - `histories_diverged` when both the app and the repository have new
            commits since they last matched.

            - `unrelated_histories` when the repository's history doesn't share
            a starting point with the app's.

            - `repository_moved` when the repository was renamed or transferred.
            `details` holds the old and new names.

            - `default_branch_changed` when the repository's default branch
            changed. `details` holds both branch names.

            - `workspace_mismatch` when the app moved to a different workspace
            after it was connected.

            - `workspace_installation_inactive` when the workspace's GitHub
            installation was disconnected.

            - `app_already_processing` or `branch_turn_in_progress` when the app
            or one of its branches is busy.

            - `branch_refs_rejected` when one of the app's open branches has
            changes on GitHub that Base44 can't fast-forward.
        '502':
          description: >-
            GitHub couldn't be reached or read (`github_unavailable` or
            `history_unavailable`), or didn't accept the app's commits
            (`push_failed`). Nothing was activated, so you can retry.
components:
  schemas:
    GitHubReconnectResult:
      properties:
        direction:
          type: string
          enum:
            - none
            - base44_to_github
            - github_to_base44
          title: Direction
          description: >-
            Which side Base44 brought up to date. Either `none` (the two already
            matched), `base44_to_github` (Base44 pushed the app's newer
            commits), or `github_to_base44` (Base44 pulled the repository's
            newer commits).
          example: base44_to_github
        repo_full_name:
          type: string
          title: Repo Full Name
          description: Full repository name, as `owner/repo`.
          example: base44/lead-tracker
        repo_url:
          type: string
          title: Repo Url
          description: URL of the repository on GitHub.
          example: https://github.com/base44/lead-tracker
        base44_head:
          type: string
          title: Base44 Head
          description: The app's latest commit when the reconnect started.
          example: 4c7e1f90ab3d5628e1a0f7b24c9d8e6350a1b2c4
        github_head:
          type: string
          title: Github Head
          description: Head of the repository's default branch when the reconnect started.
          example: 9f2c1ab7d4e58036bb1f4c0a7de92b41c0d5e8a3
        sync:
          anyOf:
            - $ref: '#/components/schemas/GitHubPullResult'
            - type: 'null'
          description: >-
            Outcome of pulling the repository's newer commits into the app, or
            `null` unless `direction` is `github_to_base44`.
      type: object
      required:
        - direction
        - repo_full_name
        - repo_url
        - base44_head
        - github_head
      title: GitHubReconnectResult
      description: >-
        Result of reconnecting the app to the GitHub repository it was
        disconnected from.
    GitHubPullResult:
      properties:
        synced:
          type: boolean
          title: Synced
          description: Whether this call applied new commits to the app.
          example: true
        already_up_to_date:
          type: boolean
          title: Already Up To Date
          description: >-
            Whether the repository's head was already the last commit Base44
            pulled, so there was nothing to do.
          example: false
        commits_pulled:
          type: integer
          title: Commits Pulled
          description: >-
            How many commits `commits` holds, so commits Base44 pushed itself
            aren't counted. The value is `0` when nothing was pulled.
          example: 2
        latest_commit_hash:
          anyOf:
            - type: string
            - type: 'null'
          title: Latest Commit Hash
          description: Repository head after the pull, or `null` when nothing was pulled.
          example: 4c7e1f90ab3d5628e1a0f7b24c9d8e6350a1b2c4
        commits:
          items:
            $ref: '#/components/schemas/GitHubPulledCommit'
          type: array
          title: Commits
          description: >-
            The commits this call applied, oldest first. Commits Base44 pushed
            itself are left out, so a pull of only those comes back with an
            empty list.
          example:
            - author_email: dana@example.com
              author_name: Dana Levi
              message: Fix the lead scoring rounding
              sha: 4c7e1f90ab3d5628e1a0f7b24c9d8e6350a1b2c4
              short_sha: 4c7e1f9
              timestamp: '2026-08-15T09:08:41+00:00'
              url: >-
                https://github.com/base44/lead-tracker/commit/4c7e1f90ab3d5628e1a0f7b24c9d8e6350a1b2c4
        files_summary:
          anyOf:
            - $ref: '#/components/schemas/GitHubPulledFiles'
            - type: 'null'
          description: >-
            Change counts for the pulled commits, or `null` when nothing was
            pulled.
        error:
          anyOf:
            - type: string
            - type: 'null'
          title: Error
          description: >-
            Why the pull didn't happen, or `null` when it succeeded. One of
            `not_connected`, `no_installation`, `sync_in_progress`,
            `connection_error`, `merge_conflict`, `sandbox_sync_failed`,
            `rate_limit_exceeded`, `rate_limit_low`, `github_api_error` or
            `unexpected_error`.
          example: merge_conflict
        error_message:
          anyOf:
            - type: string
            - type: 'null'
          title: Error Message
          description: >-
            Human-readable explanation of `error`, or `null` when the pull
            succeeded.
          example: Merge conflict while applying the pulled commits
        duration_ms:
          anyOf:
            - type: integer
            - type: 'null'
          title: Duration Ms
          description: >-
            How long the pull took, in milliseconds, or `null` when Base44
            recorded no duration for it.
          example: 4120
      type: object
      required:
        - synced
        - already_up_to_date
        - commits_pulled
      title: GitHubPullResult
      description: Outcome of a pull from the connected repository.
    GitHubPulledCommit:
      properties:
        sha:
          type: string
          title: Sha
          description: Full commit SHA.
          example: 4c7e1f90ab3d5628e1a0f7b24c9d8e6350a1b2c4
        short_sha:
          type: string
          title: Short Sha
          description: Short form of the commit SHA.
          example: 4c7e1f9
        message:
          type: string
          title: Message
          description: Commit message.
          example: Fix the lead scoring rounding
        author_name:
          type: string
          title: Author Name
          description: >-
            The author's GitHub username when GitHub reports one, otherwise the
            name recorded in the commit.
          example: dana-levi
        author_email:
          anyOf:
            - type: string
            - type: 'null'
          title: Author Email
          description: >-
            Email recorded as the commit's author, or `null` when GitHub doesn't
            report one.
          example: dana@example.com
        timestamp:
          type: string
          title: Timestamp
          description: When the commit was authored, in ISO 8601.
          example: '2026-08-15T09:08:41+00:00'
        url:
          type: string
          title: Url
          description: URL of the commit on GitHub.
          example: >-
            https://github.com/base44/lead-tracker/commit/4c7e1f90ab3d5628e1a0f7b24c9d8e6350a1b2c4
      type: object
      required:
        - sha
        - short_sha
        - message
        - author_name
        - timestamp
        - url
      title: GitHubPulledCommit
      description: One commit brought in by a pull.
    GitHubPulledFiles:
      properties:
        total_files:
          type: integer
          title: Total Files
          description: Files changed across the pulled commits.
          example: 7
        files_with_content:
          type: integer
          title: Files With Content
          description: Changed files whose new content Base44 applied to the app.
          example: 6
        files_metadata_only:
          type: integer
          title: Files Metadata Only
          description: >-
            Changed files Base44 recorded without their content, because GitHub
            didn't return a usable diff for them.
          example: 1
        files_deleted:
          type: integer
          title: Files Deleted
          description: Files removed from the app by the pull.
          example: 1
        total_additions:
          type: integer
          title: Total Additions
          description: Lines added across the pulled commits.
          example: 214
        total_deletions:
          type: integer
          title: Total Deletions
          description: Lines removed across the pulled commits.
          example: 31
      type: object
      required:
        - total_files
        - files_with_content
        - files_metadata_only
        - files_deleted
        - total_additions
        - total_deletions
      title: GitHubPulledFiles
      description: How much the pulled commits changed.
  securitySchemes:
    PersonalAccessTokenAuth:
      type: http
      scheme: bearer
      description: 'Personal access token, sent as `Authorization: Bearer <token>`.'

````