Skip to content

Instantly share code, notes, and snippets.

@btoone
Last active December 8, 2024 05:16
Show Gist options
  • Save btoone/2288960 to your computer and use it in GitHub Desktop.
Save btoone/2288960 to your computer and use it in GitHub Desktop.
A curl tutorial using GitHub's API

Introduction

An introduction to curl using GitHub's API.

The Basics

Makes a basic GET request to the specifed URI

curl https://api.github.com/users/caspyin

Includes HTTP-Header information in the output

curl --include https://api.github.com/users/caspyin

Pass user credential to basic auth to access protected resources like a users starred gists, or private info associated with their profile

curl --user "caspyin:PASSWD" https://api.github.com/gists/starred
curl --user "caspyin:PASSWD" https://api.github.com/users/caspyin

Passing just the username without the colon (:) will cause you to be prompted for your account password. This avoids having your password in your command line history

curl --user "caspyin" https://api.github.com/users/caspyin

POST

Use the --request (-X) flag along with --data (-d) to POST data

curl --user "caspyin" --request POST --data '{"description":"Created via API","public":"true","files":{"file1.txt":{"content":"Demo"}}' https://api.github.com/gists

curl --user "caspyin" -X POST --data '{"description":"Created via API","public":"true","files":{"file1.txt":{"content":"Demo"}}' https://api.github.com/gists

Of course --data implies POST so you don't have to also specify the --request flag

curl --user "caspyin" --data '{"description":"Created via API","public":"true","files":{"file1.txt":{"content":"Demo"}}' https://api.github.com/gists

Here is an example that uses the old GitHub API (v2). You can use multiple --data flags

curl --data "login=caspyin" --data "token=TOKEN" https://github.com/api/v2/json/user/show/caspyin

The post data gets combined into one so you can also just combine them yourself into a single --data flag

curl --data "login=caspyin&token=TOKEN" https://github.com/api/v2/json/user/show/caspyin

You can tell curl to read from a file (@) to POST data

curl --user "caspyin" --data @data.txt https://api.github.com/gists 

Or it can read from STDIN (@-)

curl --user "caspyin" --data @- https://api.github.com/gists
{
  "description":"Test",
  "public":false,
  "files": {
    "file1.txt": {
      "content":"Demo"
    }
  }
}
end with ctrl+d

Headers

Often when POSTing data you'll need to add headers for things like auth tokens or setting the content type. You can set a header using -H.

curl -H "Content-Type: application/json" -H "authToken: 349ab29a-xtab-423b-a5hc-5623bc39b8c8" --data '{}' https://api.example.com/endpoint

Dealing with HTTPS

If an API doens't have an SSL cert but is using HTTPS you can tell curl to ignore the security by using --insecure. Be warned this is a very "insecure" thing to do and is only listed here for "educational purposes".

curl --insecure https://api.example.com/endpoint

For my own reference mostly, here is where I first learned about using --insecure rvm/rvm#1684

OAuth

