---
title: "GitHub image upload API: what exists and what does not"
canonical_url: "https://krowk.com/guides/github-image-upload-api"
last_updated: "2026-09-02T08:08:56.098Z"
meta:
  description: "GitHub has no public endpoint for uploading images to issues or pull requests. The four alternatives — drag and drop, committing to the repo, release assets, external hosting — and what each costs."
  "og:description": "GitHub has no public endpoint for uploading images to issues or pull requests. The four alternatives — drag and drop, committing to the repo, release assets, external hosting — and what each costs."
  "og:title": "GitHub image upload API: what exists and what does not"
---

# **GitHub has no image upload API. Here is what to do instead.**

Last updated August 27, 2026

**There is no GitHub image upload API.** Not an undocumented one, not one behind a scope you can ask for. Attaching an image to an issue or a pull request comment is a browser action: you drag the file into the comment box, or use the paperclip, and the browser posts it against your logged-in session. The REST and GraphQL APIs have no equivalent endpoint, and the host the browser flow uploads to is not a documented interface.

So the real question is what to do instead. There are four answers, and which one is right depends on whether a person or a process is doing the uploading.

## Option 1 — drag and drop, by hand

Fine when there is a human with a browser. GitHub hosts the file for as long as the comment lives, at no cost, and the image renders inline.

- **Limits.** 10 MB for images and GIFs, 25 MB for other files. Video is 10 MB on a free plan and 100 MB on a paid one.
- **What it cannot do.** Anything unattended. There is no command, so no script, no CI job and no agent in a container can reach it.

## Option 2 — commit the image to the repository

Scriptable, permanent, and versioned with the code. It is also the option people regret at about the fiftieth screenshot.

- **Works because.** The contents API takes base64, so a script can create the file and then link to its raw URL.
- **What it costs.** Every screenshot is a commit and a blob in history forever. Git does not delete, so a clone a year from now still pays for the screenshots — and the diff is full of binaries nobody can review.

## Option 3 — a release asset

The one upload endpoint GitHub does document is for release assets, and it is a real option if you already cut releases. It is a poor fit for a screenshot: assets hang off a tag rather than a pull request, and the URL is a download rather than something that renders in a comment.

## Option 4 — host it somewhere and link to it

GitHub renders an inline markdown image from any host, which is what makes this work at all. Two shapes of it:

- **Your own bucket.** S3 or R2, a public prefix and a lifecycle rule. No per-upload cost beyond storage. The setup is the part that does not happen: credentials into every agent container, a policy to write, and the link still renders as a raw blob URL — so the reviewer clicks to find out whether it was worth clicking.
- **A host built for it.** Hands back a link, renders a preview, needs no bucket policy. You are trusting somebody else with a URL, which matters most for links that end up in a repository's history.

## Where Krowk sits

Krowk is the fourth option, narrowed to one job. `krowk push screenshot.png` returns a permalink, and the block it prints for GitHub is the image inline plus a link through to a preview page carrying the repository, commit, branch and agent that produced the file. The first push needs no account.

agent shell

```
gh pr comment 412 --body "$(krowk push shot.png --destination github)"
```

What it does not do: replace the browser flow for a human with a mouse, or promise the link outlives the service. Free links expire after 24 hours; links in a claimed workspace do not expire, but they are hosted links like any other. If the screenshot has to still be readable from a clone in five years, commit it.

The client is MIT and the upload API is documented, so [the CLI](https://github.com/krowkcom/cli) is a convenience rather than a dependency — curl against the API works.

[Read the CLI reference](https://krowk.com/docs)

The reference for everything above lives in [~~the docs~~](https://krowk.com/docs#api).