ctrl+shift+p filters: :st2 :st3 :win :osx :linux


by kylebebak ST3

Powerful, modern HTTP/REST client built on top of the Requests library

Labels http, api, rest, debug



  • Total 289
  • Win 103
  • OS X 137
  • Linux 49
Sep 20 Sep 19 Sep 18 Sep 17 Sep 16 Sep 15 Sep 14 Sep 13 Sep 12 Sep 11 Sep 10 Sep 9 Sep 8 Sep 7 Sep 6 Sep 5 Sep 4 Sep 3 Sep 2 Sep 1 Aug 31 Aug 30 Aug 29 Aug 28 Aug 27 Aug 26 Aug 25 Aug 24 Aug 23 Aug 22 Aug 21 Aug 20 Aug 19 Aug 18 Aug 17 Aug 16 Aug 15 Aug 14 Aug 13 Aug 12 Aug 11 Aug 10 Aug 9 Aug 8 Aug 7 Aug 6
Windows 1 4 2 0 1 3 11 6 1 2 0 0 0 2 1 2 1 0 1 0 2 2 0 0 1 0 0 1 0 1 1 0 0 3 0 5 1 2 0 0 0 0 0 1 1 1
OS X 0 0 2 1 0 4 24 21 1 0 0 0 0 1 0 0 2 0 0 0 1 2 0 1 0 1 0 1 2 1 0 1 0 1 0 0 1 1 0 0 2 0 0 1 3 0
Linux 0 2 2 1 1 1 4 2 0 0 0 0 2 1 1 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0 1 0 0



Requester: HTTP Client for Humans

LicenseBuild Status Coverage Status Join the chat at https://gitter.im/kylebebak/Requester

Requester is a modern, team-oriented HTTP client for Sublime Text 3 that combines features of apps like Postman, Paw and HTTPie with rock-solid usability and the secret sauce of Requests. 🌟

  • Super classy, well-documented syntax
    • Easily set request body, query params, custom headers, cookies
    • Support for sessions, authentication
    • Forms and file uploads, Wget-style downloads
    • HTTPS, proxies, redirects, and more
  • Intuitive, modern UX
  • Perfect for teams
    • Version and share requests however you want (Git, GitHub, etc)
    • Export requests to cURL or HTTPie, import requests from cURL
    • Lightweight, integrated test runner with support for JSON Schema
    • Export Requester tests to a runnable test script
    • AB-style benchmarking tool
    • Runs on Linux, Windows and macOS/OS X

If you're looking for an HTTP client you should try Requester even if you've never used Sublime Text. Here's why.



  1. Download and install Sublime Text 3.
  2. Install Package Control for Sublime Text.
  3. Open the command palette shift+cmd+p and type Package Control: Install Package.
  4. Search for Requester (not Http Requester) and install it.
  5. If you're seeing errors every time you run a request, this probably means the requests dependency wasn't installed successfully. To fix this, look for Package Control: Satisfy Dependencies in the command palette, run it, and restart Sublime Text.

Getting Started

Open the interactive tutorial in Sublime Text! Look for Requester: Show Tutorial in the command palette. Alternatively, just keep reading.

Open a file and insert the following.


get('https://jsonplaceholder.typicode.com/posts')  # 'requests.' prefix is optional
post('jsonplaceholder.typicode.com/posts')  # as is the URL scheme

Place your cursor on one of the lines and hit ctrl+alt+r (ctrl+r on macOS). Or, look for Requester: Run Requests in the command palette shift+cmd+p and hit Enter. A response tab will appear, with a name like GET: /albums.

Head to the response tab and check out the response. Hit ctrl+alt+r or ctrl+r (ctrl+r or cmd+r on macOS) to replay the request. You can edit the request, which is at the top of the file, before replaying it.

Now, go back to the requester file and highlight all 5 lines, and once again execute the requests.

