---
title: "Push changes to GitHub"
method: POST
path: "/api/apps/{app_id}/github/sync/manual"
---

# Push changes to GitHub

`POST /api/apps/{app_id}/github/sync/manual`

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

Pushes the app's latest saved version to the connected repository.

While automatic sync is on Base44 pushes each saved version by itself, so reach for this when a push failed or when you have turned automatic sync off: it pushes either way. It commits the app's latest saved version on the main line, so it publishes saved work rather than the current chat turn, and it never pushes a branch.

<Warning>A failed push still returns HTTP 200. Read `success` and `error` instead of the status code. An app with no active connection, or with no saved version carrying a commit, comes back `success: false` with the reason in `error` rather than a 404.</Warning>

`success: true` with `commits_pushed: false` means the repository already had that commit, so there was nothing new to send.

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

## Path parameters

- `app_id` string, required — ID of the app whose GitHub sync this affects.

## Response `200`

The outcome of the push.

- GitHubPushResult — Outcome of a push to the connected repository.
  - `success` boolean, required — Whether the push succeeded.
  - `commit_hash` string, nullable — Commit pushed to the repository, or `null` when nothing was pushed.
  - `commits_pushed` boolean, required — `true` when the push moved the repository forward. `false` both when the repository already had this commit and when nothing was pushed at all.
  - `skipped` boolean, required — `true` for exactly one reason: the connection carries no GitHub App installation. Every other reason nothing was pushed comes back `false`, including no connection at all and a connection in `error` or `revoked`, so read `error` rather than this flag.
  - `error` string, nullable — Why the push didn't happen, or `null` when it succeeded. Plain text, not a code you can branch on.
  - `duration_ms` integer, nullable — How long the push took, in milliseconds. `null` when Base44 rejected the request before starting one.

## Other responses

- `401` — Missing or invalid credentials.
- `403` — You don't have access to this app, or you used a workspace API key. These endpoints take a personal API key.
- `404` — App not found.
- `422` — Validation Error

---

[API](https://skmtc.dev/idealspot/apis/base44-app-management-api.md) · [All operations](https://skmtc.dev/idealspot/apis/base44-app-management-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/idealspot/base44-app-management-api/revisions/31ef75eb64ab/schema)
