Making HTTP POST requests to GitHub Gist API with Haskell

I’m trying to create a gist programmatically using Haskell but running into issues. I’m pretty new to working with REST APIs and the HTTP libraries in Haskell so I might be missing something obvious.

Here’s what I’m attempting:

gistRequest = postRequest "https://api.github.com/gists"

createGist = simpleHTTP $ gistRequest {rqBody = urlEncodeVars 
                                      [("username", "myuser"),
                                       ("auth_token","<my_token>"),
                                       ("file_extension[mainfile]",".hs"),
                                       ("filename[mainfile]","example"),
                                       ("content[mainfile]","main = print \"Hi there!\"")]}

When I run this code, I get a 302 redirect response that points back to the original URL, but no gist gets created. The response headers look normal but something isn’t working right.

I think I might not be formatting the POST data correctly or maybe I’m missing some required fields. Has anyone successfully used Haskell to interact with the GitHub API before? What am I doing wrong with this HTTP request?

You’re hitting the GitHub Gist API like it’s a form submission, but it wants JSON data. I hit this same issue migrating old Haskell code that called REST endpoints. That 302 redirect means GitHub’s rejecting your request format and bouncing you back. Build a proper JSON payload: {“description”: “…”, “public”: true, “files”: {“filename.hs”: {“content”: “…”}}}. Drop the URL encoding completely and use Data.Aeson for your JSON. Also check that your token has the right scopes in GitHub’s developer settings.

hey, looks like u gotta update your Gist API format. github switched to needing JSON instead of url-encoded. use Aeson for your JSON and make sure to send the oauth token in the header, not in the body. that should fix the issue!

Yeah, this is super common with manual API calls. You’re spot on - GitHub wants JSON, not URL encoded data. And auth goes in headers, not the body.

Honestly though, fighting with HTTP libraries and JSON formatting sucks. I wasted hours on this exact stuff before I started automating it.

Now I just build workflows that handle all the formatting, auth, and error handling automatically. Feed in your gist content, and it deals with all the GitHub API weirdness behind the scenes.

No more wrestling with headers, JSON structure, or token management. Just pass your code and description - boom, gist created. Way cleaner than cluttering your main code with HTTP library nonsense.

I’ve automated dozens of APIs this way. Beats the hell out of memorizing every little format quirk or debugging Haskell HTTP issues.

you’re using the old http library which makes this way harder than it needs to be. try switching to http-conduit - it handles JSON way better and GitHub’s API is picky about content types. also that 302 redirect screams auth problems so definitely move your token to headers instead.

That 302 redirect often indicates authentication issues with GitHub’s API. Instead of sending credentials in the request body, update your approach to use headers for authentication. GitHub requires either a personal access token or an OAuth token for this purpose. I encountered similar issues when I first worked with their API in Haskell. Make sure to set the Authorization header correctly and format your requests as JSON instead of URL-encoded data. Using Network.HTTP.Simple or wreq is advisable, as they provide better support for JSON than the older HTTP libraries. Additionally, ensure that your token has the ‘gist’ scope enabled in your GitHub settings, as this is crucial for successful gist creation.

It’s your request format and auth method. Hit this same issue months ago building a Haskell snippet manager. GitHub’s Gist API wants JSON, not URL-encoded form data. You need a JSON object with description, public, and files - each file needs content and optionally filename. Put your auth token in the Authorization header as token <your_token>, not the request body. I switched to the req library - way cleaner for JSON requests than the older HTTP packages. Also check that your personal access token has gist permissions enabled in GitHub settings.