17NAS DEVELOPER API

IP查詢 API

一個請求取得訪客的真實 IP、走的是 IPv4 還是 IPv6、國家地區、ASN、電信業者與時區。中國大陸直連,支付寶付款。

17nas.com 的IPv6 檢測工具本身就跑在這套邊緣上——本站至今已完成 181,251 次檢測,你在本站做的每一次檢測,走的都是同一條鏈路。

介面位址
ipapi.17nas.com
認證方式
Bearer API Key
輸出格式
JSON / Text
curl
curl https://ipapi.17nas.com/v1/ip \
  -H "Authorization: Bearer 17nas_live_xxx"
{
  "ip": "203.0.113.10",
  "protocol": "IPv4",
  "country": { "code": "CN" },
  "asn": { "number": 4134 },
  "edge": { "colo": "HKG" }
}
累計檢測
181,251 次
獨立 IP
47,207 個
近 30 天
24,357 次
服務節點
全球邊緣網路
LIVE DEMO

不用註冊,先看它能不能跑

點一下,用你現在這條網路的真實 IP 呼叫一次公開端點,看到的是沒有加工過的原始回應。注意這裡示範的是公開端點,欄位結構與帶 Key 的 /v1/ip 不同,後者以下方文件為準。

GET https://ip.17nas.com?format=json
點擊上面的按鈕,這裡會顯示真實回應結果。
剛才呼叫的是公開端點,適合臨時查詢與手動排查。

一旦要接進你自己的網站、APP、小程式或伺服器端腳本,就需要 API Key:公開端點沒有獨立額度、沒有呼叫統計、沒有錯誤紀錄,也沒有 IP 白名單,隨時可能因為被濫用而限速,出問題你查不到任何日誌。

免費領 1,000 次/月開發額度
USE CASES

大家都拿它做什麼

下面每段程式碼都可以直接複製去跑,把 17nas_live_xxx 換成你自己的 Key 就行。

家用寬頻 IP 一變就更新 DDNS

家用寬頻的公網 IP 隨時會變,NAS 的網域就會指向一個不存在的位址。用 cron 每 5 分鐘查一次,只有變了才去呼叫 DNS 服務商的介面——比無腦每次都更新省事,也不會把 DNS 介面的額度打滿。

ddns-update.sh
#!/bin/bash
# crontab: */5 * * * * /opt/ddns-update.sh
KEY="17nas_live_xxx"
CACHE="/tmp/.last_wan_ip"

IP=$(curl -fsS --max-time 10 "https://ipapi.17nas.com/v1/ip?format=text" \
      -H "Authorization: Bearer $KEY") || exit 0

# 拿不到或者跟上次一樣就直接退出,不打擾 DNS 服務商
[ -z "$IP" ] && exit 0
[ "$IP" = "$(cat "$CACHE" 2>/dev/null)" ] && exit 0

echo "$IP" > "$CACHE"
logger -t ddns "WAN IP changed to $IP"

# 換成你自己的 DNS 服務商介面
curl -fsS -X POST "https://dns.example.com/api/record" \
  -d "name=nas.example.com&type=A&value=$IP"

公網 IP 變動微信告警

不想自動改 DNS,只想知道「我家 IP 什麼時候變了」。IP 一變就推一條通知,順帶把電信業者和歸屬地一起報出來——業者換了位址池的時候特別有用。

wan_watch.py
import json, pathlib, requests

KEY = "17nas_live_xxx"
PUSH = "https://www.pushplus.plus/send"   # 換成你自己的推播通道
TOKEN = "your_pushplus_token"
CACHE = pathlib.Path("/var/tmp/wan_ip.json")

r = requests.get(
    "https://ipapi.17nas.com/v1/ip",
    headers={"Authorization": f"Bearer {KEY}"},
    timeout=10,
)
r.raise_for_status()
now = r.json()

# 剩餘額度就在回應標頭裡,不用額外查一次
print("本月剩餘呼叫:", r.headers.get("X-Quota-Remaining"))

last = json.loads(CACHE.read_text()) if CACHE.exists() else {}
if last.get("ip") == now["ip"]:
    raise SystemExit(0)

