# Overview
Rayley lets you use a static IP address no matter where your service runs. Need to access a webhook or database that requires IP allowlisting? Rayley allows you to use a single IP address across hosting providers like Heroku, Netlify, Fly.io, and Railway to CI services like GitHub Actions and CircleCI.
Features [#features]
Rayley aims to be the most developer friendly way to get a static IP address whatever language or hosting provider you use. Features include:
Language support [#language-support]
Rayley uses standard CONNECT and forward proxy protocols to provide static IP addresses, which means any language or framework that supports these protocols works out of the box.
If you don't see your language or framework listed below, Rayley should still work with it. Read the [general proxy guide](#) and reach out if you have any questions or need help getting set up.
AI resources [#ai-resources]
Rayley integrates well with agentic workflows using the following resources:
Click "Open" in any page and ask questions about Rayley, static IPs, or anything else using your favorite AI assistant.
A machine-friendly version of the documentation, designed to be easily parsed by LLMs, is available at [`llms.txt`](https://rayley.com/llms.txt) and [`llms-full.txt`](https://rayley.com/llms-full.txt).
# Python
Use a static IP address from any Python app by routing requests through Rayley's proxy.
You can use any HTTP client that supports proxy configuration. Below are examples using the popular requests library and the modern httpx client.
# requests
The [requests](https://docs.python-requests.org/) library supports proxy configuration through the `proxies` parameter. Embed the token in the proxy URL as basic auth credentials.
Prerequisites [#prerequisites]
* A Rayley account with a **Proxy Token** (`rpt_*`). Create one in the [dashboard](https://dash.rayley.com/tokens).
Installation [#installation]
```bash
pip install requests
```
Quick start [#quick-start]
Pass a `proxies` dict to route the request through your static IP address. Embed the token in the proxy URL as basic auth credentials:
```python title="proxy_request.py"
import requests
proxy_url = "https://token:rpt_your_token_here@proxy.rayley.com"
response = requests.get(
"https://api.example.com/data",
proxies={"https": proxy_url},
timeout=30,
)
print(response.json())
```
Session [#session]
Use a `Session` to reuse the proxy configuration across requests without passing `proxies` each time:
```python title="proxy_session.py"
import requests
proxy_url = "https://token:rpt_your_token_here@proxy.rayley.com"
session = requests.Session()
session.proxies = {"https": proxy_url}
# These requests use your static IP Address
response = session.get("https://api.example.com/data", timeout=30)
print(response.json())
# Requests without the session go directly to the destination
response2 = requests.get("https://api.example.com/other-data", timeout=30)
print(response2.json())
```
Full example [#full-example]
Below is a command-line script you can use to test your Proxy Token. It reads the token from the `RAYLEY_TOKEN` environment variable and takes an optional URL argument (defaulting to `https://example.com`) to make a request using your static IP address.
```python title="example.py"
import os
import sys
import requests
proxy_token = os.environ.get("RAYLEY_TOKEN")
target_url = sys.argv[1] if len(sys.argv) > 1 else "https://example.com/"
if not proxy_token:
print("Set RAYLEY_TOKEN to your Proxy Token.", file=sys.stderr)
sys.exit(1)
proxy_url = f"https://token:{proxy_token}@proxy.rayley.com"
response = requests.get(
target_url,
proxies={"https": proxy_url},
timeout=30,
)
if response.status_code == 407:
print("Authentication failed. Check your RAYLEY_TOKEN.", file=sys.stderr)
sys.exit(1)
response.raise_for_status()
print(f"Status: {response.status_code}")
print(response.json())
```
Run it:
```bash
RAYLEY_TOKEN=rpt_your_token python example.py https://example.com/
```
# httpx
[httpx](https://www.python-httpx.org/) is a modern HTTP client for Python with async support. It supports proxy configuration through the `proxy` parameter, with the token embedded in the proxy URL.
Prerequisites [#prerequisites]
* A Rayley account with a **Proxy Token** (`rpt_*`). Create one in the [dashboard](https://dash.rayley.com/tokens).
Installation [#installation]
```bash
pip install httpx
```
Quick start [#quick-start]
Create an `httpx.Client` with the `proxy` parameter to route all requests through your static IP address. Embed the token in the proxy URL as basic auth credentials:
```python title="proxy_request.py"
import httpx
proxy_url = "https://token:rpt_your_token_here@proxy.rayley.com"
with httpx.Client(proxy=proxy_url, timeout=30) as client:
response = client.get("https://api.example.com/data")
print(response.json())
```
async client [#async-client]
If you're using `asyncio` or another async framework, swap `Client` for `AsyncClient`. The proxy configuration is identical. httpx handles the rest:
```python title="proxy_async.py"
import httpx
proxy_url = "https://token:rpt_your_token_here@proxy.rayley.com"
async with httpx.AsyncClient(proxy=proxy_url, timeout=30) as client:
response = await client.get("https://api.example.com/data")
print(response.json())
```
Full example [#full-example]
Below is a command-line script you can use to test your Proxy Token. It reads the token from the `RAYLEY_TOKEN` environment variable and takes an optional URL argument (defaulting to `https://example.com`) to make a request using your static IP Address.
```python title="example.py"
import os
import sys
import httpx
proxy_token = os.environ.get("RAYLEY_TOKEN")
target_url = sys.argv[1] if len(sys.argv) > 1 else "https://example.com/"
if not proxy_token:
print("Set RAYLEY_TOKEN to your Proxy Token.", file=sys.stderr)
sys.exit(1)
proxy_url = f"https://token:{proxy_token}@proxy.rayley.com"
with httpx.Client(proxy=proxy_url, timeout=30) as client:
response = client.get(target_url)
if response.status_code == 407:
print("Authentication failed. Check your RAYLEY_TOKEN.", file=sys.stderr)
sys.exit(1)
response.raise_for_status()
print(f"Status: {response.status_code}")
print(response.json())
```
Run it:
```bash
RAYLEY_TOKEN=rpt_your_token python example.py https://example.com/
```
# Node.js
Use a static IP address from any Node.js app by routing requests through Rayley's proxy.
You can use any HTTP client that supports proxy configuration. Below are examples using the native `fetch` API and the popular Axios library.
# Axios
[Axios](https://axios-http.com/) has built-in proxy support that works with Rayley out of the box. Configure the proxy on a per-client or global basis to route requests through your static IP address.
Prerequisites [#prerequisites]
* A Rayley account with a **Proxy Token** (`rpt_*`). Create one in the [dashboard](https://dash.rayley.com/tokens).
Installation [#installation]
npm
pnpm
yarn
bun
```bash
npm install axios
```
```bash
pnpm add axios
```
```bash
yarn add axios
```
```bash
bun add axios
```
Quick start [#quick-start]
Create an Axios client with the `proxy` option to route its requests through your static IP address. Pass the token via the `Proxy-Authorization` header:
```js title="proxy-request.mjs"
import axios from 'axios';
const client = axios.create({
proxy: {
protocol: 'https',
host: 'proxy.rayley.com',
},
headers: {
'Proxy-Authorization': 'Bearer rpt_your_token_here',
},
});
const response = await client.get('https://api.example.com/data');
console.log(response.data);
```
Global defaults [#global-defaults]
Set `axios.defaults` to route all requests through Rayley globally, including from libraries that use `axios` internally:
```js title="proxy-all.mjs"
import axios from 'axios';
axios.defaults.proxy = {
protocol: 'https',
host: 'proxy.rayley.com',
};
axios.defaults.headers.common['Proxy-Authorization'] = 'Bearer rpt_your_token_here';
// All axios requests now go through the proxy
const response = await axios.get('https://api.example.com/data');
console.log(response.data);
```
Full example [#full-example]
Below is a script you can use to test your Proxy Token. It reads the token from the `RAYLEY_TOKEN` environment variable and takes an optional URL argument (defaulting to `https://example.com`) to make a request using your static IP address.
```js title="example.mjs"
import axios from 'axios';
const proxyToken = process.env.RAYLEY_TOKEN;
const targetUrl = process.argv[2] || 'https://example.com/';
if (!proxyToken) {
console.error('Set RAYLEY_TOKEN to your Proxy Token.');
process.exit(1);
}
const client = axios.create({
proxy: {
protocol: 'https',
host: 'proxy.rayley.com',
},
headers: {
'Proxy-Authorization': `Bearer ${proxyToken}`,
},
timeout: 30000,
});
try {
const response = await client.get(targetUrl);
if (response.status === 407) {
throw new Error('Authentication failed. Check your RAYLEY_TOKEN.');
}
console.log(`Status: ${response.status}`);
console.log(JSON.stringify(response.data, null, 2));
} catch (error) {
if (error.response?.status === 407) {
console.error('Authentication failed. Check your RAYLEY_TOKEN.');
} else {
console.error('Request failed:', error.message);
}
process.exit(1);
}
```
Run it:
```bash
RAYLEY_TOKEN=rpt_your_token node example.mjs https://example.com/
```
# fetch
Node.js 18+ ships with `fetch` powered by a stripped-down [undici](https://undici.nodejs.org/). It does not support proxies out of the box to compliant to the WHATWG Fetch spec.
Install the full undici library to get access to the `ProxyAgent` class, which implements the necessary proxy support. You can choose to route all `fetch` calls through the proxy by setting a global dispatcher, or specify the agent on a per-request basis.
Prerequisites [#prerequisites]
* A Rayley account with a **Proxy Token** (`rpt_*`). Create one in the [dashboard](https://dash.rayley.com/tokens).
Installation [#installation]
npm
pnpm
yarn
bun
```bash
npm install undici
```
```bash
pnpm add undici
```
```bash
yarn add undici
```
```bash
bun add undici
```
`undici` already ships with Node.js, but installing it explicitly lets you import `ProxyAgent`.
Quick start [#quick-start]
Set a global `ProxyAgent` dispatcher to route all `fetch` calls through your static IP address. Pass the token via the `token` option on the agent:
```js title="proxy-all.mjs"
import { ProxyAgent, setGlobalDispatcher } from 'undici';
const proxyAgent = new ProxyAgent({
uri: 'https://proxy.rayley.com',
token: 'Bearer rpt_your_token_here',
});
setGlobalDispatcher(proxyAgent);
// All fetch requests now go through the proxy
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log(data);
```
Using this method, even libraries that use `fetch` internally automatically use Rayley.
Use a static IP Address for specific requests only [#use-a-static-ip-address-for-specific-requests-only]
Import `fetch` from undici directly and pass a `dispatcher` option to control which requests go through the proxy:
```js title="proxy-selective.mjs"
import { ProxyAgent, fetch } from 'undici';
const proxyAgent = new ProxyAgent({
uri: 'https://proxy.rayley.com',
token: 'Bearer rpt_your_token_here',
});
// This request uses your static IP Address
const response = await fetch('https://api.example.com/data', {
dispatcher: proxyAgent,
});
const data = await response.json();
console.log(data);
// This request goes directly to the destination without using Rayley
const response2 = await fetch('https://api.example.com/other-data');
const data2 = await response2.json();
console.log(data2);
```
Full example [#full-example]
Below is a script you can use to test your Proxy Token. It reads the token from the `RAYLEY_TOKEN` environment variable and takes an optional URL argument (defaulting to `https://example.com`) to make a request using your static IP address.
```js title="example.mjs"
import { ProxyAgent, setGlobalDispatcher } from 'undici';
const proxyToken = process.env.RAYLEY_TOKEN;
const targetUrl = process.argv[2] || 'https://example.com/';
if (!proxyToken) {
console.error('Set RAYLEY_TOKEN to your Proxy Token.');
process.exit(1);
}
const proxyAgent = new ProxyAgent({
uri: 'https://proxy.rayley.com',
token: `Bearer ${proxyToken}`,
});
setGlobalDispatcher(proxyAgent);
try {
const response = await fetch(targetUrl);
if (response.status === 407) {
throw new Error('Authentication failed. Check your RAYLEY_TOKEN.');
}
const data = await response.json();
console.log(`Status: ${response.status}`);
console.log(JSON.stringify(data, null, 2));
} catch (error) {
console.error('Request failed:', error.message);
process.exit(1);
}
```
Run it:
```bash
RAYLEY_TOKEN=rpt_your_token node example.mjs https://example.com/
```
# Go
Go's standard library `net/http` supports proxies through the `Transport.Proxy` field. No external dependencies needed.
Prerequisites [#prerequisites]
* A Rayley account with a **Proxy Token** (`rpt_*`). Create one in the [dashboard](https://dash.rayley.com/tokens).
Quick start [#quick-start]
Set `Transport.Proxy` to route requests through your static IP address. Embed the token in the proxy URL as basic auth credentials:
```go title="main.go"
package main
import (
"fmt"
"io"
"net/http"
"net/url"
)
func main() {
proxyURL, _ := url.Parse("https://token:rpt_your_token_here@proxy.rayley.com")
client := &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyURL(proxyURL),
},
}
resp, err := client.Get("https://api.example.com/data")
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}
```
Other ways to connect [#other-ways-to-connect]
Set the `HTTPS_PROXY` environment variable to route all requests through Rayley without any code changes:
```bash
export HTTPS_PROXY="https://token:rpt_your_token_here@proxy.rayley.com"
```
Go's default transport uses `http.ProxyFromEnvironment`, so all requests pick up the proxy automatically:
```go title="main.go"
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
// Uses HTTPS_PROXY environment variable automatically
resp, err := http.Get("https://api.example.com/data")
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}
```
Full example [#full-example]
Below is a script you can use to test your Proxy Token. It reads the token from the `RAYLEY_TOKEN` environment variable and takes an optional URL argument (defaulting to `https://example.com`) to make a request using your static IP address.
```go title="example.go"
package main
import (
"fmt"
"io"
"net/http"
"net/url"
"os"
)
func main() {
proxyToken := os.Getenv("RAYLEY_TOKEN")
targetURL := "https://example.com/"
if len(os.Args) > 1 {
targetURL = os.Args[1]
}
if proxyToken == "" {
fmt.Fprintln(os.Stderr, "Set RAYLEY_TOKEN to your Proxy Token.")
os.Exit(1)
}
proxyURL, err := url.Parse(fmt.Sprintf("https://token:%s@proxy.rayley.com", proxyToken))
if err != nil {
fmt.Fprintf(os.Stderr, "Invalid proxy URL: %v\n", err)
os.Exit(1)
}
client := &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyURL(proxyURL),
},
}
resp, err := client.Get(targetURL)
if err != nil {
fmt.Fprintf(os.Stderr, "Request failed: %v\n", err)
os.Exit(1)
}
defer resp.Body.Close()
if resp.StatusCode == 407 {
fmt.Fprintln(os.Stderr, "Authentication failed. Check your RAYLEY_TOKEN.")
os.Exit(1)
}
body, _ := io.ReadAll(resp.Body)
fmt.Printf("Status: %d\n", resp.StatusCode)
fmt.Println(string(body))
}
```
Run it:
```bash
RAYLEY_TOKEN=rpt_your_token go run example.go https://example.com/
```
# curl
curl supports proxies through the `--proxy` flag. This works for quick tests, scripts, and CI pipelines.
Prerequisites [#prerequisites]
* A Rayley account with a **Proxy Token** (`rpt_*`). Create one in the [dashboard](https://dash.rayley.com/tokens).
Quick start [#quick-start]
```bash
curl --proxy "https://token:rpt_your_token_here@proxy.rayley.com" \
https://api.example.com/data
```
Your request to `api.example.com` now routes through Rayley and originates from your assigned static IP.
Shell script example [#shell-script-example]
```bash title="proxy-request.sh"
#!/usr/bin/env bash
set -euo pipefail
token="${RAYLEY_TOKEN:?Set RAYLEY_TOKEN to your Proxy Token}"
url="${1:-"https://example.com"}"
body="$(curl --proxy "https://token:${token}@proxy.rayley.com" "$url"))"
echo "$body"
```
Run it:
```bash
chmod +x ./proxy-request.sh
RAYLEY_TOKEN=rpt_your_token bash ./proxy-request.sh https://httpbin.org/get
```
Authentication [#authentication]
The proxy URL embeds the token as basic auth credentials. The username is the literal string `token` and the password is your Proxy Token:
```
https://token:@proxy.rayley.com
```
You can also set the `Proxy-Authorization` header with the value `Bearer ` and use the proxy URL without credentials:
```bash title="proxy-request-header.sh"
curl --proxy "https://proxy.rayley.com" \
-H "Proxy-Authorization: Bearer rpt_your_token_here" \
https://api.example.com/data
```
# Bun
Bun's `fetch` has built-in proxy support via the `proxy` option. No extra packages needed.
Prerequisites [#prerequisites]
* A Rayley account with a **Proxy Token** (`rpt_*`). Create one in the [dashboard](https://dash.rayley.com/tokens).
Quick start [#quick-start]
Pass the `proxy` option to `fetch` to route the request through your static IP address. Send the token via the `Proxy-Authorization` header:
```js title="proxy-request.ts"
const response = await fetch('https://api.example.com/data', {
proxy: 'https://proxy.rayley.com',
headers: {
'Proxy-Authorization': 'Bearer rpt_your_token_here',
},
});
const data = await response.json();
console.log(data);
```
Other ways to connect [#other-ways-to-connect]
Embed the token in the proxy URL instead of using the `Proxy-Authorization` header:
```js title="proxy-url-auth.ts"
const response = await fetch('https://api.example.com/data', {
proxy: 'https://token:rpt_your_token_here@proxy.rayley.com',
});
const data = await response.json();
console.log(data);
```
Full example [#full-example]
Below is a script you can use to test your Proxy Token. It reads the token from the `RAYLEY_TOKEN` environment variable and takes an optional URL argument (defaulting to `https://example.com`) to make a request using your static IP address.
```js title="example.ts"
const proxyToken = process.env.RAYLEY_TOKEN;
const targetUrl = Bun.argv[2] || 'https://example.com/';
if (!proxyToken) {
console.error('Set RAYLEY_TOKEN to your Proxy Token.');
process.exit(1);
}
const response = await fetch(targetUrl, {
proxy: 'https://proxy.rayley.com',
headers: {
'Proxy-Authorization': `Bearer ${proxyToken}`,
},
});
if (response.status === 407) {
console.error('Authentication failed. Check your RAYLEY_TOKEN.');
process.exit(1);
}
const data = await response.json();
console.log(`Status: ${response.status}`);
console.log(JSON.stringify(data, null, 2));
```
Run it:
```bash
RAYLEY_TOKEN=rpt_your_token bun example.ts https://example.com/
```