← 返回服务器列表

SCPSL 服务器列表 API

公开接口 · 无需鉴权 · 支持跨域 · 数据来源 scplist.kr

目录
  1. 简介与快速开始
  2. 通用说明(跨域、缓存、限制)
  3. 接口一:服务器列表 /api.php
  4. 接口二:历史在线人数 /history.php
  5. 距离与定位精度说明
  6. 错误码
  7. 调用示例(curl / JS / PHP / Python)
  8. 常见问题

1. 简介与快速开始

本站提供两个公开只读接口,可用于获取 SCP: Secret Laboratory(SCP:秘密实验室)的在线服务器列表, 并按访客地理位置就近排序,同时可查询单台服务器的历史在线人数曲线。

接口用途
GET /api.php获取在线服务器列表(支持按访客 IP 距离排序、搜索、国家/版本筛选)
GET /history.php获取指定服务器的历史在线人数(24 小时 / 7 天 / 30 天)

最快上手

# 取离某个访客最近的 5 台服务器
curl "https://scpslserver.com/api.php?ip=223.5.5.5&sort=distance_asc&limit=5"

# 查某台服务器最近 24 小时的在线人数
curl "https://scpslserver.com/history.php?server_id=56351&range=24h"

2. 通用说明

项目说明
请求方式GET(另支持 OPTIONS 预检)
协议HTTPS(HTTP 会自动跳转到 HTTPS)
鉴权无需鉴权,不需要 API Key 或 Token
响应格式JSON,Content-Type: application/json; charset=utf-8
跨域 CORS已开放 Access-Control-Allow-Origin: *,可在浏览器前端直接 fetch
字符编码UTF-8,中文不转义(未使用 \uXXXX
数据缓存服务器列表每 60 秒从上游刷新一次,期间返回缓存数据
时间格式所有时间均为 Unix 时间戳(秒)
调用统计每次外部调用会计入首页显示的「已被调用次数」
请求频率建议:上游数据 60 秒才变化一次,因此建议轮询间隔不低于 60 秒。 当前未强制限流,但请勿高频请求,以免影响服务稳定性。

3. 接口一:服务器列表

GEThttps://scpslserver.com/api.php

返回当前全部在线服务器,可按访客 IP 计算距离并排序。

请求参数

参数类型必填默认说明
ipstring请求来源 IP 用于计算距离的访客 IPv4 地址。第三方对接时传入你自己用户的 IP,即可得到「对该用户就近排序」的结果。不传则使用请求来源 IP(即你服务器的 IP)。
仅支持 IPv4,IPv6 暂不支持定位。
sortstringdistance_asc 排序方式,可选值:
distance_asc 距离由近到远
distance_desc 距离由远到近
players_desc 在线人数由多到少
players_asc 在线人数由少到多
传入非法值时自动回退为 distance_asc
searchstring 按服务器名称模糊搜索(不区分大小写,匹配去除 HTML 标记后的纯文本名称)
countrystring 按国家/地区代码精确筛选,两位 ISO 3166-1 代码,如 CNUSRU(不区分大小写)
versionstring 按游戏版本精确筛选,如 14.2.7。可用版本及其数量见返回的 version_stats
limitint0 限制返回的服务器数量(在排序之后截断)。0 或不传表示返回全部
筛选与统计的关系country_statsversion_stats 始终基于全部在线服务器统计, 不受 search / country / version 筛选影响,方便你用来渲染筛选下拉框。

响应顶层字段

字段类型说明
clientobject访客定位信息,见下表
statsobject全局统计,见下表
country_statsobject各国服务器数量,形如 {"RU":255,"CN":251},按数量降序
version_statsobject各版本服务器数量,形如 {"14.2.7":1153},按数量降序
updated_atint服务器列表数据的更新时间(Unix 时间戳)
api_countint本站 API 累计被外部调用次数
totalint本次实际返回的服务器数量(已应用筛选与 limit)
sortstring本次生效的排序方式
serversarray服务器数组,见下表

client(访客定位)

字段类型说明
ipstring本次用于定位的 IP
country_codestring国家代码,如 CN;无法识别时为空字符串
countrystring国家名(英文)
citystring城市(中国 IP 返回中文如「杭州市」,海外返回英文)
statestring省 / 州
lat / lonfloat\|null纬度 / 经度;无法定位时为 null
precisionstring定位精度:city / province / country / unknown

stats(全局统计)

字段类型说明
online_serversint当前在线服务器总数
online_usersint当前所有服务器在线玩家总数
display_serversint上游展示的服务器数
offline_serversint已注册但当前离线的服务器数(仅总数,无明细)

servers[](单台服务器)

字段类型说明
server_idint服务器 ID,查询历史人数时使用此值
account_idint服主账号 ID(同一服主的多台服务器该值相同)
ipstring服务器 IP 地址
portint游戏端口
onlinebool是否在线(本接口只返回在线服务器,故通常为 true
versionstring游戏版本,如 14.2.7
iso_codestring国家代码,如 CN
country_namestring国家名(英文),如 China
citystring服务器所在城市;无数据时为空字符串
statestring服务器所在省 / 州;无数据时为空字符串
playersstring玩家数原始字符串,如 "27/30"
players_currentint当前在线人数
players_maxint最大人数(槽位)
infostring服务器名称原始值,含服主自定义的 HTML 颜色标记
info_textstring服务器名称纯文本(已剥离 HTML),推荐使用此字段
distance_kmfloat\|null访客到该服务器的距离(公里,保留 1 位小数);无法计算时为 null
distance_precisionstring该距离的可信精度,取访客与服务器两侧较低的那个
geo_precisionstring该服务器自身的定位精度
lat / lonfloat\|null服务器经纬度,可用于地图打点
moddedbool是否为模组服
whitelistbool是否开启白名单
friendly_firebool是否开启友军伤害
officialint是否官方服(1 是 / 0 否)
tech_listarray插件列表,元素为 {"name":"EXILED","version":"9.14.2"}
pastebinstring服务器详情 pastebin ID,完整地址为 https://pastebin.com/{值}
安全提示info 字段包含服主可自定义的 HTML 内容,直接插入页面存在 XSS 风险。 请使用 info_text,或对 info 做严格转义后再渲染。

响应示例

{
  "client": {
    "ip": "223.5.5.5",
    "country_code": "CN",
    "country": "China",
    "city": "杭州市",
    "state": "浙江省",
    "lat": 30.29365,
    "lon": 120.16142,
    "precision": "city"
  },
  "stats": {
    "online_servers": 1176,
    "online_users": 4642,
    "display_servers": 1176,
    "offline_servers": 21888
  },
  "country_stats": { "RU": 255, "CN": 251, "US": 147 },
  "version_stats": { "14.2.7": 1153, "14.2.6": 8 },
  "updated_at": 1787258650,
  "api_count": 128,
  "total": 2,
  "sort": "distance_asc",
  "servers": [
    {
      "server_id": 102246,
      "account_id": 36206,
      "ip": "120.27.160.16",
      "port": 2000,
      "online": true,
      "version": "14.2.7",
      "iso_code": "CN",
      "country_name": "China",
      "city": "杭州市",
      "state": "浙江省",
      "players": "3/22",
      "players_current": 3,
      "players_max": 22,
      "info": "<b><span style=\"color:#0ff\">[CN]</span> Grass动态服</b>",
      "info_text": "[CN] Grass动态服",
      "distance_km": 0,
      "distance_precision": "city",
      "geo_precision": "city",
      "lat": 30.29365,
      "lon": 120.16142,
      "modded": true,
      "whitelist": false,
      "friendly_fire": false,
      "official": 0,
      "pastebin": "V51ZhSiz",
      "tech_list": [ { "name": "EXILED", "version": "9.14.2" } ]
    }
  ]
}

4. 接口二:历史在线人数

GEThttps://scpslserver.com/history.php

查询指定服务器的历史在线人数曲线。本站每 10 分钟采集一次全部服务器人数,数据保留 30 天

请求参数

参数类型必填默认说明
server_idint 服务器 ID,从服务器列表接口的 servers[].server_id 获取
rangestring24h 时间范围与聚合粒度:
24h 最近 24 小时,按 10 分钟聚合(最多 144 点)
7d 最近 7 天,按 1 小时聚合(最多 168 点)
30d 最近 30 天,按 6 小时聚合(最多 120 点)
传入非法值时自动回退为 24h

响应字段

字段类型说明
server_idint查询的服务器 ID
serverobject\|null服务器基本信息快照:server_idnameipportiso_code;从未采集到该服务器时为 null
rangestring本次生效的时间范围
bucket_secondsint数据点聚合粒度(秒):600 / 3600 / 21600
summaryobject区间汇总,见下表
collect_sinceint\|null本站最早一条采集记录的时间戳,用于判断数据覆盖范围
total_pointsint返回的数据点数量
pointsarray数据点数组(按时间升序),见下表

summary(区间汇总)

字段类型说明
avgfloat\|null区间内平均在线人数(1 位小数)
peakint\|null区间内最高在线人数
minint\|null区间内最低在线人数
samplesint区间内采样次数
latestobject\|null最新一条记录:players_currentplayers_maxrecorded_at

points[](数据点)

字段类型说明
tsint该时间桶的起始时间戳
avgfloat桶内平均在线人数
peakint桶内最高在线人数
minint桶内最低在线人数
slotsint该时段的最大人数(槽位)
samplesint该桶包含的采样次数
数据范围限制:历史数据仅包含本站开始采集之后的部分。上游 scplist.kr 未提供公开的历史数据接口, 因此无法回溯采集开始之前的记录。若 points 为空数组,说明该时间范围内尚无数据, 可结合 collect_since 判断已积累多久。

响应示例

{
  "server_id": 56351,
  "server": {
    "server_id": 56351,
    "name": "[US EAST] Dr. Bright's Facility #1",
    "ip": "104.234.220.126",
    "port": 7777,
    "iso_code": "US"
  },
  "range": "24h",
  "bucket_seconds": 600,
  "summary": {
    "avg": 42.3,
    "peak": 48,
    "min": 12,
    "latest": {
      "players_current": 48,
      "players_max": 48,
      "recorded_at": 1787258650
    },
    "samples": 144
  },
  "collect_since": 1787258650,
  "total_points": 144,
  "points": [
    { "ts": 1787258400, "avg": 42.5, "peak": 48, "min": 37, "slots": 48, "samples": 1 }
  ]
}

5. 距离与定位精度说明

距离使用 Haversine 球面距离公式计算,单位为公里。定位策略如下:

IP 类型使用的库说明
中国 IPip2region国内数据源,城市级命中率高;再通过中国城市坐标表转经纬度
海外 IPGeoLite2 City直接返回城市级经纬度

精度等级

精度值含义可信度
city城市级距离较准确,可直接用于就近排序
province省级IP 库无城市数据,退到省会坐标,距离为近似值
country国家级IP 库仅有国家数据,误差可能达数百公里
unknown无法定位此时 distance_kmnull
如何正确展示距离distance_precisionprovincecountry 时, 建议在界面上加「约」「≈」等标识,避免给用户造成精确的错觉。本站前端即采用此做法。

6. 错误码

HTTP 状态响应内容原因与处理
200正常 JSON成功。注意:即使 servers / points 为空数组也返回 200
204OPTIONS 预检请求的正常响应
400{"error":"缺少或无效的 server_id 参数"}调用 history.php 时未传或传了非法 server_id
500{"error":"历史数据库不可用"}历史数据库读取失败,请稍后重试或反馈
502{"error":"无法获取服务器列表,请稍后重试"}上游 scplist.kr 不可用或超时,建议稍后重试

判断成功的推荐做法:先检查 HTTP 状态码,再检查响应体是否包含 error 字段。

7. 调用示例

curl

# 全部在线服务器(不排序距离,按人数)
curl "https://scpslserver.com/api.php?sort=players_desc&limit=10"

# 只看中国的模组服,按距离排序
curl "https://scpslserver.com/api.php?ip=223.5.5.5&country=CN&sort=distance_asc"

# 搜索名称含 vanilla 的服务器
curl "https://scpslserver.com/api.php?search=vanilla"

# 某服务器 7 天历史
curl "https://scpslserver.com/history.php?server_id=56351&range=7d"

JavaScript(浏览器前端,已支持跨域)

// 获取离当前访客最近的 20 台服务器
// 浏览器端不传 ip,接口会自动使用访客来源 IP
const res = await fetch('https://scpslserver.com/api.php?sort=distance_asc&limit=20');
const data = await res.json();

if (data.error) {
  console.error('请求失败:', data.error);
} else {
  console.log(`我的位置: ${data.client.city} (${data.client.precision})`);
  data.servers.forEach(s => {
    // 注意用 info_text 而非 info,避免 XSS
    console.log(`${s.info_text} | ${s.players} | ${s.distance_km} km`);
  });
}

// 查询某台服务器的历史人数
const h = await (await fetch(
  'https://scpslserver.com/history.php?server_id=56351&range=24h'
)).json();
console.log(`平均 ${h.summary.avg} 人,峰值 ${h.summary.peak} 人`);

PHP

<?php
// 传入你自己网站访客的 IP,实现「对该访客就近排序」
$visitorIp = $_SERVER['REMOTE_ADDR'];
$url = 'https://scpslserver.com/api.php?' . http_build_query([
    'ip'    => $visitorIp,
    'sort'  => 'distance_asc',
    'limit' => 20,
]);

$json = file_get_contents($url);
$data = json_decode($json, true);

if (isset($data['error'])) {
    exit('请求失败: ' . $data['error']);
}

foreach ($data['servers'] as $s) {
    printf(
        "%s | %s | %s km (%s)\n",
        $s['info_text'],
        $s['players'],
        $s['distance_km'] ?? '-',
        $s['distance_precision']
    );
}

Python

import requests

resp = requests.get('https://scpslserver.com/api.php', params={
    'ip': '223.5.5.5',
    'sort': 'distance_asc',
    'limit': 20,
}, timeout=30)
data = resp.json()

if 'error' in data:
    raise RuntimeError(data['error'])

print(f"访客定位: {data['client']['city']} ({data['client']['precision']})")
for s in data['servers']:
    print(f"{s['info_text']} | {s['players']} | {s['distance_km']} km")

# 历史人数
h = requests.get('https://scpslserver.com/history.php', params={
    'server_id': 56351,
    'range': '7d',
}, timeout=30).json()
for p in h['points']:
    print(p['ts'], p['avg'], p['peak'])

8. 常见问题

为什么同一国家的多台服务器距离完全相同?

说明这些服务器的 distance_precisionprovincecountry—— IP 库对它们只有省级或国家级数据,只能使用同一个参考坐标。可通过该字段识别并在界面上标注为近似值。

能查到离线服务器的列表吗?

不能。上游只提供离线服务器的总数stats.offline_servers),不提供明细。 离线服务器本身也不响应任何查询协议。

历史数据为什么是空的?

本站的历史数据从部署采集任务的那一刻开始积累。若 collect_since 距今不足 24 小时, 则 7d / 30d 视图自然只有少量数据点。

支持 IPv6 吗?

接口本身可正常访问,但 ip 参数仅支持 IPv4 定位。传入 IPv6 时会无法定位, distance_km 返回 nullprecisionunknown

有调用次数限制吗?

当前未强制限流。但上游数据 60 秒才更新一次,高频请求没有意义,请将轮询间隔控制在 60 秒以上。

数据准确性如何保证?

服务器列表完全来自第三方 scplist.kr,本站不修改人数、名称等原始数据, 仅额外做地理定位、距离计算与格式整理。若上游数据有误,本站结果也会一并受影响。