CACHE.write_text(json.dumps(now))
requests.post(PUSH, json={
    "token": TOKEN,
    "title": f"公網 IP 變了:{now['ip']}",
    "content": (
        f"通訊協定 {now['protocol']}\n"
        f"電信業者 {now['asn']['organization']} (AS{now['asn']['number']})\n"
        f"地區 {now.get('city') or '-'} / {now['country']['code']}\n"
        f"原 IP {last.get('ip', '無紀錄')}"
    ),
}, timeout=10)

異地登入風控

使用者登入時記下 IP 的歸屬地和 ASN。下次換了個地區、或者從家用寬頻跳到機房 IP,就觸發二次驗證。這比單純記 IP 可靠——家用寬頻 IP 本來就天天變,但歸屬地和電信業者不會。

login_risk.php
<?php
/** 登入成功後呼叫,回傳是否需要二次驗證 */
function login_needs_verify(PDO $pdo, int $userId): bool
{
    $ch = curl_init('https://ipapi.17nas.com/v1/ip');
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 5,
        CURLOPT_HTTPHEADER => ['Authorization: Bearer 17nas_live_xxx'],
    ]);
    $body = curl_exec($ch);
    $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    // 風控介面掛了不能把使用者擋在門外,降級放行
    if ($status !== 200 || !$body) {
        error_log('ip-api unavailable, skip risk check');
        return false;
    }

    $now = json_decode($body, true);
    $fingerprint = $now['country']['code'] . '|' . $now['region'] . '|' . $now['asn']['number'];

    $stmt = $pdo->prepare('SELECT ip_fingerprint FROM user_login_env WHERE user_id = ?');
    $stmt->execute([$userId]);
    $known = $stmt->fetchColumn();

    $pdo->prepare('REPLACE INTO user_login_env (user_id, ip_fingerprint, updated_at) VALUES (?, ?, NOW())')
        ->execute([$userId, $fingerprint]);

    return $known !== false && $known !== $fingerprint;
}

按 IPv4/IPv6 決定回源

雙棧環境下,使用者走 IPv6 進來但你的後端只有 IPv4,中間那一跳的轉換會白白多花幾十毫秒。先判斷通訊協定,再決定走哪條回源鏈路或者回傳哪套資源位址。

origin-select.js
const KEY = process.env.IP_API_KEY;

async function pickOrigin() {
  const res = await fetch('https://ipapi.17nas.com/v1/ip', {
    headers: { Authorization: `Bearer ${KEY}` },
    signal: AbortSignal.timeout(5000),
  });

  if (res.status === 429) {
    // 額度用盡或觸發限速,X-Quota-Reset 告訴你什麼時候恢復
    console.warn('quota/rate limited, reset at', res.headers.get('X-Quota-Reset'));
    return ORIGINS.v4;   // 降級到預設線路,不要拋錯
  }
  if (!res.ok) return ORIGINS.v4;

  const { protocol, edge } = await res.json();
  console.log('edge colo:', edge.colo);
  return protocol === 'IPv6' ? ORIGINS.v6 : ORIGINS.v4;
}

const ORIGINS = {
  v4: 'https://origin-v4.example.com',
  v6: 'https://origin-v6.example.com',
};

小程式 / APP 日誌留存

小程式和 APP 上架要求留存使用者操作日誌,其中 IP 和歸屬地是必填項。關鍵是必須在伺服器端呼叫——把 Key 打進前端安裝包,等於把你的額度送給所有人。

audit_log.php
<?php
/**
 * 伺服器端記錄一條合規日誌。
 * 注意:Key 只能放在伺服器端。小程式/APP 端把請求打到你自己的伺服器,
 * 由伺服器再去呼叫 17NAS,前端永遠接觸不到 Key。
 */
function write_audit_log(PDO $pdo, int $userId, string $action): void
{
    $ctx = ['ip' => null, 'country' => null, 'isp' => null];

    $ch = curl_init('https://ipapi.17nas.com/v1/ip');
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 5,
        CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('IP_API_KEY')],
    ]);
    if ($body = curl_exec($ch)) {
        $data = json_decode($body, true);
        $ctx = [
            'ip' => $data['ip'] ?? null,
            'country' => $data['country']['code'] ?? null,
            'isp' => $data['asn']['organization'] ?? null,
        ];
    }
    curl_close($ch);

    $pdo->prepare(
        'INSERT INTO audit_logs (user_id, action, ip, country, isp, created_at)
         VALUES (?, ?, ?, ?, ?, NOW())'
    )->execute([$userId, $action, $ctx['ip'], $ctx['country'], $ctx['isp']]);
}

