API کوتاه کننده لینک کوکلی
با REST API کوکلی لینک کوتاه را از داخل اپلیکیشن، سایت، ربات تلگرام یا CRM خودتان بسازید، ویرایش کنید و آمار کلیکها را بگیرید. خروجی JSON است و احراز هویت با کلید API انجام میشود.
- REST و JSON
درخواست و پاسخ استاندارد JSON روی HTTPS؛ با هر زبان برنامهنویسی کار میکند.
- دسترسی قابل تنظیم
برای هر کلید فقط دسترسیهای لازم (مثلاً فقط خواندن) را فعال کنید.
- امنیت کلید
محدودسازی IP، تاریخ انقضا و باطلکردن فوری کلید از داشبورد.
- آمار و QR
آمار کلیک روزانه، کشور و دستگاه و تصویر QR هر لینک از طریق API.
شروع سریع
- ۱پلن دارای API را فعال کنید
دسترسی API در پلنهایی که در صفحهٔ پلنها با «دسترسی API» مشخص شدهاند فعال است.
- ۲کلید API بسازید
در داشبورد به بخش «کلیدهای API» بروید، نام و دسترسیهای کلید را انتخاب کنید. کلید فقط یکبار نمایش داده میشود.
- ۳اولین درخواست را بفرستید
کلید را در هدر Authorization: Bearer بفرستید و با POST /links اولین لینک کوتاه را بسازید.
ساخت یک لینک کوتاه با زبان دلخواه — آدرس پایه: https://kok.li/api/v1
curl -X POST https://kok.li/api/v1/links \
-H "Authorization: Bearer kk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"longUrl": "https://example.com/very/long/url"}'احراز هویت
همهٔ درخواستها (بهجز معرفی و فایل OpenAPI) کلید API لازم دارند. کلید را در هدر Authorization: Bearer kk_live_… یا X-API-Key بفرستید. کلید را فقط در سمت سرور نگه دارید و هرگز در کد مرورگر یا اپ موبایل قرار ندهید.
- برای هر کلید میتوانید تاریخ انقضا و فهرست IPهای مجاز (IP تکی یا بازهٔ CIDR) تعیین کنید.
- کلید باطلشده یا منقضی بلافاصله با خطای ۴۰۱ رد میشود.
- مدیر سایت میتواند در صورت سوءاستفاده دسترسی یک کلید یا حساب را غیرفعال کند.
دسترسیها (Scopes)
هنگام ساخت کلید مشخص میکنید کلید به کدام بخشها دسترسی داشته باشد. اصل «کمترین دسترسی لازم» را رعایت کنید؛ مثلاً کلید داشبورد گزارشگیری فقط به links:read و analytics:read نیاز دارد.
| Scope | کاربرد | مسیرها |
|---|---|---|
links:read | خواندن لینکها | GET /links، GET /links/{code} |
links:write | ساخت و ویرایش لینک | POST /links، POST /links/bulk، PATCH /links/{code} |
links:delete | حذف لینک | DELETE /links/{code} |
analytics:read | مشاهده آمار کلیک | GET /links/{code}/stats، GET /analytics |
qr:read | دریافت QR کد | GET /links/{code}/qr |
account:read | اطلاعات حساب و مصرف | GET /me |
مسیرهای API
همهٔ مسیرها نسبت به https://kok.li/api/v1 هستند. پاسخها JSON و زمانها ISO 8601 (UTC) هستند.
/api/v1/linksساخت لینک کوتاه
یک لینک کوتاه جدید میسازد. آدرس مقصد پیش از ساخت از نظر امنیتی بررسی میشود و سهمیهٔ ماهانهٔ پلن شما کم میشود.
دسترسی لازم: links:write
longUrlالزامی | string | آدرس مقصد (http یا https) |
alias | string | کد اختصاصی ۶ تا ۳۲ کاراکتر (حروف انگلیسی، عدد، - و _) |
utmSource / utmMedium / utmCampaign / utmTerm / utmContent | string | پارامترهای ردیابی کمپین که به آدرس مقصد اضافه میشوند |
expireIn | string | مدت اعتبار: 1d، 3d، 7d، 14d، 30d، 90d یا never |
expiresAt | string | تاریخ انقضا به فرمت ISO 8601 |
password | string | رمز باز کردن لینک |
{
"longUrl": "https://example.com/products/summer-sale",
"alias": "summer-sale",
"utmSource": "telegram",
"expireIn": "30d"
}{
"code": "summer-sale",
"shortUrl": "https://kok.li/summer-sale",
"longUrl": "https://example.com/products/summer-sale?utm_source=telegram",
"clicks": 0,
"scanStatus": "clean",
"expiresAt": "2026-10-25T08:30:00.000Z",
"createdAt": "2026-09-25T08:30:00.000Z"
}/api/v1/links/bulkساخت گروهی لینک
تا ۵۰ لینک را در یک درخواست میسازد. هر آیتم همان فیلدهای «ساخت لینک» را دارد و نتیجهٔ هر آیتم جداگانه برمیگردد؛ خطای یک آیتم مانع ساخت بقیه نمیشود.
دسترسی لازم: links:write
linksالزامی | array | آرایهای از ۱ تا ۵۰ شیء با فیلدهای ساخت لینک |
{
"links": [
{ "longUrl": "https://example.com/a" },
{ "longUrl": "https://example.com/b", "alias": "promo-b" }
]
}{
"created": 1,
"failed": 1,
"results": [
{ "index": 0, "ok": true, "link": { "code": "x7Kp2q", "shortUrl": "https://kok.li/x7Kp2q" } },
{ "index": 1, "ok": false, "status": 409, "code": "alias_taken", "error": "این alias قبلاً استفاده شده." }
]
}/api/v1/linksلیست لینکها
لینکهای حساب را بهترتیب جدیدترین با صفحهبندی برمیگرداند.
دسترسی لازم: links:read
page | integer | شمارهٔ صفحه (پیشفرض ۱) |
limit | integer | تعداد در هر صفحه، حداکثر ۱۰۰ (پیشفرض ۵۰) |
q | string | جستجو در آدرس مقصد، کد و برچسبها |
status | string | active | paused | archived | blocked |
tag | string | فقط لینکهای دارای این برچسب |
folder | string | فقط لینکهای این پوشه |
{
"links": [
{
"id": "66f3…",
"code": "summer-sale",
"shortUrl": "https://kok.li/summer-sale",
"longUrl": "https://example.com/products/summer-sale",
"clicks": 128,
"status": "active",
"tags": ["campaign"],
"passwordProtected": false,
"utm": { "source": "telegram", "medium": null, "campaign": null, "term": null, "content": null },
"expiresAt": null,
"createdAt": "2026-09-25T08:30:00.000Z"
}
],
"pagination": { "page": 1, "limit": 50, "total": 1, "totalPages": 1 }
}/api/v1/links/{code}دریافت یک لینک
جزئیات کامل یک لینک (مقصد، وضعیت، تعداد کلیک، برچسبها، انقضا و…) را برمیگرداند.
دسترسی لازم: links:read
/api/v1/links/{code}ویرایش لینک
فقط فیلدهای ارسالشده تغییر میکنند. متد PUT هم با همین رفتار پذیرفته میشود. برای حذف رمز، password را null بفرستید.
دسترسی لازم: links:write
longUrl | string | آدرس مقصد جدید (دوباره بررسی امنیتی میشود) |
tags | string[] | برچسبها (حداکثر ۲۰) |
folder | string | null | پوشه |
maxClicks | integer | null | سقف کلیک؛ پس از آن لینک متوقف میشود |
fallbackUrl | string | null | آدرس جایگزین پس از انقضا یا توقف |
password | string | null | رمز جدید یا null برای حذف رمز |
expireIn / expiresAt | string | تغییر زمان انقضا |
deviceTargets | object | مقصد جدا برای ios، android و desktop |
{
"tags": ["campaign", "autumn"],
"maxClicks": 1000
}/api/v1/links/{code}حذف لینک
لینک و تمام آمار کلیک آن را برای همیشه حذف میکند.
دسترسی لازم: links:delete
{ "ok": true }/api/v1/links/{code}/statsآمار کلیک یک لینک
سری روزانهٔ کلیک و بازدیدکنندهٔ یکتا، مجموع بازه و مقایسه با بازهٔ قبل. در پلنهای دارای آمار پیشرفته، تفکیک کشور، دستگاه، مرورگر، سیستمعامل و منبع ارجاع هم در breakdown برمیگردد.
دسترسی لازم: analytics:read
range | integer | 7 | 10 | 14 | 30 | 90 | 180 | 365 روز (پیشفرض ۱۰) |
from / to | YYYY-MM-DD | بازهٔ دلخواه به وقت ایران (بهجای range) |
{
"link": { "code": "summer-sale", "shortUrl": "https://kok.li/summer-sale", "clicks": 128 },
"range": 10,
"from": "2026-09-16",
"to": "2026-09-25",
"daily": [{ "date": "2026-09-25", "label": "۳ مهر", "clicks": 14, "uniques": 11 }],
"totals": { "clicks": 128, "uniques": 97 },
"totalsPrev": { "clicks": 90, "uniques": 70 },
"breakdown": null
}/api/v1/analyticsآمار کل حساب
همان خروجی آمار لینک، ولی برای مجموع همهٔ لینکهای حساب. پارامترهای range یا from/to را میپذیرد.
دسترسی لازم: analytics:read
/api/v1/links/{code}/qrتصویر QR کد
تصویر PNG یا SVG کد QR لینک کوتاه را برمیگرداند (پاسخ تصویر است، نه JSON).
دسترسی لازم: qr:read
format | string | png (پیشفرض) یا svg |
size | integer | عرض تصویر بین ۶۴ تا ۱۰۲۴ پیکسل (پیشفرض ۳۲۰) |
color / bgColor | hex | رنگ نقش و پسزمینه، مثل 000000 و ffffff |
margin | integer | حاشیه ۰ تا ۱۰ |
ecc | string | سطح تصحیح خطا: L، M، Q یا H |
/api/v1/meحساب، کلید و مصرف
اطلاعات حساب، پلن، دسترسیها و سقف نرخ کلید فعلی و میزان مصرف ماه جاری را برمیگرداند.
دسترسی لازم: account:read
{
"user": { "id": "66f1…", "name": "علی" },
"plan": { "tier": "pro", "label": "حرفهای" },
"key": { "prefix": "kk_live_3fa9c1", "scopes": ["links:read", "links:write"], "rateLimitPerMinute": 60 },
"limits": { "maxKeys": 10, "maxLinks": -1, "monthlyLinkLimit": 1000 },
"usage": { "period": "2026-09", "monthlyLinksCreated": 42, "totalLinks": 318 }
}محدودیت نرخ و سهمیه
- هر کلید سقف درخواست در دقیقه دارد (پیشفرض ۶۰). مقدار باقیمانده در هدرهای
RateLimit-Limit،RateLimit-RemainingوRateLimit-Resetبرمیگردد. - پس از عبور از سقف، پاسخ ۴۲۹ با کد
rate_limitedمیگیرید؛ چند ثانیه صبر و دوباره تلاش کنید. - لینکهای ساختهشده با API از همان سقف کل و سهمیهٔ ماهانهٔ پلن شما کم میشوند.
- ساخت گروهی حداکثر ۵۰ لینک در هر درخواست را میپذیرد.
خطاها
پاسخ خطا همیشه یک پیام فارسی در error و یک کد ثابت انگلیسی در code دارد؛ منطق برنامه را بر اساس code بنویسید.
{ "error": "این API key دسترسی «links:write» را ندارد.", "code": "insufficient_scope", "requiredScope": "links:write" }| کد | HTTP | معنی |
|---|---|---|
missing_api_key | 401 | کلید در هدر Authorization یا X-API-Key ارسال نشده است. |
invalid_api_key | 401 | کلید نامعتبر است یا باطل شده است. |
key_expired | 401 | تاریخ انقضای کلید گذشته است؛ کلید جدید بسازید. |
key_disabled | 403 | کلید توسط مدیر سایت موقتاً غیرفعال شده است. |
ip_not_allowed | 403 | IP شما در فهرست IPهای مجاز این کلید نیست. |
api_access_denied | 403 | پلن یا حساب شما دسترسی API ندارد (فیلد reason دلیل را میگوید). |
insufficient_scope | 403 | کلید دسترسی لازم برای این مسیر را ندارد (فیلد requiredScope). |
validation_error | 400 | بدنهٔ درخواست نامعتبر است (فیلد field نام فیلد مشکلدار است). |
not_found | 404 | لینک یا مسیر پیدا نشد. |
alias_taken | 409 | کد اختصاصی قبلاً استفاده شده است. |
url_rejected | 422 | آدرس مقصد به دلایل امنیتی پذیرفته نشد. |
limit_reached | 403 | به سقف کل لینکهای پلن رسیدهاید. |
quota_exceeded | 429 | سهمیهٔ ساخت لینک ماهانهٔ پلن تمام شده است. |
rate_limited | 429 | تعداد درخواست در دقیقه از سقف کلید بیشتر شده است. |
سوالات متداول API
پاسخ کوتاه به پرسشهای رایج توسعهدهندگان.
API کوکلی رایگان است؟
دسترسی API در پلنهایی فعال است که در صفحهٔ پلنها با «دسترسی API» مشخص شدهاند. تعداد لینکهایی که با API میسازید از همان سهمیهٔ پلن شما کم میشود.
کلید API را کجا بسازم و اگر لو رفت چه کنم؟
از داشبورد، بخش «کلیدهای API» کلید بسازید. کلید فقط یکبار نمایش داده میشود و ما فقط هش آن را نگه میداریم. اگر کلید لو رفت، همانجا آن را باطل کنید و کلید جدید بسازید؛ باطلکردن فوراً اعمال میشود.
سقف تعداد درخواست API چقدر است؟
هر کلید بهطور پیشفرض ۶۰ درخواست در دقیقه دارد. سقف دقیق کلید شما در پاسخ GET /me و در هدرهای RateLimit-Limit و RateLimit-Remaining هر پاسخ آمده است. با پیام rate_limited کمی صبر کنید و دوباره تلاش کنید.
چطور دسترسی یک کلید را محدود کنم؟
هنگام ساخت یا ویرایش کلید فقط دسترسیهای لازم را انتخاب کنید (مثلاً فقط links:read برای گزارشگیری). میتوانید استفاده از کلید را به IPهای سرور خودتان محدود کنید و برایش تاریخ انقضا بگذارید.
آیا مشخصات OpenAPI (Swagger) دارید؟
بله. فایل OpenAPI 3 در آدرس https://kok.li/api/v1/openapi.json در دسترس است و میتوانید آن را در Postman، Insomnia یا Swagger UI ایمپورت کنید.