# 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/ ```