多線路出口 IP 巡檢

手上有一堆 VPS、Proxy 或者多撥線路,想確認每條線路真實的出口 IP 和落地機房。逐條跑一遍,出口不對的立刻能發現。

egress-check.sh
#!/bin/bash
KEY="17nas_live_xxx"
IFACES=("eth0" "eth1" "wg0")

printf "%-8s %-40s %-10s %s\n" "介面" "出口IP" "通訊協定" "電信業者"
for IF in "${IFACES[@]}"; do
  JSON=$(curl -fsS --max-time 8 --interface "$IF" \
          "https://ipapi.17nas.com/v1/ip" \
          -H "Authorization: Bearer $KEY" 2>/dev/null)

  if [ -z "$JSON" ]; then
    printf "%-8s %-40s %-10s %s\n" "$IF" "(不通)" "-" "-"
    continue
  fi

  printf "%-8s %-40s %-10s %s\n" \
    "$IF" \
    "$(echo "$JSON" | jq -r .ip)" \
    "$(echo "$JSON" | jq -r .protocol)" \
    "$(echo "$JSON" | jq -r .asn.organization)"
done
COMPARISON

要不要自己搭一個?

取一個真實 IP 本身不難,難的是長期維護它。下面是三條路各自要付出的成本。

對比項 自己搭 國外服務 17NAS
中國大陸存取延遲取決於你的伺服器跨境,波動大邊緣就近回應
IPv6 支援要自己設定雙棧多數支援原生雙棧
GeoIP / ASN 資料庫更新自己下載、自己更新服務方維護服務方維護
日常維護憑證、機器、監控全歸你無無
呼叫統計與錯誤紀錄要自己寫有控制台內建
付款方式—多數只收信用卡支付寶
出問題找誰找自己英文工單,隔時區中文回饋,同時區
起步成本一台伺服器 + 時間按量計費免費 1,000 次/月

說句公道話:如果你只是個人玩票、每天呼叫幾次,自己用 Nginx 回傳 $remote_addr 就夠了,不用花這個錢。真正值得買的是那些「掛了會有人找你」的場景——線上業務、要留存日誌、要長期穩定跑的自動化。

PLANS

API方案

額度用完就停止呼叫,不會產生欠費,也不會自動扣款。年度方案按月釋出額度。

註冊就能用,不用付錢

註冊開發者可建立 1 個 API Key,每月 1,000 次呼叫額度,IPv4 與 IPv6 共用。夠你把接入調通再決定要不要買。僅限個人開發測試,商業使用請選下方方案。

免費建立 API Key

API 開發版

¥19.9/月
  • 100,000 次/月
  • 5 QPS 併發
  • 1 個 API Key
  • 不支援白名單
  • 7 天錯誤紀錄
  • 允許商業使用

API 商業版

¥299.0/月
  • 5,000,000 次/月
  • 50 QPS 併發
  • 5 個 API Key
  • 100 條 IP/CIDR 白名單
  • 90 天錯誤紀錄
  • 允許商業使用

企業客製

¥999/月起
  • 客製額度與併發
  • 合約與專屬 SLA
  • 專屬技術支援
  • 可私有化部署
聯絡我們
額度不夠用?不用急著升級

已有付費方案的使用者可以隨時加購一次性加量包:¥14.90 / 100,000 次、¥59.90 / 1,000,000 次。加量包疊加在本期額度之上,隨本期一起到期,不自動續約。在控制台直接購買。

目前支援的付款方式:Stripe。企業合約 SLA 與一般商業方案分開提供。

DATA

順便說個數據:IPv6 在中國大陸普及到什麼程度了

基於 17NAS 訪客在 2026 年 2 月 5 日 至今的 181,251 次真實檢測(47,207 個獨立 IP)。這些檢測走的就是本頁在賣的這套邊緣網路。

雙棧(IPv4 + IPv6)最理想的狀態,兩種通訊協定都能用
61.2%108,657 次
僅 IPv4還沒開通 IPv6,或路由器/防火牆沒放行
35.8%63,473 次
僅 IPv6較少見,部分行動網路和純 IPv6 環境
1.4%2,401 次
未取得結果弱網、逾時或 Proxy 環境下的檢測失敗
1.6%2,763 次

