🚀 Fixing the -352 Verification Failure When Calling Bilibili's API
When writing crawlers or third-party apps that call Bilibili APIs (such as fetching the trending video list), you often hit error code -352.

When writing crawlers or third-party apps that call Bilibili APIs (such as fetching the trending video list), you often hit the API returning error code -352.
1. Symptoms
- Target endpoint:
https://api.bilibili.com/x/web-interface/ranking/v2(trending ranking) - Error response:
- Why it happens:
-352is Bilibili’s risk-control (verification) block code. It usually means the request headers are missing the key Cookie that identifies the device fingerprint (such asbuvid3), so the server treats the request as an illegal script or a “naked” request.
2. The Fix: Inject the Device Fingerprint (buvid3)
To pass verification, we first need to obtain a valid buvid3 from Bilibili’s front-end fingerprint API and add it to the request Cookie.
Step 1: Get buvid3
Call Bilibili’s front-end SPI endpoint to get the device fingerprint.
- Endpoint:
https://api.bilibili.com/x/frontend/finger/spi - Method:
GET - Response example:
Step 2: Build the Request Headers
Once you have the b_3 value, you need to concatenate it into the Cookie in a specific format.
⚠️ Note: A Cookie alone is not enough. Bilibili’s APIs usually also strictly check the
User-Agent, so be sure to send a standard browser UA.
Header configuration:
headers: {
// Key point 1: the Cookie must end with the "infoc" suffix
"Cookie": `buvid3=${b_3}infoc;`,
// Key point 2: you must impersonate a browser, otherwise it easily triggers -404 or -412
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Accept": "*/*",
"Host": "api.bilibili.com",
"Connection": "keep-alive"
}
3. Code Example (JavaScript/Node.js)
Here is a complete wrapper that automatically fetches the fingerprint and calls the target endpoint:
const axios = require('axios');
async function fetchBilibiliRanking() {
// 1. Get the device fingerprint buvid3
let buvid3 = '';
try {
const spiResponse = await axios.get('https://api.bilibili.com/x/frontend/finger/spi');
buvid3 = spiResponse.data.data.b_3;
console.log('获取指纹成功:', buvid3);
} catch (e) {
console.error('获取指纹失败', e);
return;
}
// 2. Request the target endpoint with the Cookie
const targetUrl = 'https://api.bilibili.com/x/web-interface/ranking/v2';
try {
const result = await axios.get(targetUrl, {
headers: {
// Concatenate the Cookie; note the trailing semicolon and infoc suffix
"Cookie": `buvid3=${buvid3}infoc;`,
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Referer": "https://www.bilibili.com/" // Some endpoints may check the Referer
}
});
if (result.data.code === 0) {
console.log('数据获取成功:', result.data.data.list.slice(0, 3)); // print the first 3
} else {
console.error('接口报错:', result.data);
}
} catch (e) {
console.error('请求异常:', e.message);
}
}
fetchBilibiliRanking();
💡 Additional Notes
- Lifetime:
buvid3is theoretically long-lived, but under high concurrency it’s best to refresh it regularly or maintain a Cookie pool. - Other risk controls: If you still get errors after adding
buvid3(such as-412), you may need to also addbuvid4or check the quality of your IP.
Comments