A keyboard-first Terminal User Interface (TUI) API client inspired by tools like Postman — built for developers who live in the terminal.
This project focuses on the core 70% of API workflows: sending requests, inspecting responses, and iterating quickly — without heavy GUI overhead.
Modern API clients are powerful but often:
- Heavy and slow to open
- GUI-centric and mouse-driven
- Hard to use over SSH or low-resource environments
Pigeonman is designed to be:
- 🥔 Potato Device🙋♂️
- ⚡ Fast & lightweight
- ⌨️ Keyboard-first
- 📁 File-based & Git-friendly
- 🎨 Beautiful with Rich syntax highlighting
- 🛡️ Reliable with error handling & timeouts
- 🧠 Focused on inspection, not decoration
- Load API collections from YAML
- Environment variable substitution (
{{VAR}}syntax) - Command Palette (
Ctrl+P) - Quick access to actions & collection switching - Multiple Collections - Switch between collections without restart
- Collapsible group folders - Organize requests with interactive tree view
- Edit & Save - Modify requests in UI and save changes to YAML (
ito edit,Ctrl+Sto save) - Send HTTP requests (GET, POST, PUT, DELETE, PATCH)
- Inspect responses with rich syntax highlighting (Dracula theme):
- Status code with color coding
- Response time
- Headers
- Pretty-printed JSON body
- Search & filter requests in real-time (
/key) - Three response display modes:
- JSON (pretty-printed with syntax highlighting)
- RAW (plain text)
- HEADERS (headers only)
- Keyboard-driven navigation
- Request history - Track recently sent requests (
hkey) - Export responses to JSON with full request metadata (
exports/folder)
Pigeonman TUI showing collapsible request groups, request details, and JSON response inspector
The UI follows a three-panel layout:
┌──────────────────────────────────┬────────────────────┐
│ Request List │ Request Details │ Response Inspector │
│ │ │ │
│ [Search...] │ Name: Get User │ Status: 200 OK │
│ 📁 Users (5) │ Method: GET │ Time: 123ms │
│ 🟢 GET /users│ Path: /users/1 │ JSON Body │
│ 🟡 POST /... │ Headers: (none) │ │
│ │ Body: (none) │ │
│ ───────────── │ │ │
│ HISTORY │ │ │
│ GET /users/1 │ │ │
└────────────────┴──────────────────┴────────────────────┘
| Key | Action |
|---|---|
j / k |
Navigate up/down request list |
Enter |
Send selected request |
r |
Re-send request |
h |
Toggle request history |
TAB |
Switch panel focus |
/ |
Search/filter requests |
Esc |
Clear search / close modal |
Ctrl+P |
Command palette |
1 |
JSON response mode |
2 |
RAW response mode |
3 |
HEADERS response mode |
e |
Export response |
c |
Copy response to clipboard |
X |
Copy request as cURL |
i |
Toggle edit mode |
Ctrl+S |
Save collection |
? |
Show help |
q |
Quit application |
Note for Linux users: You may need to install
xclip(sudo apt install xclipor equivalent) for the copy feature to work. Windows and macOS have built-in clipboard tools.
Press Ctrl+P to open the Command Palette for quick access to actions and collection switching.
Quick Actions:
- Send Request, Copy as cURL, Copy Response
- Toggle Edit Mode, Save Collection
- Toggle History, Show Help
- Switch response modes (JSON/RAW/Headers)
Collection Management:
- Recent Collections - Auto-tracks last 10 opened collections
- Example Collections - Quick access to built-in examples
- Load from file - Open any YAML collection
Collections are automatically saved to ~/.pigeonman/config.json:
{
"recent_collections": [
"examples/large-project.yaml",
"examples/medium-project.yaml",
"examples/small-project.yaml"
],
"last_opened_collection": "examples/large-project.yaml"
}- Press
ito enter edit mode - Modify request fields:
- Name - Request name
- Method - HTTP method (GET, POST, etc.)
- Path - API endpoint path
- Body - JSON request body
- Changes are applied immediately
- Press
Ctrl+Sto save to YAML file - Collection file is updated on disk
- Auto-exits edit mode and returns to tree view
1. Press i → Edit mode enabled
2. Edit fields → Name, Method, Path, Body
3. Press Ctrl+S → Changes saved to YAML
4. Press Esc or i → Exit edit mode (if not saved)
API requests are defined using a simple, human-readable YAML format.
name: Example API
base_url: https://api.example.com
env:
TOKEN: your_token_here
requests:
- name: Get Users
group: Users
method: GET
path: /users
headers:
Authorization: Bearer {{TOKEN}}
- name: Create User
group: Users
method: POST
path: /users
headers:
Content-Type: application/json
body:
name: test
email: test@example.com
- name: List Products
group: Products
method: GET
path: /productsVariables use {{VAR_NAME}} syntax and can be defined in:
envsection in collection YAML.envfile in same directory as collection- System environment variables
Priority: Collection env → .env file → System env (later overrides earlier)
Requests can be organized into groups/folders using the group field:
requests:
- name: Login
group: Authentication
method: POST
path: /api/login
- name: List Users
group: Users
method: GET
path: /api/usersGroups are displayed as collapsible folders in the request list:
- 📁 Folder icons for groups with request count
- ▶ Click folder to collapse/expand
- ▶ Auto-expand on load for easy access
- Method color coding - Each request shows its HTTP method with color:
- 🟢
GET- Bright green - 🟡
POST- Bright yellow - 🔵
PUT- Bright blue - 🔴
DELETE- Bright red - 🟣
PATCH- Bright magenta
- 🟢
Tree Structure Example:
📁 Users (5)
🟢 GET /users
🟢 GET /users/1
🟡 POST /users
🔵 PUT /users/1
🔴 DELETE /users/1
📁 Testing (4)
🟢 GET /users/99999
🟢 GET /invalid-endpoint
🟡 POST /users
🟣 PATCH /users/1
⚪ GET /posts/1/comments
Keyboard Navigation:
↑/↓- Navigate between requests and foldersEnteron folder - Toggle collapse/expandEnteron request - Send request
Example .env file:
# API credentials
API_KEY=your_secret_key
DB_HOST=localhost
DB_PORT="5432"pip install -r requirements.txt# Basic example
python app.py examples/collection.yaml
# Small project
python app.py examples/small-project.yaml
# Medium project (e-commerce)
python app.py examples/medium-project.yaml
# Large project (SaaS platform)
python app.py examples/large-project.yaml
# Authentication workflows
python app.py examples/auth-workflow.yaml💡 Tip: Check out
examples/README.mdfor detailed documentation of all example files.
pigeonman/
├── app.py # Main application
├── core/
│ ├── loader.py # Load & validate YAML collections
│ ├── env.py # Environment variable resolver
│ ├── env_file.py # .env file parser
│ ├── client.py # HTTP client wrapper
│ ├── exporter.py # Export responses
│ ├── history.py # Request history manager
│ └── config.py # App configuration & recent collections
├── ui/
│ ├── request_list.py # Tree-based request list
│ ├── request_view.py # Request details panel
│ ├── response_view.py # Response inspector with modes
│ ├── history_view.py # Request history panel
│ ├── help_modal.py # Help overlay
│ └── command_palette.py # Command palette for quick actions
├── styles/
│ └── app.tcss # Theme & layout styling
├── examples/
│ ├── README.md # Examples documentation
│ ├── small-project.yaml # Simple REST API example
│ ├── medium-project.yaml # E-commerce API example
│ ├── large-project.yaml # SaaS platform example
│ ├── auth-workflow.yaml # Authentication patterns
│ └── collection.yaml # Basic example
├── media/
│ ├── lilbro.jpeg # Application logo
│ └── demo.JPG # Demo screenshot
├── exports/ # Auto-generated export folder
├── requirements.txt
├── LICENSE
└── README.md
- Python 3.10+
- Terminal with ANSI support
textual— TUI frameworkhttpx— async HTTP clientrich— rich text renderingpyyaml— YAML parsing
To keep the project focused, the following are intentionally not included in early versions:
- WebSocket support
- GraphQL playground
- OAuth UI flows
- Cookie jar management
- Scripting / test assertions
- Complex authentication helpers
These may be considered in future versions.
- Load collection
- Send request
- Show response
- Environment variables
- JSON pretty-printing (Dracula theme)
- Response timing
- Search & filtering
- Response export with metadata
- Response display modes (JSON/RAW/HEADERS)
- Request history
- Dynamic theme binding
- UX refinements
- Copy request as cURL command
- Group/organize requests with folders
- Save collection changes from UI
- Multiple collections support
- Command palette with quick actions
- Recent collections tracking
- Edit mode with real-time updates
- Request chaining (use response data in next request)
- Pre-request scripts
- Response assertions/tests
- Collection runner (batch execution)
- GraphQL support
- WebSocket connections
- gRPC endpoints
- Import from Postman collections
- Import from HAR files
- Export to Postman format
- Convert cURL commands to YAML
Contributions are welcome.
- Keep features small and focused
- Follow keyboard-first UX principles
- Prefer readability over cleverness
If you find Pigeonman helpful and want to support its development, you can buy me a coffee!
Every coffee helps keep this project alive and growing! 🐦
This project is licensed under the MIT License - see the LICENSE file for details.