合計 62.6% 的訪客具備 IPv6 能力。需要說明的是:會主動來 17NAS 測 IPv6 的人,本身就比一般網友更關心 IPv6,所以這個樣本存在自我選擇偏差,不能當作全國普及率,只能反映「關心 IPv6 的這批人」的實際情況。資料每小時更新。想測測你自己的網路?IPv6 檢測工具在這裡。

REFERENCE

介面文件

先看下面的三步接入,五分鐘能跑通第一個請求;細節再往下翻。

  1. 1
    建立 API Key

    登入後在控制台點「建立 API Key」。金鑰只完整顯示一次,伺服器端只存雜湊,遺失只能重新產生。

    前往控制台建立
  2. 2
    帶上 Bearer 標頭發一個請求

    把金鑰放進 Authorization 標頭,直接請求 /v1/ip。

    看請求範例
  3. 3
    讀回應標頭裡的額度

    每次成功回應都帶 X-Quota-Remaining,不用額外呼叫介面查用量。

    查看回應標頭說明

身分認證

在伺服器端請求的 Authorization 標頭中送出 Bearer 金鑰。

Authorization: Bearer 17nas_live_xxxxxxxxx

不要把金鑰放進瀏覽器腳本、APP 或小程式安裝包——這些都能被反編譯出來。前端需要用時,讓前端請求你自己的伺服器,由伺服器代為呼叫。可以在控制台設定 IP/CIDR 白名單進一步限制來源。

GET/v1/ip

ipapi.17nas.com

回傳本次 HTTP 連線實際使用的 IP 和通訊協定。請求走 IPv4 就回傳 IPv4,走 IPv6 就回傳 IPv6,不需要額外指定。

參數位置說明
AuthorizationHeader必填。Bearer <你的 API Key>
formatQuery選填。json(預設)或 text;text 只回傳純 IP,適合 shell 直接取值
# JSON(預設)
curl https://ipapi.17nas.com/v1/ip \
  -H "Authorization: Bearer 17nas_live_xxx"

# 只回傳純文字 IP,適合 shell 指令碼直接取值
curl "https://ipapi.17nas.com/v1/ip?format=text" \
  -H "Authorization: Bearer 17nas_live_xxx"

# 強制走 IPv4 / IPv6 查詢,用 curl 自己的參數控制
curl -4 https://ipapi.17nas.com/v1/ip -H "Authorization: Bearer 17nas_live_xxx"
curl -6 https://ipapi.17nas.com/v1/ip -H "Authorization: Bearer 17nas_live_xxx"

回應欄位

200 OK
{
  "ip": "203.0.113.10",
  "protocol": "IPv4",
  "country": { "code": "CN" },
  "region": "Guangdong",
  "city": "Shenzhen",
  "timezone": "Asia/Shanghai",
  "asn": { "number": 4134, "organization": "CHINANET" },
  "edge": { "colo": "HKG" },
  "request_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "generated_at": "2026-07-26T09:00:00.000Z"
}
欄位型別說明
ipstring本次連線的公網 IP
protocolstringIPv4 或 IPv6
country.codestringISO 3166-1 兩位國家代碼,取不到為 null
region / citystring省/州與城市,英文;精度取決於邊緣資料庫,可能為 null
timezonestringIANA 時區名稱,如 Asia/Shanghai
asn.numbernumber自治系統號碼;取不到為 0
asn.organizationstring電信業者名稱,可能為 null
edge.colostring處理本次請求的邊緣節點三字碼
request_idstring本次請求的唯一 ID,回報問題時帶上它

地理位置欄位依賴邊緣節點的 GeoIP 資料,行動網路、衛星鏈路、企業 NAT 出口和部分 Proxy 下可能不準或為空。請把這些欄位當參考而不是事實,不要用它做強制性的地域攔截。

額度回應標頭

每次成功回應都會帶上目前額度狀態,不需要額外呼叫介面去查。

回應標頭說明
X-RateLimit-Limit每秒允許的請求數(QPS)
X-RateLimit-Remaining目前這一秒還剩多少次
X-RateLimit-Reset限速視窗重置的 Unix 時間戳
X-Quota-Limit本期總額度
X-Quota-Used本期已用
X-Quota-Remaining本期剩餘
X-Quota-Reset本期額度重置時間
X-Request-Id本次請求 ID,回報問題時帶上它

