# How Apollo PS4's Auto-Update System Checks for New Versions via the GitHub Releases API

> Discover how Apollo PS4's auto-update checks GitHub releases API for new versions. Learn about JSON parsing, version comparison, and automatic PKG downloads for a seamless experience.

- Repository: [Damián Parrino/apollo-ps4](https://github.com/bucanero/apollo-ps4)
- Tags: internals
- Published: 2026-02-26

---

**Apollo PS4 queries the GitHub Releases API endpoint, parses the JSON response to extract the latest version tag and download URL, compares it against the compiled version string, and conditionally downloads the new PKG file to `/data/apollo-ps4.pkg`.**

The auto-update system in [bucanero/apollo-ps4](https://github.com/bucanero/apollo-ps4) provides a seamless way for users to stay current without manual intervention. By leveraging the GitHub Releases API, the application performs lightweight HTTP requests to determine if a newer build exists, then handles the entire download and installation flow through native C string parsing and libcurl integration.

## GitHub API Endpoint Configuration

The foundation of the update mechanism is a hardcoded API endpoint that points to the repository's latest release metadata.

### Defining the Update URL in saves.h

In [`include/saves.h`](https://github.com/bucanero/apollo-ps4/blob/main/include/saves.h), the developers define the GitHub API URL as a preprocessor macro:

```c
#define APOLLO_UPDATE_URL  "https://api.github.com/repos/bucanero/apollo-ps4/releases/latest"

```

This endpoint returns a JSON payload containing the release name, tag, and asset URLs. The constant is referenced throughout the update logic in [`source/settings.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/settings.c) whenever the system needs to verify the current version against the remote repository.

## Triggering the Update Check

The update sequence initiates when a user selects the *Update* menu option or when the application boots with auto-updates enabled.

### The update_callback Function

Located in [`source/settings.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/settings.c), the `update_callback(int sel)` function serves as the entry point. It first verifies that the user has enabled automatic updates via the `apollo_config.update` flag. When enabled, the function proceeds to download the release metadata and parse the version information.

## Downloading and Parsing the Release Data

The system employs a two-phase approach: first fetching the JSON payload, then extracting specific fields using lightweight string operations rather than a full JSON parser.

### HTTP Request with http_download

The `http_download` function in [`source/http.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/http.c) handles the network layer using libcurl. The settings code invokes it to fetch the release metadata into a temporary cache file:

```c
if (!http_download(APOLLO_UPDATE_URL, NULL,
                   APOLLO_LOCAL_CACHE "ver.check", 0))
    return;  // Network error or download failed

```

This stores the raw JSON response at `APOLLO_LOCAL_CACHE "ver.check"` for subsequent parsing.

### JSON Parsing via String Search

Rather than linking against a JSON library, Apollo uses `strstr` to locate specific keys within the response buffer. The logic in [`source/settings.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/settings.c) extracts two critical fields:

**Version extraction:**

```c
static const char find[] = "\"name\":\"Apollo Save Tool v";
const char* start = strstr(buffer, find);
if (!start) { free(buffer); return; }

start += strlen(find);
char version[32] = {0};
sscanf(start, "%31[^\"]", version);  // Extract until closing quote

```

**Download URL extraction:**

```c
start = strstr(end+1, "\"browser_download_url\":\"");
if (!start) { free(buffer); return; }

start += 24;  // Skip the key and quotes
char download_url[512] = {0};
sscanf(start, "%511[^\"]", download_url);

```

This approach minimizes binary size and dependencies while reliably parsing the predictable GitHub API response format.

## Version Comparison and User Prompt

Once extracted, the remote version string undergoes a case-insensitive comparison against the compile-time constant `APOLLO_VERSION`:

```c
if (strcasecmp(APOLLO_VERSION, start) == 0) {
    show_message(_("You are on the latest version"));
    free(buffer);
    return;
}

```

If `strcasecmp` returns a non-zero value, indicating a mismatch, the system presents a confirmation dialog using `show_dialog(DIALOG_TYPE_YESNO, ...)`. This ensures users explicitly consent before downloading potentially large package files.

## Downloading the Update Package

Upon user confirmation, the system initiates a second HTTP request to fetch the actual update binary. The logic determines the appropriate destination path based on directory availability:

```c
char* pkg_path = (dir_exists("/data/pkg") == SUCCESS)
                 ? "/data/pkg/apollo-ps4.pkg"
                 : "/data/apollo-ps4.pkg";

if (http_download(start, NULL, pkg_path, 1))
    show_message(_("Update downloaded to %s"), pkg_path);

```

The final parameter `1` passed to `http_download` enables the progress bar visualization, providing user feedback during the potentially lengthy download of the PKG file.

## Summary

Apollo PS4's auto-update system demonstrates an efficient, minimal-dependency approach to software distribution:

- **Endpoint Configuration**: The GitHub Releases API URL is defined as `APOLLO_UPDATE_URL` in [`include/saves.h`](https://github.com/bucanero/apollo-ps4/blob/main/include/saves.h)
- **Network Layer**: `http_download` in [`source/http.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/http.c) uses libcurl to fetch JSON metadata and binary assets
- **Parsing Strategy**: [`source/settings.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/settings.c) employs `strstr` and `sscanf` for lightweight JSON extraction without external libraries
- **Version Logic**: Case-insensitive comparison via `strcasecmp` against the compiled `APOLLO_VERSION` constant
- **Delivery**: Automatic path selection between `/data/pkg/` and `/data/` for the final PKG download

## Frequently Asked Questions

### What GitHub API endpoint does Apollo PS4 use for update checks?

Apollo PS4 queries `https://api.github.com/repos/bucanero/apollo-ps4/releases/latest` as defined by the `APOLLO_UPDATE_URL` macro in [`include/saves.h`](https://github.com/bucanero/apollo-ps4/blob/main/include/saves.h). This endpoint returns the latest release metadata including version names and asset download URLs.

### How does Apollo PS4 parse the GitHub API JSON without a JSON library?

The application uses standard C string functions rather than a JSON parser. It calls `strstr(buffer, "\"name\":\"Apollo Save Tool v")` to locate the version field and `strstr` again to find `"browser_download_url":"`, then uses `sscanf` to extract the quoted string values. This approach keeps the binary size small and avoids external dependencies.

### Where does Apollo PS4 save the downloaded update file?

The system checks for the existence of `/data/pkg/` first. If that directory exists, it saves the update to `/data/pkg/apollo-ps4.pkg`; otherwise, it falls back to `/data/apollo-ps4.pkg`. This logic is implemented in the `update_callback` function within [`source/settings.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/settings.c).

### Can the auto-update check be disabled in Apollo PS4?

Yes, the update check respects the `apollo_config.update` configuration flag. Users can disable automatic updates through the settings menu, which prevents `update_callback` from executing the HTTP request to the GitHub API when the application starts or when the update menu is accessed.