IP allowlist
The allowed-ips command (aliases: ip-allowlist, ips) mirrors
/settings/allowed-ips. Set it up and every request from a non-listed
IP — including the public API surface and the developer secret-key API
— is refused with HTTP 403.
Backed by /api/v1/app/ip-allowlist/*.
Paid feature. Trial accounts get HTTP 402 with code
feature_locked. The CLI surfaces the standardplan_requiredupgrade prompt with the exact upgrade URL.
Safety net. The IP-allowlist endpoints themselves skip the allowlist gate — you can always reach
splashify allowed-ipsfrom any IP to fix a bad entry. No risk of locking yourself out.
Quick start
# Add the office IP
splashify allowed-ips add --name "Bangalore office" \
--mode single --ip 203.0.113.4
# Add the VPN range
splashify allowed-ips add --name "VPN" \
--mode range --start 10.0.0.0 --end 10.0.0.255
# Confirm
splashify allowed-ips
# Remove
splashify allowed-ips delete <entry_id>Command reference
splashify allowed-ips — list
splashify allowed-ips # default
splashify allowed-ips list # alias| Backed by | GET /api/v1/app/ip-allowlist |
|---|
Response shape:
{
"success": true,
"entries": [
{
"entry_id": "uuid",
"name": "Bangalore office",
"mode": "single", // single | range
"ip_value": "203.0.113.4",
"range_start":"",
"range_end": "",
"created_at": "2026-05-20T14:00:00Z"
},
{
"entry_id": "uuid",
"name": "VPN",
"mode": "range",
"ip_value": "",
"range_start":"10.0.0.0",
"range_end": "10.0.0.255",
"created_at": "2026-05-20T14:01:00Z"
}
]
}splashify allowed-ips add — add an entry
# Single IP
splashify allowed-ips add --name "Office" --mode single --ip 203.0.113.4
# IP range
splashify allowed-ips add --name "VPN" --mode range \
--start 10.0.0.0 --end 10.0.0.255| Backed by | POST /api/v1/app/ip-allowlist |
|---|
| Flag | Required | Notes |
|---|---|---|
--name | yes | Friendly label, max 80 chars |
--mode | yes | single (default) | range |
--ip | when mode=single | IPv4 address |
--start | when mode=range | range start (IPv4, must be ≤ --end) |
--end | when mode=range | range end (IPv4) |
Limits:
- 50 entries per account — POST returns 400 once full. Delete a stale entry first.
- IPv4 only — IPv6 is not currently supported.
start ≤ endfor ranges — the backend rejects inverted ranges.
splashify allowed-ips delete — remove
splashify allowed-ips delete <entry_id>
splashify allowed-ips rm <entry_id> # alias| Backed by | DELETE /api/v1/app/ip-allowlist/:entry_id |
|---|
Effect: immediate. The cache invalidates in Redis on the next request, so subsequent calls from that IP are refused on the next round-trip.
Common workflows
Look up your current outbound IP
curl -s https://ifconfig.me
# 203.0.113.4
splashify allowed-ips add --name "$(hostname) ($(date -u +%F))" \
--mode single --ip "$(curl -s https://ifconfig.me)"Sync a list of CI runner IPs into the allowlist
# Read a file with one IP per line
while read -r ip; do
[ -z "$ip" ] && continue
splashify allowed-ips add --name "CI runner $ip" --mode single --ip "$ip"
done < ci-runners.txtDelete every entry older than 6 months
CUTOFF=$(date -u -v-6m '+%Y-%m-%dT%H:%M:%SZ') # macOS
# CUTOFF=$(date -u -d '6 months ago' '+%Y-%m-%dT%H:%M:%SZ') # linux
splashify allowed-ips | \
jq -r --arg c "$CUTOFF" '.entries[] | select(.created_at < $c) | .entry_id' | \
xargs -I{} splashify allowed-ips delete {}Audit which IPs are listed
splashify allowed-ips | jq '.entries[] |
if .mode == "single" then "\(.name)\t\(.ip_value)"
else "\(.name)\t\(.range_start) - \(.range_end)" end'Allowlist a single IP for 30 minutes (temp access)
RESP=$(splashify allowed-ips add --name "temp $(date +%s)" \
--mode single --ip "$(curl -s https://ifconfig.me)")
ID=$(echo "$RESP" | jq -r '.entry.entry_id')
echo "Temporary entry: $ID — will auto-delete in 30 minutes"
( sleep 1800 && splashify allowed-ips delete "$ID" ) &Behavior
When at least one entry is present:
- Every authenticated request to
/api/v1/app/*and the public developer API (/api/v1/public/*etc.) is gated. - Requests from a non-listed IP get HTTP 403 with body
{"success":false,"message":"IP not allowed"}. - The IP-allowlist endpoints themselves skip this check — you can
always reach
splashify allowed-ipsto fix mistakes.
When zero entries are present:
- The gate is a no-op — every authenticated IP gets through.
- This is the default state for new accounts.
Troubleshooting
feature_locked (402) — the allowlist is a paid add-on. Run
splashify subscription plans for the upgrade options.
HTTP 400 “Maximum 50 entries” — clean up old entries first
(splashify allowed-ips delete <id>).
Locked myself out — that’s exactly why the IP-allowlist endpoints
skip the gate. From a different machine, run splashify allowed-ips
with the same oc_live_ token and add your new IP. (The token-based
auth itself isn’t IP-gated either.)
add --mode range rejected — make sure --start and --end are
both valid IPv4 and start ≤ end. The CLI validates client-side, but
the backend re-validates with stricter parsing.
Cache lag — Redis caches the allowlist for ~10s. After a delete,
a request from that IP might still get through briefly before the
cache expires. Same for add — give it ~10s before testing from a
newly-added IP.
See also
splashify token—oc_live_tokens are separate from IP allowlist (a token + a non-listed IP still fails).splashify devices— list of session devices, which is gated by the allowlist when active.splashify subscription— confirm the feature is on your current plan.