Configuration Reference
View SourceComplete reference for all HTTPower configuration options.
Configuration Levels
HTTPower supports three levels of configuration with clear precedence:
- Per-Request (highest priority) - Options passed to individual requests
- Per-Client (medium priority) - Options in
HTTPower.new() - Global (lowest priority) - Options in
config.exs
Rule: More specific configuration overrides less specific.
Configuration Availability Matrix
This table shows which options are supported at each configuration level:
Adapter Selection
| Option | Global Config | Per-Client | Per-Request | Notes |
|---|---|---|---|---|
adapter | ✅ | ✅ | ✅ | Global: config :httpower, adapter: |
Testing
| Option | Global Config | Per-Client | Per-Request | Notes |
|---|---|---|---|---|
test_mode | ✅ | ❌ | ❌ | Global only |
Retry Configuration
| Option | Global Config | Per-Client | Per-Request | Notes |
|---|---|---|---|---|
max_retries | ✅ | ✅ | ✅ | |
retry_safe | ✅ | ✅ | ✅ | |
base_delay | ✅ | ✅ | ✅ | |
max_delay | ✅ | ✅ | ✅ | |
jitter_factor | ✅ | ✅ | ✅ |
Rate Limiting
| Option | Global Config | Per-Client | Per-Request | Notes |
|---|---|---|---|---|
rate_limit | ✅ | ✅ | ✅ | Global: nested config |
rate_limit_key | ❌ | ✅ | ✅ | Per-client/request only |
Circuit Breaker
| Option | Global Config | Per-Client | Per-Request | Notes |
|---|---|---|---|---|
circuit_breaker | ✅ | ✅ | ✅ | Global: nested config |
circuit_breaker_key | ❌ | ✅ | ✅ | Per-client/request only |
Logging
| Option | Global Config | Per-Client | Per-Request | Notes |
|---|---|---|---|---|
logging | ✅ | ✅ | ✅ | Global: nested config |
Request Options
| Option | Global Config | Per-Client | Per-Request | Notes |
|---|---|---|---|---|
base_url | ❌ | ✅ | ❌ | Per-client only |
headers | ❌ | ✅ | ✅ | Merged across levels |
body | ❌ | ❌ | ✅ | Per-request only (POST/PUT) |
timeout | ❌ | ✅ | ✅ | Per-client/request only |
ssl_verify | ❌ | ✅ | ✅ | Per-client/request only |
proxy | ❌ | ✅ | ✅ | Per-client/request only |
Global Configuration
Set in config/config.exs, config/prod.exs, etc.
config :httpower,
# Adapter (optional - auto-detects if not specified)
adapter: HTTPower.Adapter.Req, # or HTTPower.Adapter.Tesla
# Retry Configuration
max_retries: 3,
retry_safe: false,
base_delay: 1000,
max_delay: 30000,
jitter_factor: 0.2,
# Rate Limiting
rate_limit: [
enabled: false,
requests: 100,
per: :minute,
strategy: :wait,
max_wait_time: 5000
],
# Circuit Breaker
circuit_breaker: [
enabled: false,
failure_threshold: 5,
failure_threshold_percentage: nil,
window_size: 10,
timeout: 60_000,
half_open_requests: 1
],
# Logging
logging: [
enabled: true,
level: :info,
sanitize_headers: [], # Additional headers to sanitize (adds to defaults)
sanitize_body_fields: [] # Additional body fields to sanitize (adds to defaults)
],
# Test Mode
test_mode: falseAdapter Configuration
adapter
Type:
module() | {module(), term()}- Default: Auto-detected (prefers Req, then Tesla)
- Supported: Global config, per-client, per-request
- Description: HTTP adapter to use. Can be specified globally or overridden per-client/request.
Global Configuration (Simple):
# config/config.exs
config :httpower, adapter: HTTPower.Adapter.Req
# or
config :httpower, adapter: HTTPower.Adapter.TeslaPer-Client (Simple or with Pre-configured Client):
# Simple adapter module
client = HTTPower.new(
adapter: HTTPower.Adapter.Req,
base_url: "https://api.example.com"
)
# Adapter with pre-configured Tesla client
tesla_client = Tesla.client([
Tesla.Middleware.BaseURL.new("https://api.example.com"),
Tesla.Middleware.JSON
])
client = HTTPower.new(
adapter: {HTTPower.Adapter.Tesla, tesla_client}
)Per-Request Override:
# Override the adapter for a specific request
HTTPower.get(url, adapter: HTTPower.Adapter.Tesla)Retry Configuration
max_retries
- Type:
non_neg_integer() - Default:
3 - Description: Maximum number of retry attempts for failed requests.
- Example:
config :httpower, max_retries: 5
retry_safe
- Type:
boolean() - Default:
false - Description: Whether to retry on connection resets (
econnreset). Only enable for idempotent operations. - Example:
config :httpower, retry_safe: true
base_delay
- Type:
non_neg_integer()(milliseconds) - Default:
1000 - Description: Base delay for exponential backoff. Actual delay:
base_delay * 2^(attempt-1). - Example:
config :httpower, base_delay: 2000 # Start with 2 second delay
max_delay
- Type:
non_neg_integer()(milliseconds) - Default:
30000 - Description: Maximum delay cap for exponential backoff.
- Example:
config :httpower, max_delay: 60000 # Cap at 60 seconds
jitter_factor
- Type:
float()(0.0 to 1.0) - Default:
0.2 - Description: Randomization factor to prevent thundering herd. Delay multiplied by
(1 - jitter_factor * random()). - Example:
config :httpower, jitter_factor: 0.3 # 30% jitter
Retryable Conditions
HTTPower retries on:
- Status codes: 408, 429, 500, 502, 503, 504
- Errors:
:timeout,:closed,:econnrefused,:econnreset(ifretry_safe: true)
Rate Limiting Configuration
rate_limit.enabled
- Type:
boolean() - Default:
false - Description: Enable/disable rate limiting globally.
- Example:
config :httpower, rate_limit: [enabled: true]
rate_limit.requests
- Type:
pos_integer() - Default:
100 - Description: Maximum number of requests allowed per time window.
- Example:
config :httpower, rate_limit: [requests: 60]
rate_limit.per
Type:
:second | :minute | :hour- Default:
:minute - Description: Time window for rate limiting.
- Example:
config :httpower, rate_limit: [per: :second]
rate_limit.strategy
Type:
:wait | :error- Default:
:wait - Description: How to handle rate limit exceeded:
:wait- Block until tokens available (up tomax_wait_time):error- Return{:error, :too_many_requests}immediately
- Example:
config :httpower, rate_limit: [strategy: :error]
rate_limit.max_wait_time
- Type:
non_neg_integer()(milliseconds) - Default:
5000 - Description: Maximum time to wait for rate limit tokens when using
:waitstrategy. - Example:
config :httpower, rate_limit: [max_wait_time: 10000]
Per-Request Rate Limiting
HTTPower.get(url,
rate_limit: [requests: 10, per: :second],
rate_limit_key: "special_endpoint" # Custom bucket key
)Circuit Breaker Configuration
circuit_breaker.enabled
- Type:
boolean() - Default:
false - Description: Enable/disable circuit breaker globally.
- Example:
config :httpower, circuit_breaker: [enabled: true]
circuit_breaker.failure_threshold
- Type:
pos_integer() - Default:
5 - Description: Number of failures in sliding window before opening circuit.
- Example:
config :httpower, circuit_breaker: [failure_threshold: 3]
circuit_breaker.failure_threshold_percentage
- Type:
float()(0.0 to 100.0) ornil - Default:
nil - Description: Alternative to absolute threshold. Opens circuit when failure rate exceeds percentage. Requires
window_sizerequests minimum. - Example:
config :httpower, circuit_breaker: [ failure_threshold_percentage: 50.0, # Open at 50% failure rate window_size: 20 ]
circuit_breaker.window_size
- Type:
pos_integer() - Default:
10 - Description: Number of recent requests to track in sliding window.
- Example:
config :httpower, circuit_breaker: [window_size: 20]
circuit_breaker.timeout
- Type:
pos_integer()(milliseconds) - Default:
60000 - Description: How long circuit stays open before transitioning to half-open.
- Example:
config :httpower, circuit_breaker: [timeout: 30_000] # 30 seconds
circuit_breaker.half_open_requests
- Type:
pos_integer() - Default:
1 - Description: Number of test requests allowed in half-open state. All must succeed to close circuit.
- Example:
config :httpower, circuit_breaker: [half_open_requests: 3]
Per-Request Circuit Breaker
HTTPower.get(url,
circuit_breaker: [failure_threshold: 3, timeout: 30_000],
circuit_breaker_key: "payment_api" # Custom circuit key
)Manual Circuit Control
# Check state
HTTPower.Middleware.CircuitBreaker.get_state("my_api") # => :closed | :open | :half_open | nil
# Manually open
HTTPower.Middleware.CircuitBreaker.open_circuit("my_api")
# Manually close
HTTPower.Middleware.CircuitBreaker.close_circuit("my_api")
# Reset completely
HTTPower.Middleware.CircuitBreaker.reset_circuit("my_api")Logging Configuration
HTTPower uses a telemetry-based logging system that you opt into by attaching the logger.
Enabling Logging
# In your application.ex
def start(_type, _args) do
# Attach logger with options
HTTPower.Logger.attach(
level: :info,
log_headers: true,
log_body: true,
sanitize_headers: ["x-custom-token"],
sanitize_body_fields: ["secret_key"]
)
# ... rest of your supervision tree
endConfiguration Options
All options can be passed to HTTPower.Logger.attach/1 or configured via Application config (when using attach/0):
level
Type:
:debug | :info | :warning | :error- Default:
:info - Description: Log level for HTTP requests.
- Example:
HTTPower.Logger.attach(level: :debug) # Or in config config :httpower, :logging, level: :debug
log_headers
- Type:
boolean() - Default:
true - Description: Whether to include headers in logs.
- Example:
HTTPower.Logger.attach(log_headers: false)
log_body
- Type:
boolean() - Default:
true - Description: Whether to include request/response body in logs.
- Example:
HTTPower.Logger.attach(log_body: false)
sanitize_headers
- Type:
list(String.t()) - Default:
[](adds to built-in defaults) - Description: Additional header names to sanitize (case-insensitive). Additive - adds to defaults.
- Built-in defaults:
["authorization", "api-key", "x-api-key", "token", "cookie", "secret"] - Example:
HTTPower.Logger.attach(sanitize_headers: ["x-custom-token"]) # Or in config config :httpower, :logging, sanitize_headers: ["x-custom-token"]
sanitize_body_fields
- Type:
list(String.t()) - Default:
[](adds to built-in defaults) - Description: Additional body field names to sanitize. Additive - adds to defaults.
- Built-in defaults:
["password", "credit_card", "cvv", "card_number", "api_key", "token", "ssn"] - Example:
HTTPower.Logger.attach(sanitize_body_fields: ["tax_id", "secret"])
Disabling Logging
# Don't attach the logger
# HTTPower.Logger.attach() # Commented out
# Or detach programmatically
HTTPower.Logger.detach()Request Options
timeout
- Type:
pos_integer()(seconds) - Default:
60 - Description: Request timeout in seconds.
- Example:
HTTPower.get(url, timeout: 30)
headers
- Type:
map() - Default:
%{} - Description: HTTP headers for the request.
- Example:
HTTPower.get(url, headers: %{"authorization" => "Bearer token"})
body
Type:
String.t() | binary()- Default:
"" - Description: Request body for POST/PUT requests.
- Example:
HTTPower.post(url, body: Jason.encode!(%{name: "John"}))
ssl_verify
- Type:
boolean() - Default:
true - Description: Enable SSL certificate verification.
- Example:
HTTPower.get(url, ssl_verify: false) # Not recommended for production
proxy
Type:
:system | keyword()- Default:
:system - Description: Proxy configuration.
:systemuses system environment variables. - Example:
HTTPower.get(url, proxy: [host: "proxy.example.com", port: 8080])
Per-Client Configuration
Create reusable clients with HTTPower.new():
client = HTTPower.new(
base_url: "https://api.example.com",
headers: %{"authorization" => "Bearer #{token}"},
timeout: 30,
max_retries: 5,
circuit_breaker: [failure_threshold: 3],
rate_limit: [requests: 100, per: :minute]
)
# Use the client
HTTPower.get(client, "/users")
HTTPower.post(client, "/users", body: data)Test Mode
test_mode
- Type:
boolean() - Default:
false - Description: When enabled, blocks all real HTTP requests unless they include a
:plugoption. - Example:
# In test_helper.exs Application.put_env(:httpower, :test_mode, true) # In tests Req.Test.stub(HTTPower, fn conn -> Req.Test.json(conn, %{"status" => "ok"}) end) HTTPower.get(url, plug: {Req.Test, HTTPower}) # Allowed HTTPower.get(url) # Blocked with {:error, :network_blocked}
Configuration Priority Examples
Example 1: Override global with per-client
# Global config
config :httpower, max_retries: 3
# Per-client override
client = HTTPower.new(max_retries: 5) # Uses 5, not 3Example 2: Override per-client with per-request
client = HTTPower.new(timeout: 30)
# This request uses 60 second timeout
HTTPower.get(client, "/slow", timeout: 60)
# This request uses client's 30 second timeout
HTTPower.get(client, "/fast")Example 3: Header merging
# Global config
config :httpower, headers: %{"user-agent" => "HTTPower/1.0"}
# Per-client config
client = HTTPower.new(headers: %{"authorization" => "Bearer token"})
# Per-request config
HTTPower.get(client, "/api",
headers: %{"x-request-id" => "123"}
)
# Final headers include all three:
# {
# "user-agent" => "HTTPower/1.0",
# "authorization" => "Bearer token",
# "x-request-id" => "123"
# }Environment-Specific Configuration
Development
# config/dev.exs
config :httpower,
logging: [enabled: true, level: :debug],
circuit_breaker: [enabled: false], # Disabled for easier debugging
rate_limit: [enabled: false]Test
# config/test.exs
config :httpower,
test_mode: true,
logging: [enabled: false],
circuit_breaker: [enabled: false],
rate_limit: [enabled: false]Production
# config/prod.exs
config :httpower,
max_retries: 3,
circuit_breaker: [
enabled: true,
failure_threshold: 5,
timeout: 60_000
],
rate_limit: [
enabled: true,
requests: 100,
per: :minute,
strategy: :wait
],
logging: [
enabled: true,
level: :info,
sanitize_headers: ["authorization", "api-key"],
sanitize_body_fields: ["password", "credit_card", "cvv"]
]Next Steps
- Read Production Deployment Guide for production setup
- See Migrating from Tesla or Migrating from Req
- Check
guides/examples/for runnable examples