建議在程式碼裡監控 X-Quota-Remaining,低於 10% 時告警,別等到呼叫直接失敗才發現。

錯誤狀態

401 金鑰無效、已撤銷或格式不對 403 來源 IP 不在白名單內 429 超過 QPS 限速,或本期額度耗盡 503 服務暫時不可用,稍後重試
{
  "error": {
    "code": "quota_exhausted",
    "message": "Monthly quota exhausted",
    "request_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "docs_url": "https://17nas.com/ip-api.php#documentation",
    "upgrade_url": "https://17nas.com/ip-api.php?source=api-error&placement=quota-exhausted#pricing",
    "reset_at": "2026-08-01T00:00:00+08:00"
  }
}

429 有兩種成因,靠回應標頭區分:X-RateLimit-Remaining 為 0 是瞬時限速,等一秒就能繼續;X-Quota-Remaining 為 0 是本期額度用盡,要等到 reset_at 或者加量/升級。

重試與降級

這是一個網路請求,它一定會有失敗的時候。幾條實務建議:

  • 設定 5 秒以內的逾時,不要讓它拖垮你的主流程
  • 遇到 503 或逾時可以重試,用指數退避(1s、2s、4s),最多 3 次
  • 遇到 401 / 403 不要重試,那是設定問題,重試只會浪費額度
  • 遇到 429 且是額度耗盡,重試沒有意義,直接走降級邏輯
  • 非關鍵路徑(比如日誌記錄)失敗就跳過,別因為拿不到 IP 歸屬地把使用者的正常操作擋下來
  • 可以在本地快取幾分鐘——同一台伺服器的出口 IP 通常不會秒級變化
FAQ

買之前你可能想問的

免費額度能商用嗎?

不能。免費的 1,000 次/月僅限個人開發測試。任何對外提供服務的場景——你的網站、APP、小程式、交付給客戶的系統——都需要購買商業方案。付費方案會在控制台顯示「允許商業使用」。

額度用完了會怎樣?會不會自動扣費?

不會。額度用完後介面直接回傳 429 並停止呼叫,不產生任何欠費,也不會自動扣款。你可以等下個週期自動恢復,或者買個加量包立刻續上。我們不做「先用後付」,就是為了避免你哪天被 bug 無窮迴圈打出一張天價帳單。

年付的額度是一次性給完嗎?

不是,按月釋出。比如買一年 API Pro,是每個月給 100 萬次、連續給 12 個月,不是一次性給 1200 萬次。這樣設計是為了防止額度在頭一個月被異常呼叫一次打光。每個月的剩餘額度不累積到下個月。

付款後多久能用?

付款成功後新額度會在 1 分鐘內同步到全球邊緣節點。同步完成前的呼叫仍按原額度計算,不會白扣。控制台的訂單狀態變成「已完成」就代表已經生效。

支援退款嗎?

API 額度屬於虛擬商品,額度一經發放原則上不支援退款。但如果是我們這邊的原因導致服務不可用,或者你付款後額度沒有正常到帳,請帶上訂單號到意見回饋頁找我們,會逐單處理。建議先用免費額度把接入調通再購買。

API Key 外洩了怎麼辦?

立刻去控制台撤銷這個 Key 並新建一個,撤銷會在 1 分鐘內同步到邊緣。為了防患未然,建議提前設定好 IP/CIDR 白名單——這樣即使 Key 外洩,別人在你的伺服器 IP 之外也用不了。

我可以中途升級方案嗎?

可以,在控制台點「升級方案」,只補差價,服務到期時間不變。注意升級需要保持目前的計費週期(月付升月付、年付升年付)。想從月付轉年付,在續約時選年付即可。

資料存在哪裡?會記錄我查了什麼嗎?

呼叫紀錄只保存彙總的用量統計(每小時的成功/失敗次數、平均耗時)和錯誤日誌。錯誤日誌裡的來源 IP 是去識別化後儲存的,保留天數依方案而定(7 天起)。我們不會保存你每次查詢回傳的具體 IP 內容。

服務穩定性怎麼保證?

介面部署在全球邊緣網路上,請求由離使用者最近的節點就近回應,不回源到單點伺服器,任何一個地區的節點異常都不會導致整體不可用。需要合約化 SLA 承諾的,請選擇企業客製方案。

還是拿不定主意?

那就先用免費額度把接入調通。跑通了再決定要不要買,反正不花錢。