این سند راهنمای کامل استفاده از APIهای NestAPI برای توسعهدهندگان است. اگر قصد دارید سرویسهای ما را در برنامه خود صدا بزنید، این صفحه نقطه شروع شماست.
تمام مثالهای این مستند با فراخوانی واقعی endpointها روی محیط production تست شدهاند و خروجیها دقیقاً همان چیزی است که سرور برمیگرداند.
آدرس پایه
https://open.nestapi.ir/{version}/{api_name}
| بخش | توضیح |
|---|---|
https://open.nestapi.ir | دامنه سرویس عمومی |
{version} | نسخه API، مثلا apis-1 |
{api_name} | نام سرویس، مثلاً bmi یا ip-info |
هر API یک نسخه دارد که در مستندات بخش لینک اصلی API قابل دسترس است.
متد و فرمت درخواست
همهٔ endpointها بجز چند استثنا با متود GET در دسترس هستند و ورودی ها به صورت Query String ارسال میشود.
GET https://open.nestapi.ir/apis-1/bmi?age=30&weight=70&height=175
احراز هویت
در حال حاضر برای استفاده از API نیازی به توکن یا کلید دسترسی نیست؛ endpointها عمومی و بدون احراز هویت در دسترساند.
- ارسال پارامتر
key(یا هر پارامتر مشابه) توسط سرویس عمومی اعمال نمیشود؛ مقدارش نادیده گرفته میشود. پس هیچ گواهیای برای درخواست لازم نیست. - یک پارامتر به نام
keyدر برخی سرویسها (مثلsearch-shazam) وجود دارد، ولی آن کلید لایسنس شما نیست؛ ورودی اختصاصی همان سرویس است.
اگر نسخهٔ بعدی، احراز هویت الزامی شود، آن وقت:
- هرگز توکن را در کدهای سمت کلاینت (جاوااسکریپت مرورگر، اپلیکیشن موبایل) قرار ندهید.
- توکن را فقط در سمت سرور نگه دارید و از متغیرهای محیطی یا Secret Manager استفاده کنید.
- در صورت شک به افشای توکن، آن را فوراً باطل و توکن جدید بگیرید.
نمونه درخواست
https://open.nestapi.ir/apis-1/bmi?age=30&weight=70&height=175
پاسخ:
{
"success": true,
"data": {
"bmi": 22.86,
"status": "وزن نرمال (Normal)",
"risk": "🟢 وضعیت بدنی سالم و نرمال",
"input": { "age": 30, "weight": 70, "height": 175 }
},
"source": {
"name": "NestAPI",
"version": "1.0.1",
"developers": "t.me/Nest_API t.me/devh3n"
}
}
نمونه کد
- PHP
- Python
- JavaScript
- cURL
composer require nestapi/nestapi
<?php
use NestApi\NestApi;
$api = new NestApi();
$result = $api->bmi(age: 30, weight: 70, height: 175);
echo $result->get('status');
راهنمای کامل در مستندات پکیج PHP آمده است.
pip install nestapi-py
from nestapi import NestApi
with NestApi() as api:
result = api.bmi(age=30, weight=70, height=175)
print(result.get("status"))
راهنمای کامل در مستندات پکیج Python آمده است.
npm install @devh3n/nestapi
import { NestApi } from "@devh3n/nestapi";
const api = new NestApi();
const result = await api.bmi({ age: 30, weight: 70, height: 175 });
console.log(result.get("status"));
راهنمای کامل در مستندات پکیج JavaScript آمده است.
curl "https://open.nestapi.ir/apis-1/bmi?age=30&weight=70&height=175"
فرمت پاسخ
همهٔ پاسخها — چه موفق، چه خطا — یک ساختار ثابت دارند. این ساختار در همهٔ سرویسها یکسان است.
پاسخ موفق
{
"success": true,
"data": { "bmi": 22.86 },
"source": {
"name": "NestAPI",
"version": "1.0.1",
"developers": "t.me/Nest_API t.me/devh3n"
}
}
| فیلد | همیشه هست؟ | توضیح |
|---|---|---|
success | بله | روی پاسخ موفق همیشه true |
data | بله | محتوای اصلی پاسخ: آبجکت، آرایه، رشته یا null |
meta | خیر | فقط وقتی سرویس چیزی برای گزارش دارد (مثلاً صفحهبندی) |
source | بله | هویت و نسخهٔ سرویس |
فیلد data
بسته به سرویس، data میتواند هر یک از اینها باشد:
- آبجکت:
{ "ip": "...", "location": { ... } } - آرایه:
{ "data": [ { ... }, { ... } ] } - رشته:
{ "data": { "ascii": " _ \n | | \n" } } null: وقتی سرویس چیزی برای برگرداندن ندارد
فیلد meta (اختیاری)
{
"success": true,
"data": [ { "name": "Samsung Galaxy S26 Ultra", "url": "..." } ],
"meta": {
"query": { "term": "galaxy" },
"pagination": { "count": 20 }
},
"source": { "name": "NestAPI", "version": "1.0.1", "developers": "..." }
}
meta فقط وقتی در پاسخ است که سرویس آن را فرستاده باشد؛ نبودنش خطا نیست.
فیلد source
| فیلد | مثال | توضیح |
|---|---|---|
name | NestAPI | نام سرویس |
version | 1.0.1 | نسخهٔ در حال سرویسدهی |
developers | t.me/Nest_API t.me/devh3n | ارتباط با توسعهدهندگان |
این فیلد روی همهٔ پاسخها — موفق و خطا — یکسان و بدون استثنا ظاهر میشود.
پاسخ خطا
{
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "Route not found: GET /apis-1/nope"
},
"source": { "name": "NestAPI", "version": "1.0.1", "developers": "..." }
}
| فیلد | توضیح |
|---|---|
success | همیشه false |
error.code | کد ماشینخوان و پایدار — برای شرطبندی در کلاینت از همین استفاده کنید |
error.message | پیام انسانی و همیشه انگلیسی |
error.details | اختیاری — فقط وقتی وجود دارد |
روی error.message شرط نزنید چون متن آن میتواند تغییر کند. روی error.code شرط بزنید و message را فقط برای نمایش به کاربر بگیرید.
پارامتر نامعتبر یا ناقص
دو حالت متفاوت وجود دارد و کد وضعیت متفاوتی دارند:
۱) پارامتر نیامده — وضعیت 400 و کد PARAM_NOT_FOUND، با آرایهای از جزئیات برای هر پارامتر گمشده:
{
"success": false,
"error": {
"code": "PARAM_NOT_FOUND",
"message": "Required parameters not found: 'age', 'weight', 'height'",
"details": [
{ "parameter": "age", "message": "'age' parameter not found", "description": "Age in years, e.g. ?age=30." },
{ "parameter": "weight", "message": "'weight' parameter not found", "description": "Weight in kilograms, e.g. ?weight=70." },
{ "parameter": "height", "message": "'height' parameter not found", "description": "Height in centimeters, e.g. ?height=175." }
]
}
}
details همیشه آرایه است — حتی وقتی فقط یک پارامتر کم است. پس کلاینت با یک forEach همهٔ حالتها را پوشش میدهد.
۲) پارامتر آمده ولی قالب یا بازهٔ آن غلط است — وضعیت 422 و کد VALIDATION_ERROR، با آبجکتی که کلیدش بخش و نام پارامتر است:
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"details": { "query.age": "Must be less than or equal to 120" }
}
}
کلید هر خطا با بخش مربوطه شروع میشود — query. یا body. — پس از همان معلوم است مشکل از کجاست. (همهٔ endpointهای عمومی فعلاً ورودی فقط از Query String میگیرند.)
کدهای خطا
| کد | وضعیت | علت |
|---|---|---|
NOT_FOUND | 404 | مسیر وجود ندارد، یا متد روی آن ثبت نشده |
PARAM_NOT_FOUND | 400 | پارامتر لازم ارسال نشده |
VALIDATION_ERROR | 422 | پارامتر آمده ولی نوع، قالب یا بازهاش نادرست است |
TOO_MANY_QUERY_PARAMETERS | 400 | بیش از ۱۰۰ کلید در Query String |
BODY_TOO_LARGE | 413 | حجم بدنه از حد مجاز بیشتر است |
RATE_LIMITED | 429 | تجاوز از محدودیت نرخ سمت برنامه |
RATE_LIMIT_EXCEEDED | 429 | تجاوز از محدودیت نرخ سمت لایهٔ وبسرور |
UNAUTHORIZED | 401 | گذرواژه یا توکن سرویس محافظتشده نامعتبر است |
FORBIDDEN | 403 | دسترسی به سرویس مجاز نیست |
CONFLICT | 409 | تعارض با وضعیت فعلی منبع |
SERVICE_UNAVAILABLE | 503 | سرویس موقتاً در دسترس نیست |
DATABASE_ERROR | 500 | خطای پایگاه داده (جزئیات فقط در لاگ) |
INTERNAL_SERVER_ERROR | 500 | خطای داخلی پیشبینینشده |
*_FAILED / *_INVALID | 400/404 | کدهای اختصاصی هر سرویس، مثل INVALID_IP یا IP_LOOKUP_FAILED |
هر سرویس ممکن است کدهای اختصاصی خودش را داشته باشد (مثلاً INVALID_IP با وضعیت 400) پس فقط به کد های عمومی بالا تکیه نکنید.
هدرها و CORS
سرویس از مرورگر و جاوااسکریپت سمت کلاینت پشتیبانی میکند:
| هدر | مقدار |
|---|---|
Access-Control-Allow-Origin | * |
Access-Control-Allow-Methods | GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS |
Access-Control-Allow-Headers | Content-Type, Accept, Authorization, If-None-Match, Range |
Access-Control-Max-Age | 86400 |
X-Content-Type-Options | nosniff |
X-Frame-Options | DENY |
Referrer-Policy | strict-origin-when-cross-origin |
Strict-Transport-Security | max-age=15552000 |
Content-Type | application/json; charset=UTF-8 |
OPTIONS بهصورت Preflight با وضعیت 204 و بدون بدنه پاسخ داده میشود.
نکات امنیتی و فنی
- از پروتکل HTTPS استفاده کنید؛ نسخهٔ HTTP به HTTPS ریدایرکت میشود.
- چون احراز هویت فعلاً لازم نیست، هیچ توکنی در سمت کلاینت قرار نمیگیرد؛ اگر سرویسی توکن اختصاصی خودش را میخواهد، آن را فقط سمت سرور نگه دارید.
- پاسخها و خطاها را به درستی مدیریت کنید: قبل از خواندن
data،successرا چک کنید. - طول هر پارامتر رشتهای به ۸ کیلوبایت محدود میشود و آرایهها حداکثر ۱۰۰ عضو میپذیرند.
آدرس پایه API را در متغیرهای ثابت و مرکزی نگه دارید تا تعویض دامنه بدون بازنویسی کد انجام شود.
define('API_BASE_URL', 'https://open.nestapi.ir/');
API_BASE_URL = "https://open.nestapi.ir/"
const API_BASE_URL = "https://open.nestapi.ir/";
اگر ساختار پروژهٔ شما ماژولار است، این مقادیر را در فایل
.envیا فایل تنظیمات متمرکز ذخیره کنید.
منابع تکمیلی
- مقدمهٔ مستندات
- سوالات متداول
- کانال اطلاعرسانی: @Nest_API
- ارتباط با توسعهدهنده: @devh3n - @aLirzix