Tabs will open for all 4 requests (Requester conveniently ignores the blank line). Before checking out these tabs, execute the requests yet again. You'll notice duplicate requests don't create a mess of new tabs, they just overwrite the content in the matching response tabs (read on if you'd like to change this behavior).

Jump to Request

Go back to your requester file and save it as <anything>.pyr. The extension is important. Run Sublime Text's Goto Symbol by pressing ctrl+r (cmd+r on macOS). If your requester file has this extension, you can jump between your requests almost instantaneously.

Multiline Requests

For executing requests defined over multiple lines, you have two options:

  • fully highlight one or more requests and execute them
  • place your cursor on the first line of a request and execute it

Notice that if a URL scheme isn't supplied, Requester sets it as http by default.

If you want to close all open tabs, look for Requester: Close All Response Tabs in the command palette.

JSON Response Formatting

Requester supports 3 options for JSON response formatting, indent_sort, indent, and raw. The default value for all requests, which can be changed in Requester's settings, is indent_sort. If you don't want keys in objects sorted alphabetically, use indent or raw.

get('http://headers.jsontest.com/', fmt='indent_sort')
get('http://headers.jsontest.com/', fmt='indent')
get('http://headers.jsontest.com/', fmt='raw')

Ergonomic GET Requests

Try sending the following requests. This is obviously not valid Python syntax, but Requester has a shortuct for basic GET requets. If you run Requester on a URL like the one below, it automatically wraps it like so: requests.get('<url>'). And it doesn't wrap the URL in quotes if it's already got them.


Pinned Response Tabs

When you execute a request, Requester overwrites response tabs that have the same request method and URL as the request you're executing. If you want multiple views into the same request, you can pin your response tabs. Pinned response tabs are never overwritten.

In a response tab, go to the command palette and look for Requester: Pin/Unpin Response Tab, or look in the response tab for the keyboard shortcut to pin/unpin tab.

Environment Variables

It's time to refactor your requests to use environment variables. Requester has a powerful scripting language for env vars… Python!

You can define them directly in your requester file. Just put your variables in a code block fenced by ###env lines. Try executing these requests.

base_url = 'https://jsonplaceholder.typicode.com'

get(base_url + '/albums')
post(base_url + '/albums')

Variables you define in your env block can be referenced by any of your requests. The ###env lines must have no leading or trailing spaces. Only the first env block in a requester file is used.

You can import and use anything in Python's standard library in your env block. You can also import and use requests. This makes Requester's env vars powerful and flexible. Here's a toy example. Copy it to another file and give it a try.

import requests
base_url = 'https://www.metaweather.com/api'
r = requests.get(base_url + '/location/search/?lattlong=19.4326,-99.1332')
woeid = str(r.json()[0]['woeid'])  # get "where on earth id" for Mexico City

get('{}/location/{}/'.format(base_url, woeid))  # use "where on earth id" to get Mexico City's weather data

Advanced Features

Find out what makes Requester really special. In the future if you need to refresh your memory, just press shift+cmd+p to open the command palette, and type Requester.

Separate Env File

Requester can save and source your env vars from a separate env file. To do this, first you want to save your requester file. This way you can use a relative path from your requester file to your env file, which is convenient. Save it with any name, but use the .pyr extension. requester.pyr is fine. More on the .pyr extension later.

Next, save a file with the name requester_env.py in the same directory as requester.pyr, and add an env var to it.

base_url = 'https://jsonplaceholder.typicode.com'

Finally, define the path of your env_file in your requester file like so:

env_file = 'requester_env.py'

get(base_url + '/albums')
post(base_url + '/albums')

Requester will now look for the env file at the path requester_env.py, which is relative to the location of the requester file. You can change this path to any relative path you want, e.g. relative/path/to/env.py. You can also use an absolute path to the env vars file if you want.

Merging Vars from Env Block and Env File

Is totally fine. If a var has the same name in the env block and the env file, the var from the env file takes precedence.

Why? If you're working on a team, your requester file should probably be in version control. Static env vars and default values for dynamic env vars can be defined in the env block of your requester file.

Dynamic env vars, like a base_url that might point to staging one minute and production the next, can be (re)defined in an env file. Put the env file in your .gitignore. This way devs can tweak their envs without making useless commits or stepping on each other's toes.

Request Body, Query Params, Custom Headers, Cookies

post('httpbin.org/post', data={'key1': 'value1', 'key2': 'value2'})

post('httpbin.org/post', json=[1, 2, 3])
post('httpbin.org/post', json={'name': 'Jimbo', 'age': 35, 'married': False, 'hobbies': ['wiki', 'pedia']})

get('httpbin.org/get', params={'key1': 'value1', 'key2': 'value2'})

get('httpbin.org/headers', headers={'key1': 'value1', 'key2': 'value2'})

get('httpbin.org/cookies', cookies={'key1': 'value1', 'key2': 'value2'})

get('httpbin.org/redirect-to?url=foo')  # response tab shows redirects

Body, Query Params, and Headers are passed to requests as dictionaries. Cookies can be passed as a dict or an instance of requests.cookies.RequestsCookieJar.

If you execute the last request, you'll notice the response tab shows the series of redirects followed by the browser.

If you want to disallow redirects by default, simply change Requester's allow_redirects setting to false.


Need to log in first so all your requests include a session cookie? Session objects make this a cinch.

Instantiate the session object in the env block and use it in your requests. Copy this code to a new file, run the request, and check out the session_id cookie in the request headers.

import requests
s = requests.Session()
s.get('http://httpbin.org/cookies/set?session_id=12345', timeout=5)


In the example above, each time you execute Requester: Run Requests, a new session is created, and once all responses are returned the session is destroyed.

If you highlight and run multiple requests that depend a session s, they will all share the same session s. If you run them serially, you can control the order in which cookies are added to the session.


Requests has excellent support for authentication. Basic Authentication and Digest Authentication are built in, and implementing custom auth schemes is easy.

To use a custom auth scheme with Requester you define the auth class in your env block or env file, then pass an instance of this class to the auth argument of a request.

Requester comes with a few pre-written auth classes you can use in your code, or as a reference. Run Requester: Authentication Options in the command palette to see the list. Have a look at Token auth, which simplifies passing a token in the “Authorization” header of your requests.

If you want help handling more complicated forms of auth, like OAuth1 and OAuth2, have a look at this section.

Forms and File Uploads

Requests makes posting forms and uploading files easy. See how in the Requests documentation.

Requests also supports streaming and chunked file uploads, which is great (and necessary) if the file you're uploading doesn't fit in memory, but the API is a bit more complicated. Requester has the special streamed and chunked arguments to make these uploads trivial.

post('https://requestb.in/<your_request_bin>', streamed='/path/to/file')
post('https://requestb.in/<your_request_bin>', chunked='/path/to/file')

If you pass the file as a chunked upload, the “Transfer-Encoding”: “chunked” header is added to your request. Some servers don't allow chunked uploads, in which case you can use a streamed upload. If they're an option, chunked uploads are nicer: they come with a progress bar and can be cancelled.

If you need streaming uploads for multipart forms, or uploads of multiple files, the requests-toolbelt packages has your back. Check out this section.


Requester also provides Wget-style downloads. Just add the filename keyword arg to a call to requests.get.

get('http://www.nationalgeographic.com/content/dam/animals/thumbs/rights-exempt/mammals/d/domestic-dog_thumb.jpg', filename='image.jpg')

As with streamed and chunked uploads, filename can be an absolute path, or a path relative to your requester file. Also, as with uploads, multiple downloads can be executed in parallel. Downloads can be cancelled. They come with a nice progress bar.

Downloaded File Name

If you pass a value for filename that has no basename, Requester infers the name of the file from the URL. Examples of such filenames: '', relative/path/, /absolute/path/.

In this mode, if the file name already exists, Requester adds a suffix to make the file name unique. Try downloading this file several times in succession.

get('http://www.nationalgeographic.com/content/dam/animals/thumbs/rights-exempt/mammals/d/domestic-dog_thumb.jpg', filename='')

Cancel Outstanding Requests

If you have outstanding requests that are taking a while to return, and you don't want to wait for them to time out, you can cancel them by calling Requester: Cancel Requests from the command palette.

Chaining Requests

If you need to run requests or tests one after another, in the order in which they're defined in your requester file, look for Requester: Run Requests Serially or Requester: Run Tests Serially in the command palette.

Behind the scenes, this just passes the concurrency=1 arg to requester or requester_run_tests, and voilà, you've chained your requests.

Note: code inside your env block/env file always runs serially, which includes any requests you put in there.

Chaining by Reference

If you need true request chaining, such that a request can reference the Response object returned by the previous request, that's easy too. Requester lets you reference the most recently returned response using the Response variable, and also lets you name your responses. Copy the following code to a new view, highlight it, and run Requester: Run Requests Serially.


get('http://httpbin.org/cookies', cookies={'url': Response.json()['url']})

If you don't run requests serially, the second request fails, because it's executed before the first request returns. Now try naming the response from a request using the name argument.

get('httpbin.org/get', name='first_response')
get('google.com', allow_redirects=False)
get('httpbin.org/cookies', cookies={'url': first_response.json()['url']})

By the way, you shouldn't name an env var “Response”, or with the same name that you pass to a request's name argument, because it will be overwritten.

Navigation and History

UX is sort of an obsession for me, and it's sacred in Requester. The biggest UX difference between Requester and other HTTP clients is the ease with which you can find, modify and execute your requests — the ones in your requester file, and the ones in you request history.

Requester File Navigation (.pyr extension)

Try running Requester: New Requester File from the command palette. You'll get a file pointing to an empty env file, with an empty env block, and a link to Requester's syntax at the top. It's ready for starting a new collection of requests.

You'll notice the file you just created has a special extension, .pyr. This is the Python Requester extension. You should save all your requester files with this extension.

Here's why. Run Requester: New Requester File (Navigation Demo) from the command palette. You'll get a new requester file with some stub requests already inserted. Now, run Sublime's Goto Symbol command (cmd+r on macOS)… You can jump between request groups and individual requests almost instantaneously using fuzzy search!

Behind the scenes, .pyr files get the special Requester syntax applied to them (you can set this syntax on any view you like by running Set Syntax: Requester from the command palette). Requester is the default Python syntax with a few Requester-specific improvements:

  • your ###env block delimeters are highlighted
  • request groups can be declared by starting a line with two or more ## characters
  • you can use Sublime's Goto Symbol to jump between requests and request groups ✨✨

Request History

Requester saves a history of executed requests. Call Requester: Request History to check it out. They appear in reverse chronological order and include each request's age, URL, response status code, and requester file. They're fuzzy searchable!

Choose an old request and select it. A special response tab will open, with the request string, some response metadata, and the usual response tab commands, but nothing else.

Replay the chosen request. It runs as if it were executed from its original requester file, but it also pulls in up-to-date env vars from the env block and the env file.

Page Through Past Requests

Notice the key bindings for prev/next request in response tabs? Give them a try.

If these or other bindings don't work, don't fret! Here's a 1 minute, permanent fix to the problem.

These commands let you page through past requests one at a time, and can be used from any response tab. Combine them with fuzzy search for request searching nirvana.

Imagine you want to find a GET request you ran when you were working with the Twitter API over the weekend. You open search with Requester: Request History and type twitter, and see a bunch of requests from around 3 days ago. You're not sure which is the right one, so you hit enter to get a better look.

From here, you begin to page back, past a few 40Xs, some POSTs, then boom, the elusive 200 GET is right in front of you. You replay it, and now it's back on top of your request history. Next time you want it it'll take 1 second to find instead of 10.

Requester's history is one of Requester's most convenient features, which means you might want to modify your keymap and bind something to requester_history. ✨✨

Open your keymap from the command palette by running Preferences: Key Bindings. For example, on macOS you might bind it to ctrl+h by adding the following:

{ "keys": ["ctrl+h"], "command": "requester_history" },

Explore Hyperlinked APIs (HATEOAS)

Ever used an API that returns hyperlinks to other resources in the response? This pattern is part of a larger concept in REST called HATEOAS, or hypermedia as the engine of application state.

It's a mouthful, but the idea is simple: an API response should tell clients how to interact with related resources by providing them hyperlinks to those resources. This allows APIs to change without breaking clients, as long as clients are written to take their cues from the hyperlinks returned by the API.

Requester is ready-made for exploring these APIs. From a response tab, highlight any URL and press ctrl+e (cmd+e on macOS). Instead of replaying the original request, Requester sends a GET request to the highlighted URL and opens the response in a new tab.

It also compares the domain of the highlighted URL with the domain of the original request. If they're the same, Requester includes the same args and kwargs in the new request. If the original request was authenticated, the “exploratory” request will be authenticated as well.

If the domains are not the same, Requester strips all additional args and kwargs from the request, to ensure that none of your auth credentials are sent to a URL not belonging to the “source” API.

    headers={'Authorization': 'Bearer my_secret_token'},
    json={'same_domain': 'http://httpbin.org/get', 'other_domain': 'https://jsonplaceholder.typicode.com/posts'}

Execute the request above. In the response tab, try highlighting each of the URLs in the response body and sending exploratory requests. Requester makes it trivial to explore hyperlinked URLs without worrying about leaking your credentials. ✨✨

Options Requests

Want to see which HTTP verbs a given endpoint accepts? Send an OPTIONS request to the endpoint. Requester makes this ridiculously easy – from a response tab, just press ctrl+o (cmd+o on macOS).

Import Any Python Package with Requester

Requester comes bundled with the requests and jsonschema packages, but you can trivially extend it to source any Python 3 package in its env. All you have to do is set Requester's packages_path setting to a directory with Python 3 packages. Requester can then import these packages in your env block or env file. ✨✨

In my settings for Requester packages_path points to a Python 3 virtual env: /Users/kylebebak/.virtualenvs/general/lib/python3.5/site-packages. I use pip to install these packages.

Here are a couple of no-brainers:

Pip3 Quickstart

If you don't have virtualenv or you're not comfortable using it, the quick solution is to install Python 3, which will install pip3 and python3 executables. Run which pip3 to make sure you've done this.

Then run pip3 install requests-oauthlib, pip3 install requests-toolbelt, and so on for whatever packages you'd like to use with Requester.

Finally, run pip3 show requests-oauthlib, and look for the LOCATION field in the output. Now you know where pip is installing your packages.

Use this path as your packages_path setting in Requester's settings file. To open these settings, look for Requester: Settings in the command palette.

OAuth1 and OAuth2

requests-oauthlib makes OAuth1 and OAuth2 a lot easier. Let's say you want explore the Twitter REST API, which uses OAuth1 for authentication. Go to https://apps.twitter.com/app/new, create a new application, then go to the Keys and Access Tokens tab for your application. Generate an access token and an access token secret, grab your API key and secret, and pass them to OAuth1.

from requests_oauthlib import OAuth1

get('https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=stackoverflow&count=100', auth=auth)

# ...
#   "created_at": "Wed Sep 13 19:10:10 +0000 2017",
#   "entities": {
#     "hashtags": [],
#     "symbols": [],
#     "urls": [
#       {
#         "display_url": "stackoverflow.blog/2017/09/06/inc\u2026",
#         "expanded_url": "https://stackoverflow.blog/2017/09/06/incredible-growth-python/",
#         "indices": [
#           32,
#           55
#         ],
#         "url": "https://t.co/4NCaBp5RKh"
#       }
#     ],
#     "user_mentions": []
#   },
#   "favorite_count": 2,
# ...

Python has auth libraries for authenticating with a wide variety of APIs. With pip and the packages_path setting Requester can access them all.

Test Runner

Requester has a built-in test runner! Copy and paste this into an empty file.

base_url = 'https://jsonplaceholder.typicode.com'
prop = 'status_code'

# first request
get(base_url + '/posts')
assert {prop: 200, 'encoding': 'utf-8'}

# second request, with no assertion
get(base_url + '/profile')

# third request
get(base_url + '/comments')
assert {'status_code': 500}

Highlight all the requests, look for Requester: Run Tests in the command palette, and run it. You'll notice that test results are displayed for the first and third requests.

What's going on here? If a request has an assertion below it, the key, value pair in the assertion is compared with the returned Response object. If key is a valid property of the Response object, value is compared with the property. If they're not equal discrepancies are displayed.

Some valid properties: apparent_encoding, cookies, encoding, headers, history, is_permanent_redirect, is_redirect, json, links, reason, status_code, text, content.

Making Assertions About Response Structure

cookies, headers and json point to Python dicts or lists, which means comparing for equality isn't very useful. Much more useful are the following special assertion keys for these properties: cookies_schema, headers_schema, json_schema.

Including one of these in an assertion will validate the corresponding property with jsonschema.validate. This lets you describe the structure of cookies, headers, and JSON responses returned by your API. Look at the example below. The test fails because we assert that the userId for each object in the array of results has a type of string, and this isn't true.

If you have a JSON API, JSON Schema is an excellent way to describe your API's data format. Use it.

assert {
    'json_schema': {
        "type": "array",
        "items": {
            "type": "object",
            "properties": {
                "body": {"type": "string"},
                "id": {"type": "number"},
                "title": {"type": "string"},
                "userId": {"type": "string"}

The test runner was built for convenience:

  • requests and assertions can use env vars
  • requests without corresponding assertions are ignored
  • the order of requests is preserved in the results tab

Assertions can be inserted seamlessly into a requester file; if you're not doing a test run they're simply ignored.

Export Tests to Runnable Script

If you want to integrate your Requester tests into your app's test routine, Requester can export request/assertion pairs to a runnable test script. Highlight the requests and assertions you want to export and look for Requester: Export Tests To Runnable Script in the command palette.

This test script depends only on the Python requests and jsonschema packages. To run it from the command line you just call python -m unittest <test_module_name>. The default test module name is requester_tests.

The test export command lacks two conveniences available to all other Requester commands:

  • it doesn't automatically include the timeout argument in calls to requests
  • it doesn't automatically add a scheme to URLs with no scheme

Benchmarking Tool

Want to see how your staging or production servers hold up under load? Requester's benchmarking tool is like ab or siege, but it's easier to use. Highlight one or more requests, and call Requester: Run Benchmarks from the command palette.

You'll be prompted for the number N of each request to run, and the concurrency C. In other words, if you highlight 5 requests, then input 100 for N and 20 for C, you'll send a total of 500 requests, 100 to each endpoint, in bunches of 20 at a time.

Requester then displays a profile with response time metrics, grouped by request method and URL. Try it on these 3 here, with N=100 and C=20.

get('http://httpbin.org/headers', headers={'key1': 'value1', 'key2': 'value2'})

get('http://httpbin.org/get', params={'key1': 'value1', 'key2': 'value2'})

get('http://httpbin.org/cookies', cookies={'key1': 'value1', 'key2': 'value2'})

It goes without saying, but please don't use this for DoS attacks on servers you don't own. Regardless of what you pass for N, the total number of requests executed is capped at 100000. C is capped at 1000, which translates to tens of millions of requests per day.

Warning: benchmarks runs with C above ~100 may slow down the UI while they are running.

Export/Import with cURL, HTTPie

Need your requests in a more portable format? Requester exports to and import from the ubiquitous cURL format.

This makes it trivial to share requests with teammates who don't use Requester, or execute your requests on any server you like.

Prefer HTTPie instead of cURL? You can also export requests to HTTPie!

Exporting works seamlessly with env vars. Just highlight a group of requests and look for Requester: Export To cURL or Requester: Export To HTTPie in the command palette. For importing it's Requester: Import From cURL. Exporting to HTTPie supports a bunch of features, including basic and digest authentication, file downloads, and even sessions. For sessions, just highlight your env block along with the requests you want to export.

Special Keyword Arguments

Requester's syntax is basically identical to Requests' syntax, but it adds support for the following special kwargs.

  • fmt: one of ('raw', 'indent', 'indent_sort'), controls formatting of JSON responses
  • name: binds name to response object so that it can be referenced by subsequent serially executed requests
  • filename: downloads the response to the specied path
  • streamed: performs a streaming upload of the specified file
  • chunked: performs a chunked upload, with a progress indicator, of the specified file


Commands defined by this package, in case you want to add or change key bindings.

  • requester
  • requester_replay_request
  • requester_explore_url: explore url in response tab
  • requester_history: search and re-execute past requests
  • requester_cancel_requests: cancel all outstanding requests
  • requester_cancel_downloads: cancel outstanding file downloads
  • requester_cancel_uploads: cancel outstanding file uploads
  • requester_response_tab_toggle_pinned: pin (or unpin) a response tab so that it isn't overwritten by requests with its same method and URL
  • requester_close_response_tabs
  • requester_reorder_response_tabs: reorders response tabs to match order of requests in requester file
  • requester_new_requester_file: create empty requester file
  • requester_run_tests
  • requester_export_tests: export tests to runnable script
  • requester_prompt_benchmarks
  • requester_auth_options
  • requester_export_to_curl: export selected requests to cURL
  • requester_export_to_httpie: export selected requests to HTTPie
  • requester_import_from_curl: import selected cURL requests
  • requester_show_tutorial
  • requester_show_documentation
  • requester_show_syntax

Response Tab Commands

The following commands are only available in response tabs. The key bindings listed below are for macOS. Every response tab shows these key bindings.

  • cmd+r: replay request
  • ctrl+alt+ ←/→: prev/next request
  • cmd+t: pin/unpin tab
  • cmd+e: explore URL
  • cmd+o: options

If you try to execute one of these commands and nothing happens, you've already mapped the binding to another command. Run Preferences: Key Bindings from the command palette, find the conflicting key combination, add the following context to the binding, and restart Sublime Text.

"context": [
  { "key": "setting.requester.response_view", "operator": "equal", "operand": false }

This removes the conflict by disabling your binding only in Requester's response views.


Requester's modifiable settings, and their default values. You can override any of these settings by creating a Requester.sublime-settings file in Sublime's Packages/User directory. The easiest way to do this is go to Preferences > Package Settings > Requester > Settings from the menu bar, or look for Requester: Settings in the command palette.

  • timeout, 15: default timeout in seconds for all requests
  • timeout_env, 15: default timeout in seconds for executing env block/env file
  • allow_redirects, true: are redirects allowed by default?
  • scheme, "http": scheme prepended to URLs in case no scheme is specified
  • fmt, "indent_sort": JSON response formatting, one of (“raw”, “indent”, “indent_sort”)
  • max_content_length_kb, 5000: don't render responses whose content length (kilobytes) exceeds this value
  • change_focus_after_request, true: if a single request is executed, change focus to response tab after request returns
  • reorder_tabs_after_requests, false: if multiple requests are executed, automatically reorder response tabs based on requests in requester file after requests return
  • pin_tabs_by_default, false: pin newly opened response tabs by default, so they aren't overwritten by requests with the same method and URL
  • history_file, "Requester.history.json": name of request history file, stored in User directory
  • history_max_entries, 250: max number of requests in history file
  • chunk_size, 1024: chunk size for file downloads (bytes)
  • only_download_for_200, true: only perform file download if response status code is 200
  • packages_path, "": absolute path to extra python packages included in env

Contributing and Tests

See here.

Inspired By

  • Requests — Requester sends all its requests using this amazing library.
  • HTTPie — A truly “Pythonic” tool. Its focus on intuitiveness and ergonomics inspired many of Requester's features, including its docs site.
  • Postman — A strong influence on much of Requester's “managed” UI.

Why Requester?

Requester combines features from applications like Postman, Paw, Insomnia and HTTPie with the elegance and power of Requests and rock-solid UX of Sublime Text.

Requester leans on Requests as much as possible. This means Requester does most anything Requests does, which means it does most anything you need to explore, debug, and test a modern API.

It also means Requester uses an extensively documented, battle-tested library famed for its beauty. If you don't know how to do something with Requester, there are thousands of blog posts, articles and answers on Stack Overflow that explain how to do it.

Apart from being feature-rich, Requester is built for speed and simplicity. I was a Postman user before writing Requester, and I got tired of, for example, having to click in 4 places to add or change an env var. With Requester you might have to move your cursor up a few lines.

Request navigation and history are especially powerful. Finding a request you executed a week ago, editing it and executing it is lightning fast.


The paid collaboration features of HTTP client apps, such as sharing and versioning, are not only free in Requester, they're better. Requester works with text files, and as good as the developers at Postman and Paw are, they don't beat GitHub at collaboration, and they don't beat Git at version control.

Need to share requests with someone who doesn't use Requester? Exporting all of your requests to cURL or HTTPie takes a few seconds.

Requester is cross-platform and built for teams. If you debug web APIs for work or for fun, try it. Try it even if you don't use Sublime Text. You'll have to switch between two text editors, but you already have to switch between your editor and your HTTP client. Sublime Text running Requester probably has a smaller footprint than your HTTP client, and it's probably a lot easier to use. ✨✨