In a nutshell, this is disgusting:
curl -X POST https://api.github.com/repos/owner/repo/issues \
-H "Authorization: Bearer ghp_token123" \
-H "Content-Type: application/json" \
-H "Accept: application/vnd.github.v3+json" \
-d '{
"title": "Bug Report",
"body": "Something is broken",
"labels": ["bug", "priority-high"],
"assignees": ["developer1", "developer2"]
}'
saul github set url https://api.github.com/repos/{?repo_owner}/{?repo_name}/{@endpoint}
saul set method POST
saul set header Authorization="Bearer {@token}" #Btw this {@} prompts you the first time, then you need to choose to update the variable with a flag on call
saul set body title="Bug Report" body="Something is broken" labels=[bug,priority-high] assignees=[developer1,developer2]
saul call
- Workspace-based – Each API gets its own organized folder
- Smart variables –
{@token}persists,{?name}prompts every time - Response filtering – Show only the fields you care about
- Git-friendly – TOML files version control beautifully
- Unix composable – Script it, pipe it, shell it
Supports: Linux, macOS, Windows (I hope)
curl -sSL https://raw.githubusercontent.com/DeprecatedLuar/better-curl-saul/main/install.sh | bash
- Download binary for your OS from releases
- Make executable:
chmod +x saul-* - Move to PATH:
sudo mv saul-* /usr/local/bin/saul
Note
I have no idea how to use a windows shell so I expect you to have bash 👍
git clone https://github.com/DeprecatedLuar/better-curl-saul.git
cd better-curl-saul
./other/install-local.sh # Local development build
Note
One-line install automatically downloads pre-built binaries or builds from source as fallback so you don’t get sad 🙁
saul set url https://raw.githubusercontent.com/DeprecatedLuar/better-curl-saul/main/install.sh && saul call --raw | bash # (Maybe works, who knows)
# Create a test workspace
saul demo set url https://jsonplaceholder.typicode.com/posts/1
saul demo set method GET
saul demo call
# Try with variables
saul api set url https://httpbin.org/post
saul api set method POST
saul api set body name={?your_name} message="Hello from Saul"
saul api call
# Oh... yeah, for nesting just use dot notation like obj.field=idk
Alright so you can:
set, check(will become get), edit, rm your
body, header, query, request, history or maybe even
response, also url, method, timeout, history
# Configure your API workspace (or preset, same thing)
saul [workspace] set url https://api.example.com
saul set method POST
saul set header Authorization="Bearer {@token}"
saul set body user.name={?username} user.email=john@test.com
# Execute the request
saul call
# Check your configuration, note that preset/workspace name keeps
# stored in memory after first mention on syntax
saul [anoter_workspace] check url
saul check body
# View response history
saul check history
Important note about variables mechanics:
There are 2 variable types
- soft variables {?} prompt you at EVERY call
- hard variables {@} require manual update by running a flag (not yet added sorry) or running
saul set variable varname value
Beta software – Core features work, documentation in progress.
Bug or feedback? I will be very, very, very happy if you let me know your thoughts.

.png)



