curl --request POST \
--url https://app.base44.com/api/apps/{app_id}/github/link-existing \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"repo_full_name": "acme/lead-tracker"
}
'import requests
url = "https://app.base44.com/api/apps/{app_id}/github/link-existing"
payload = { "repo_full_name": "acme/lead-tracker" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({repo_full_name: 'acme/lead-tracker'})
};
fetch('https://app.base44.com/api/apps/{app_id}/github/link-existing', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.base44.com/api/apps/{app_id}/github/link-existing",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'repo_full_name' => 'acme/lead-tracker'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.base44.com/api/apps/{app_id}/github/link-existing"
payload := strings.NewReader("{\n \"repo_full_name\": \"acme/lead-tracker\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.base44.com/api/apps/{app_id}/github/link-existing")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"repo_full_name\": \"acme/lead-tracker\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/github/link-existing")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"repo_full_name\": \"acme/lead-tracker\"\n}"
response = http.request(request)
puts response.read_body{
"connection_id": "6890b1c4f2a7e3105d8a4472",
"repo_full_name": "acme/lead-tracker",
"repo_url": "https://github.com/acme/lead-tracker",
"default_branch": "main",
"last_synced_commit": "3f5d19c8cfc920e65313a0c5174e7e052d13bb2c"
}Link an existing GitHub repository
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 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 reports the app as already up to date once the import has finished.
curl --request POST \
--url https://app.base44.com/api/apps/{app_id}/github/link-existing \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"repo_full_name": "acme/lead-tracker"
}
'import requests
url = "https://app.base44.com/api/apps/{app_id}/github/link-existing"
payload = { "repo_full_name": "acme/lead-tracker" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({repo_full_name: 'acme/lead-tracker'})
};
fetch('https://app.base44.com/api/apps/{app_id}/github/link-existing', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.base44.com/api/apps/{app_id}/github/link-existing",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'repo_full_name' => 'acme/lead-tracker'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.base44.com/api/apps/{app_id}/github/link-existing"
payload := strings.NewReader("{\n \"repo_full_name\": \"acme/lead-tracker\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.base44.com/api/apps/{app_id}/github/link-existing")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"repo_full_name\": \"acme/lead-tracker\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/github/link-existing")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"repo_full_name\": \"acme/lead-tracker\"\n}"
response = http.request(request)
puts response.read_body{
"connection_id": "6890b1c4f2a7e3105d8a4472",
"repo_full_name": "acme/lead-tracker",
"repo_url": "https://github.com/acme/lead-tracker",
"default_branch": "main",
"last_synced_commit": "3f5d19c8cfc920e65313a0c5174e7e052d13bb2c"
}Authorizations
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.
Path Parameters
ID of the app to connect to a GitHub repository.
Body
Request to link the app to a repository that already holds its code.
Repository to link, as owner/repo. Its base44/config.jsonc project name must equal the app's name.
3 - 200^[A-Za-z0-9-]+/[A-Za-z0-9._-]+$"acme/lead-tracker"
Response
The connection Base44 stored for the app.
Result of linking an app to the repository that already holds its code.
ID of the connection Base44 stored for this app.
"6890b1c4f2a7e3105d8a4472"
Full repository name, as owner/repo.
"acme/lead-tracker"
URL of the repository on GitHub.
"https://github.com/acme/lead-tracker"
Branch Base44 syncs with. Always main.
"main"
Head commit of main the app was linked at.
"3f5d19c8cfc920e65313a0c5174e7e052d13bb2c"
Was this page helpful?