# Open GoPro: an interface specification for talking to a GoPro camera

> Open GoPro is a specification repository for the interface between software and a GoPro camera, with a Python SDK, a Kotlin SDK, runnable demos in several languages and a protobuf toolchain that runs in Docker. The odd part of the workflow is a bot that adds copyright headers to your pull request before anyone reviews it.

**gopro/OpenGoPro** — An open source interface specification to communicate with a GoPro camera with accompanying demos and tutorials.

- Repository: https://github.com/gopro/OpenGoPro
- Website: https://gopro.github.io/OpenGoPro/
- Stars: 991 · Forks: 204
- Language: Kotlin
- License: NOASSERTION
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/gopro-opengopro

## A spec repository where the SDKs are only part of the story

The first line of the readme explains who it is for. This README is only for a developer who wants to modify or contribute to the repository. If you are a user, you should go to the Open GoPro GitHub Pages site for the specs and getting started information. That split matters, because the repository is easy to misjudge from the outside. It is described as an open source interface specification to communicate with a GoPro camera, with accompanying demos and tutorials, and it is structured as a small number of content types. Demos are runnable examples in various languages and frameworks, and they exist independently of the documentation, with their own contributing guide in the demos folder. Capabilities are the specifications that describe what a particular camera and firmware version can do, referenced from the BLE and HTTP specifications. Tools are utilities needed by the demos and tutorials, each with its own readme. The Python SDK lives on PyPI as open_gopro with its own documentation, and the Kotlin SDK has documentation on the project site as well.

## Capabilities are per camera and per firmware version

The design decision that makes the specification usable is that capabilities are not global. They are per camera and firmware version, which is the honest answer to the question a developer asks first: can this setting be set on my camera, and on this firmware, at all. The readme points to the BLE feature settings and camera capabilities page and to the HTTP settings section for the details. For a hardware interface where a single model year changes which commands exist, a single flat command list would send developers into firmware bug reports with the wrong expectations. The consequence for a user is that a capability you read about in the specification may not apply to the camera in your hand, and the documentation has to be read against the specific model and firmware. The specification version is separate from all of that, and the readme states the current version as 2.0.

## Demos are the documentation that actually compiles

The demos folder is described as runnable examples in various languages and frameworks, and from the point of view of the demos they are independent of the Jekyll based documentation, which is how the project site is built. The Makefile shows where the examples live, and the paths are informative. There is a Python tutorial directory with a module named tutorial_5_ble_protobuf, so the tutorial series walks through Bluetooth Low Energy control using protobuf messages, and the Python SDK directory carries a wireless camera control demo with its own generated protobuf models. The Kotlin side is a KMP SDK under demos/kotlin/kmp_sdk/wsdk, with generated proto code in its commonMain sources. The practical value of this arrangement is that a demo that no longer runs is a visible failure, in a way that a code sample in a documentation page is not. If you are evaluating the project, reading one tutorial and one SDK demo tells you more about the real shape of the interface than any amount of specification browsing.

## Protobuf generation runs inside a container

The wire format of the camera interface is defined in protobuf, and the generated code is committed into three separate places: the Python tutorial, the Python SDK and the Kotlin SDK. Generating it is a make target, and the target does not build anything locally. It runs a container first:

```bash
docker compose run --build --rm proto-build
```

The compose file defines a single service named proto-build, built from the tools/proto_build context, running under the ephemeral profile so it does not start with everything else. It mounts the protobuf directory as the input and a build directory as the output:

```yaml
services:
    proto-build:
        build:
            context: tools/proto_build
        container_name: proto-build
        profiles:
            - ephemeral
        volumes:
            - ./protobuf:/proto_in
            - ./.build/protobuf:/proto_output
```

After the container finishes, the make target clears the previously generated files and copies the new Python output into the tutorial and SDK directories, and the Kotlin output into the Kotlin SDK. Doing the generation in a container means the toolchain version is pinned by the image rather than by whatever the developer has installed, which is the only way the committed output stays consistent across machines.

## A bot edits your pull request to add a copyright header

The copyright policy is enforced in an unusual way, and it is worth knowing before you open your first pull request. All relevant source files shall contain a copyright, and this is managed by a Pre Merge Checks GitHub Action. When a pull request is opened, or updated, the action searches for missing or incorrect copyrights, adds or fixes them, and updates the branch. The effect is that your branch changes after you push it, without you doing anything, and the reviewer sees a diff that includes headers you did not write. If the automated process is not what you want, the same check can be run by hand, and the Makefile exposes it as a target:

```bash
make copyright
```

There is an escape hatch for files that should not carry a header, and it is a first line comment reading No (C) Copyright, as the readme puts it, which excludes that file from the process. The rule exists because the specification, the SDKs and the demos all carry GoPro copyright, and the enforcement keeps that uniform across a repository that takes contributions from many people. It is also the kind of policy that generates friction, and the manual target is the compromise the project offers.

## Version 2.0, a custom licence and no tagged releases

Two housekeeping facts frame any decision to build on this project. The first is versioning. The readme names the current version as 2.0, the Makefile carries the same VERSION value and passes it to the copyright tool, and the compose file header records the version and the GoPro copyright in the same way. There are no GitHub releases, so there is no tag to pin a dependency to and no release notes to read, and a consumer who needs a stable reference point has to pin a commit. The last push was on 2026-06-08, which is inside the six month window but not recent, and for a specification that tracks camera firmware behaviour that is the kind of gap worth watching. The second is the licence. The project ships a LICENSE file that GitHub cannot classify, so the terms are not obvious from the repository metadata and the file itself is the place to look. Anything you build on top of the SDKs, commercial or not, has to live with whatever that file says, and the readme does not summarise it.

## Conclusion

Open GoPro is worth adopting if you build software that drives a GoPro and want a documented interface instead of a reverse engineered one, with a Python SDK to start from and demos that show working sequences. It is the wrong choice if you only need the bundled user facing documentation, which lives on the project site rather than in the repository, or if you need a published release to pin against, since the project tags none. Before you build, read the BLE and HTTP specifications for your camera and firmware version, run make protos before regenerating any SDK code, and expect the copyright action to edit your branch when you open the pull request.

## FAQ

### What is Open GoPro?

It is an open source interface specification for communicating with a GoPro camera, with a Python SDK published as open_gopro on PyPI, a Kotlin SDK, runnable demos in several languages and tutorials, plus capability descriptions for specific cameras and firmware versions.

### Where are the camera capabilities documented?

The capabilities are separate specifications describing what a particular camera and firmware version can do. The readme points at the BLE feature settings and camera capabilities page and at the HTTP settings section of the project site.

### How do I regenerate the protobuf code?

Run the protos target in the Makefile, which calls docker compose run --build --rm proto-build and then copies the generated Python and Kotlin files into the Python tutorial, the Python SDK and the Kotlin SDK directories. A single compose service does the generation so the toolchain comes from the container image.

### What happens to my pull request when I open it?

A Pre Merge Checks GitHub Action searches for missing or incorrect copyright headers, adds or fixes them and updates your branch, so the diff includes changes you did not make. You can run the same check locally with make copyright, and a file can opt out with a No (C) Copyright comment on its first line.

## Sources

- [gopro/OpenGoPro on GitHub](https://github.com/gopro/OpenGoPro)
- [Issues](https://github.com/gopro/OpenGoPro/issues)
- [Project website](https://gopro.github.io/OpenGoPro/)
- [README](https://github.com/gopro/OpenGoPro/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/gopro-opengopro
