TL;DR
- Charles Proxy intercepts HTTP/HTTPS traffic for inspection and modification
- SSL Proxying requires certificate installation on device (mobile/browser)
- Breakpoints let you modify requests/responses in real-time
- Map Local/Remote redirects requests to local files or different servers
- Throttling simulates slow networks for performance testing
Best for: Mobile testers, API developers, QA debugging production issues Skip if: You only need simple request inspection (browser DevTools is enough) Reading time: 14 minutes
The mobile app crashes but only on slow networks. The API returns different data in production than staging. You need to test error handling but can’t make the server return errors.
Charles Proxy sits between your app and the internet. It sees everything, lets you change anything. Network debugging becomes possible instead of guesswork.
This tutorial covers Charles from installation to advanced techniques — everything for effective network debugging.
What is Charles Proxy?
Charles Proxy is an HTTP proxy and monitor. It captures network traffic from any application configured to use it, displaying requests and responses for inspection.
What Charles does:
- Intercept traffic — see every request your app makes
- Inspect SSL/TLS — decrypt HTTPS for debugging
- Modify requests — change headers, body, URL before sending
- Mock responses — return fake data without server changes
- Throttle bandwidth — simulate slow/unreliable networks
- Record sessions — save and replay traffic for analysis
Common use cases:
- Debug API integration issues
- Test mobile apps without backend changes
- Reproduce production bugs locally
- Verify request/response formats
- Test error handling with fake error responses
Installation and Setup
Installing Charles
macOS:
brew install --cask charles
Windows/Linux: Download from charlesproxy.com
Basic Configuration
- Launch Charles — it starts proxying immediately
- Go to Proxy → Proxy Settings
- Default port is 8888 (change if needed)
- Enable macOS Proxy or Windows Proxy for system-wide capture
SSL Proxying Setup
By default, Charles can’t read HTTPS content. Enable SSL Proxying:
- Go to Proxy → SSL Proxying Settings
- Check Enable SSL Proxying
- Add hosts:
*for all, or specific likeapi.example.com - Install Charles Root Certificate:
- macOS: Help → SSL Proxying → Install Charles Root Certificate
- Trust it in Keychain Access (Always Trust)
⚠️ Security Note: Only enable SSL Proxying for domains you're testing.
Never leave * enabled in production environments.
Browser Configuration
Chrome/Firefox Automatic
Charles automatically configures system proxy. Most browsers use it by default.
Manual Configuration
If automatic doesn’t work:
- Browser Settings → Network → Proxy
- Manual proxy:
localhost:8888 - Use same for HTTP and HTTPS
Firefox Specific
Firefox uses its own proxy settings:
- Settings → Network Settings → Manual proxy
- HTTP Proxy:
127.0.0.1, Port:8888 - Check “Also use this proxy for HTTPS”
Mobile Device Setup
iOS Configuration
- Connect iPhone to same WiFi as computer
- Find your computer’s IP: Help → Local IP Address
- On iPhone: Settings → WiFi → (i) next to network
- Configure Proxy → Manual
- Server: your computer’s IP
- Port: 8888
- Install SSL certificate:
- Open Safari, go to
chls.pro/ssl - Download and install profile
- Settings → General → About → Certificate Trust Settings
- Enable trust for Charles certificate
- Open Safari, go to
Android Configuration
- Connect to same WiFi
- WiFi Settings → Modify Network → Advanced
- Proxy: Manual
- Hostname: computer’s IP
- Port: 8888
- Install certificate:
- Open browser, go to
chls.pro/ssl - Download certificate
- Settings → Security → Install from storage
- For Android 7+: App must trust user certificates
- Open browser, go to
// Android app network_security_config.xml for debugging
<network-security-config>
<debug-overrides>
<trust-anchors>
<certificates src="user" />
</trust-anchors>
</debug-overrides>
</network-security-config>
Inspecting Traffic
Reading Requests
Click any request in Charles to see:
Overview Tab:
- URL, method, status code
- Timing information
- Response size
Request Tab:
- Headers (authentication, content-type)
- Query parameters
- Body (JSON, form data)
Response Tab:
- Status code and headers
- Body content (formatted JSON/XML)
- Raw response data
Filtering Traffic
Focus on relevant requests:
- Sequence View: All traffic in order
- Structure View: Grouped by host
- Filter bar: Type domain to filter
- Focus: Right-click host → Focus (hides others)
- Exclude: Tools → Block List (hide noise)
Searching
Find specific content:
- Cmd/Ctrl + F: Search in selected request
- Edit → Find: Search all traffic
- Search in headers, body, URL
Modifying Requests
Breakpoints
Stop requests for manual modification:
- Right-click request → Breakpoints
- Or Proxy → Breakpoint Settings for patterns
- When request hits breakpoint:
- Modify URL, headers, body
- Click Execute to continue
- Click Abort to cancel
Pattern: https://api.example.com/users/*
Break on: Request and Response
Rewrite Tool
Automatic modifications without breakpoints:
- Tools → Rewrite
- Enable and add rule set
- Configure:
- Location:
api.example.com - Type: Modify Header / Body / URL
- Match and Replace values
- Location:
Example — Add auth header:
Type: Add Header
Where: Request
Header Name: Authorization
Header Value: Bearer test-token-123
Example — Modify response:
Type: Body
Where: Response
Match: "status": "pending"
Replace: "status": "completed"
Mocking Responses
Map Local
Return local file instead of server response:
- Right-click request → Map Local
- Select local file (JSON, HTML, etc.)
- All matching requests return your file
Use case: Test UI with specific data without backend changes
// mock-user.json
{
"id": 1,
"name": "Test User",
"role": "admin",
"features": ["beta-feature", "new-ui"]
}
Map Remote
Redirect requests to different server:
- Tools → Map Remote
- Map from:
https://api.example.com/* - Map to:
https://staging.example.com/*
Use case: Test production app against staging backend
Compose New Request
Create requests from scratch:
- Tools → Compose
- Enter URL, method, headers, body
- Execute to send
- Useful for API exploration
Network Throttling
Simulate poor network conditions:
- Proxy → Throttle Settings
- Enable Throttling
- Choose preset or customize:
| Preset | Bandwidth | Latency |
|---|---|---|
| 56k Modem | 48 kbps | 200ms |
| 3G | 780 kbps | 200ms |
| 4G | 8 Mbps | 50ms |
| Custom | Your values | Your values |
Testing scenarios:
- App behavior on slow connection
- Timeout handling
- Retry logic
- Loading states
Recording and Replaying
Save Session
- File → Save Session
- Charles saves all traffic as
.chlsfile - Share with team for debugging
Export Requests
- Select requests
- File → Export Session
- Formats: HAR, JSON, Text, cURL
Export as cURL: Right-click → Copy cURL Request
curl -X POST 'https://api.example.com/login' \
-H 'Content-Type: application/json' \
-d '{"email":"user@test.com","password":"123"}'
Repeat Requests
- Select request
- Right-click → Repeat (single)
- Right-click → Repeat Advanced (multiple with delay)
Common Testing Scenarios
Testing Error Handling
Mock server errors:
// Create error-500.json
{
"error": "Internal Server Error",
"code": 500
}
Map Local with HTTP status:
- Tools → Rewrite
- Add rule for response status
- Match: any status, Replace: 500
Testing Timeout Behavior
- Enable Throttling
- Set very high latency (30000ms)
- Observe app timeout handling
Testing Empty States
Mock empty array response:
// empty-list.json
{
"items": [],
"total": 0
}
Authentication Testing
Test expired token handling:
- Breakpoint on request
- Modify Authorization header to invalid value
- Verify app handles 401 correctly
Charles Proxy with AI Assistance
AI tools can help with network debugging workflows.
What AI does well:
- Explain HTTP status codes and headers
- Generate mock JSON responses
- Convert cURL to code snippets
- Analyze traffic patterns
What still needs humans:
- Identify which traffic matters
- Understand business context of data
- Security implications of findings
- Real device testing decisions
FAQ
What is Charles Proxy?
Charles Proxy is an HTTP proxy and monitor application. It sits between your application and the internet, capturing all HTTP and HTTPS traffic for inspection and modification. Testers use it to debug API issues, mock server responses, simulate network conditions, and understand how applications communicate with backends.
Is Charles Proxy free?
Charles Proxy offers a 30-day free trial with 30-minute session limits. After trial, a license costs $50 per user (one-time purchase). Free alternatives include mitmproxy (command-line, open source), Proxyman (macOS native), and browser DevTools for basic inspection.
How do I use Charles with mobile apps?
Configure your mobile device’s WiFi proxy settings to point to your computer’s IP address and Charles port (default 8888). Both devices must be on the same network. For HTTPS traffic, install Charles SSL certificate on your device and trust it in security settings. Android 7+ apps may need additional configuration to trust user certificates.
Can Charles modify API responses?
Yes. Charles offers several modification options: Breakpoints for real-time editing, Map Local to return local files, Map Remote to redirect to different servers, and Rewrite rules for automatic header/body modifications. These features let you test edge cases, error handling, and UI states without backend changes.
Official Resources
See Also
- API Testing Tutorial - API testing fundamentals
- Appium Tutorial - Mobile testing automation
- Postman Tutorial - API testing tool
- API Security Testing - Security testing basics