The first thing to know is that your API Token (found in https://github.com/settings/admin) is not the same token used by OAuth. They are different tokens and you will need to generate an OAuth token to be authorized.

Follow the API's instructions at http://developer.github.com/v3/oauth/ under the sections "Non-Web Application Flow" and "Create a new authorization" to become authorized.

Note: Use Basic Auth once to create an OAuth2 token http://developer.github.com/v3/oauth/#oauth-authorizations-api

curl https://api.github.com/authorizations \
--user "caspyin" \
--data '{"scopes":["gist"],"note":"Demo"}'

This will prompt you for your GitHub password and return your OAuth token in the response. It will also create a new Authorized application in your account settings https://github.com/settings/applications

Now that you have the OAuth token there are two ways to use the token to make requests that require authentication (replace "OAUTH-TOKEN" with your actual token)

curl https://api.github.com/gists/starred?access_token=OAUTH-TOKEN
curl -H "Authorization: token OAUTH-TOKEN" https://api.github.com/gists/starred

List the authorizations you already have

curl --user "caspyin" https://api.github.com/authorizations

Resources

@btoone
Copy link
Author

btoone commented Feb 23, 2017

It seems this has been useful over the years to various people. If you would like to contribute any changes to this gist, please fork and then ping me here in the comments to review.

@pwsouth
Copy link

pwsouth commented May 5, 2017

@suntong
Copy link

suntong commented Aug 14, 2017

@caspyin, thanks for the great post. How can you send base64 encoded content?

I tried,

curl -H 'Accept: application/vnd.github.VERSION.base64' --data @data.txt https://api.github.com/gists

But the content is still base64 encoded:
https://gist.github.com/anonymous/c79cbfcf466af02eb08dc9ad6f26b587

Here is my test data.txt:

{
  "description": "the description for this gist",
  "public": true,
  "files": {
    "file1.txt": {
      "content": "aG9zdEBtYWlsLmNvbTpwYXNzd29yZAo="
    }
  }
}

Thx.

@suntong
Copy link

suntong commented Aug 14, 2017

I figured it out -- base64 encoding is only supported for download, not upload.

So to post any arbitrary string or file, check out

jsonfiddle

Usage
https://github.com/go-jsonfile/jsonfiddle#usage-1

jsonfiddle esc will escape any arbitrary string so as to embed it as content of json string. This seems useless at first, but it actually allows you to embed any arbitrary file into GitHub Gists JSON API, so as to post any arbitrary file onto GitHub Gist:

echo '{"description":"SmartyStreets API Demo","public":true,"files":{"SmartyStreets.json":{"content":'"`jsonfiddle fmt -i test/SmartyStreets.json | jsonfiddle esc -i`"'}}}' | curl --data @- https://api.github.com/gists

This will give you
https://gist.github.com/anonymous/1423d4768dd9b88262ca513626e68d8e

By "arbitrary file" I do mean arbitrary file. Check this out:
https://gist.github.com/anonymous/a51798ce99ff59d8d4ba536cbf4b6996

This is why jsonfiddle esc is a command on its own, instead of being part of functionalities of jsonfiddle fmt or jsonfiddle sort.

@aman0446
Copy link

I'm trying to access my company's github repository(github enterprise). command i'm using is
curl --user "name:pwd" "https://github."company name".com/{owner}/repo" , but i'm getting "Not found error" .
When i login through the browser with the same credentials, it is going through.
i was reading through " OAuth and PAT(Personal Access tokens). Couldn't get to working. Can someone walk me through the steps if you have already done it?

@gmilos
Copy link

gmilos commented Sep 1, 2017

@aman0446 you need something like this:

curl -H "Authorization: token PAT-TOKEN" https://github.COMPANY_NAME.com/api/v3/users/USER/repos

@rpbaptist
Copy link

rpbaptist commented Dec 12, 2017

For OTP (2FA) you will have to send this header along:

curl -H "X-GitHub-OTP: 123456"

@ttpro1995
Copy link

In

curl --user "ttpro1995:MY_OWN_PASSWORD" --data '{"description":"Created via API","public":"false","files":{"file1.txt":{"content":"Demo"}}' https://api.github.com/gists
How can I replace password with something else (API key )?

@testqazqwe
Copy link

create a github repo webhook with curl:

curl -v --header "Authorization: token 123_generated_token" -X POST -d '{"active": true, "events": ["push"], "config": {"url": "https://service_url", "content_type": "json"}}' https://api.github.com/repos/OWNER/REPONAME/hooks

@krpavan3
Copy link

krpavan3 commented Mar 6, 2019

How to create a repository under a particular organization in Github enterprise account using curl command.

Curl command used:


curl -u 'user_name' https://github.com/api/v3/user/repos/sample_ORG -d '{"name":"Test-Repo","description":"This project is a test"}'

Error message displayed


{
"message": "Not Found",
"documentation_url": "https://developer.github.com/enterprise/2.14/v3"
}

@rokibhasansagar
Copy link

For User:

Replace ACCESS_TOKEN with Git OAuth Token and NEW_REPO_NAME with your New Repository Name

curl -H "Authorization: token ACCESS_TOKEN" -d '{"name": "NEW_REPO_NAME", "private": <true/false>, "description": "<may_add_a_little_info_about_the_repo>"}' https://api.github.com/user/repos

Or like...

curl -i -X POST https://api.github.com/user/repos \
-H "Authorization: token <ACCESS_TOKEN>" \
-d @- << EOF
{
  "name": "<NEW_REPO_NAME>",
  "private": <true/false>,
  "description": "<add_a_little_info_about_the_repo>"
}
EOF

»» At least the name key is Required to create the repo.

For Organization:

Replace ORGANISATION_NAME with the Organization Name that you have access to

curl -H "Authorization: token ACCESS_TOKEN" -d '{"name": "NEW_REPO_NAME"}' https://api.github.com/orgs/ORGANISATION_NAME/repos

★ This uses the latest Developer's API v3
»» Works well even if you have enabled Two-Factor Security

@elect86
Copy link

elect86 commented May 9, 2021

Is it possible to create/update multiple files at once? Because right now we have a PUT per commit..

@0wwafa
Copy link

0wwafa commented Oct 12, 2024

how to post an image to a gist?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment