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

# Pull changes from GitHub

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

Pulls new commits from the connected repository into the app.

Call this after someone pushes to the repository, or before reading the app's code, to bring Base44 up to date. It compares the repository's head with the last commit Base44 pulled, applies the diff to the app's files, updates the app's sandbox, and records the new head. With nothing new to apply it returns `synced: false` and `already_up_to_date: true`.

<Warning>A failed pull still returns HTTP 200. Read `synced` and `error` instead of the status code. An app with no active connection comes back `synced: false` with `error: not_connected` rather than a 404.</Warning>

`error: merge_conflict` means the repository's commits and the app's own changes touch the same lines. Hand it to [Resolve GitHub sync conflicts](/api-reference/resolve-github-sync-conflicts). `sync_in_progress` means another pull, or a builder turn, holds the app right now, so retry it. On any error Base44 leaves the commit it last pulled where it was, so the next pull starts over from the same place rather than skipping the commits that failed.

This endpoint allows 20 requests per minute per caller, shared with [Resolve GitHub sync conflicts](/api-reference/resolve-github-sync-conflicts).

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

<Note>This endpoint accepts a personal API key. Workspace API keys are not authorized for it and are rejected with a 403.</Note>



## OpenAPI

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


        Pulls new commits from the connected repository into the app.


        Call this after someone pushes to the repository, or before reading the
        app's code, to bring Base44 up to date. It compares the repository's
        head with the last commit Base44 pulled, applies the diff to the app's
        files, updates the app's sandbox, and records the new head. With nothing
        new to apply it returns `synced: false` and `already_up_to_date: true`.


        <Warning>A failed pull still returns HTTP 200. Read `synced` and `error`
        instead of the status code. An app with no active connection comes back
        `synced: false` with `error: not_connected` rather than a 404.</Warning>


        `error: merge_conflict` means the repository's commits and the app's own
        changes touch the same lines. Hand it to [Resolve GitHub sync
        conflicts](/api-reference/resolve-github-sync-conflicts).
        `sync_in_progress` means another pull, or a builder turn, holds the app
        right now, so retry it. On any error Base44 leaves the commit it last
        pulled where it was, so the next pull starts over from the same place
        rather than skipping the commits that failed.


        This endpoint allows 20 requests per minute per caller, shared with
        [Resolve GitHub sync
        conflicts](/api-reference/resolve-github-sync-conflicts).


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


        <Note>This endpoint accepts a personal API key. Workspace API keys are
        not authorized for it and are rejected with a 403.</Note>
      operationId: sync_github_to_base44_api_apps__app_id__github_sync_post
      parameters:
        - name: app_id
          in: path
          required: true
          schema:
            type: string
            description: ID of the app whose GitHub sync this affects.
            title: App Id
          description: ID of the app whose GitHub sync this affects.
          example: 6820f3a4e7b91d003c45a1f2
      responses:
        '200':
          description: The outcome of the pull.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GitHubPullResult'
        '401':
          description: Missing or invalid credentials.
        '403':
          description: >-
            You don't have access to this app, or you used a workspace API key.
            These endpoints take a personal API key.
        '404':
          description: App not found.
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '429':
          description: Rate limit exceeded (20 requests per minute).
components:
  schemas:
    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: >-
            `true` when 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. `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. `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.
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    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.
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: api_key
      description: Personal API key.

````