API রেফারেন্স

REST API
আপনার লিংকের ওপর গড়ে তুলুন।

একটি API টোকেন দিয়ে অথেনটিকেট করুন, লিংকের তালিকা দেখুন ও তৈরি করুন, ভিজিট পড়ুন এবং ওয়েবহুকে সাবস্ক্রাইব করুন।

বেস URL https://letl.ink/api/v1 শুধু HTTPS

প্ল্যান Growth Ultimate
এই পৃষ্ঠায়

শুরু করা

REST API Growth ও Ultimate প্ল্যানে পাওয়া যায়। অনুরোধগুলো HTTPS-এর মাধ্যমে https://letl.ink/api/v1-এ যায়। Free বা Solo প্ল্যানের ওয়ার্কস্পেস /api/v1 থেকে 403 plan_required পায়; MCP এন্ডপয়েন্ট আলাদাভাবে Ultimate প্ল্যানে সীমিত।

  1. Integrations → REST API খুলুন (শুধু ওয়ার্কস্পেসের মালিক ও অ্যাডমিনরা)।
  2. একটি টোকেন তৈরি করুন। এর মেয়াদ শেষ হয় না।
  3. এটি পাসওয়ার্ডের মতো সংরক্ষণ করুন। একটি টোকেনই এই ওয়ার্কস্পেসের REST API, MCP সার্ভার ও যুক্ত সব অটোমেশন প্ল্যাটফর্মে কাজ করে, তাই এটি রিজেনারেট করলে সবগুলো একসাথে অকার্যকর হয়ে যায়।

টোকেন তৈরি করা থাকলে সদস্যরা তা কপি করতে পারেন; কেবল মালিক ও অ্যাডমিনরা এটি পরিবর্তন করতে পারেন।

অথেনটিকেশন

টোকেনটি X-API-KEY অথবা Authorization: Bearer হিসেবে পাঠান। /api/v1 ও /mcp-এ দুটিই গ্রহণ করা হয়। কোনো টোকেন ছাড়া অনুরোধ করলে 401 unauthenticated ফেরত আসে।

GET আমি কে?
curl -H "X-API-KEY: YOUR_TOKEN" \
  https://letl.ink/api/v1/auth/me

সমতুল্য হেডার: Authorization: Bearer YOUR_TOKEN

রীতিনীতি

নিচের প্রতিটি এন্ডপয়েন্টে এগুলো প্রযোজ্য।

রেসপন্স এনভেলপ

প্রতিটি সফল রেসপন্স একটি JSON অবজেক্ট, যাতে একটি data কী থাকে, আর ফলাফল সম্পর্কে কিছু বলার থাকলে একটি meta কী — পেজিনেশন, নির্ধারিত তারিখের সময়সীমা, ভৌগোলিক তথ্য অন্তর্ভুক্ত কিনা। প্রতিটি ব্যর্থতা একটি অবজেক্ট, যাতে একটি error কী থাকে, যার মধ্যে একটি স্থির code, মানুষের পড়ার মতো message এবং কখনো কখনো details। মেসেজের লেখার ওপর নয়, সবসময় code-এর ওপর ভিত্তি করে শাখা তৈরি করুন।

আকার
// success
{ "data": { … }, "meta": { … } }

// failure
{ "error": { "code": "invalid_parameter",
             "message": "sort must be one of: created_at, clicks.",
             "details": { "parameter": "sort" } } }

পেজিনেশন

তালিকার এন্ডপয়েন্ট limit (1–200, ডিফল্ট 50) ও offset গ্রহণ করে। meta ব্লক total, has_more ও next_offset জানায়, তাই হিসাব না করেই পেজ করতে পারেন: has_more false না হওয়া পর্যন্ত offset = meta.next_offset দিয়ে কল করতে থাকুন।

সব লিংক পেজ ধরে দেখা
offset=0
while [ "$offset" != "null" ]; do
  page=$(curl -s -H "X-API-KEY: $TOKEN" \
    "https://letl.ink/api/v1/links?limit=200&offset=$offset")
  echo "$page" | jq -c '.data[]'
  offset=$(echo "$page" | jq -r '.meta.next_offset')
done

সর্টিং, ফিল্টারিং ও সার্চ

GET /links গ্রহণ করে sort (created_at, clicks, short_code, title, updated_at), direction (asc/desc), search (শর্ট কোড, টাইটেল ও গন্তব্যের সঙ্গে মেলায়), type, archived, favorite ও domain। অজানা মান চুপচাপ উপেক্ষা না করে invalid_parameter ও অনুমোদিত মানের তালিকাসহ প্রত্যাখ্যান করা হয়।

তারিখের সময়সীমা

start_date ও end_date YYYY-MM-DD ফরম্যাটে এবং দুটো দিনই অন্তর্ভুক্ত। সময়সীমা আপনার প্ল্যানের ডেটা সংরক্ষণের সীমার মধ্যে সীমিত করা হয় — 30 দিনের সংরক্ষণযুক্ত প্ল্যানে এক বছরের ইতিহাস চাইলে যে 30 দিন আছে তা-ই ফেরত আসে, এবং meta.date_range জানায় আসলে কোন সময়সীমা ব্যবহার হয়েছে।

রেট লিমিট

প্রতি অ্যাকাউন্টে প্রতি মিনিটে 600টি রিকোয়েস্ট, স্লাইডিং উইন্ডোতে। প্রতিটি রেসপন্সে থাকে X-RateLimit-Limit, X-RateLimit-Remaining ও X-RateLimit-Reset (একটি Unix টাইমস্ট্যাম্প)। সীমা ছাড়ালে সেকেন্ডে একটি Retry-After হেডারসহ 429 rate_limited ফেরত আসে। সঙ্গে সঙ্গে আবার চেষ্টা না করে Retry-After অনুযায়ী অপেক্ষা করুন।

প্রতিটি রেসপন্সের হেডার
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 586
X-RateLimit-Reset: 1789000816

সংস্করণ

পাথেই সংস্করণ থাকে। রেসপন্সে একটি ফিল্ড বা নতুন ঐচ্ছিক প্যারামিটার যোগ করা ব্রেকিং পরিবর্তন নয় এবং যেকোনো সময় হতে পারে, তাই সতর্কভাবে পার্স করুন এবং অচেনা কী উপেক্ষা করুন। বিদ্যমান কোনো ফিল্ড বদলায় বা সরায় এমন যেকোনো কিছু নতুন সংস্করণ প্রিফিক্সের অধীনে আসে।

এন্ডপয়েন্ট

অ্যাকাউন্ট

GET /me সংযোগ পরীক্ষা

পরিচয়, ওয়ার্কস্পেস, প্ল্যান এবং সেই প্ল্যানের প্রতিটি সুবিধা। কোনো টোকেন যাচাই করার এবং চেষ্টা করার আগে অ্যাকাউন্ট কী কী করতে পারে তা জানার সবচেয়ে সহজ উপায়।

GET cURL
curl -H "X-API-KEY: YOUR_TOKEN" \
  https://letl.ink/api/v1/me
রেসপন্স 200
{
  "data": {
    "user": { "id": 1, "email": "[email protected]", "name": "You" },
    "workspace": { "id": 12, "name": "My Workspace", "block_bots": true },
    "plan": {
      "id": "growth",
      "name": "Growth",
      "limits": {
        "links": 200,
        "monthly_clicks": 100000,
        "custom_domains": 3,
        "qr_codes": 30,
        "retention_days": 365
      },
      "features": {
        "api": true,
        "webhooks": true,
        "integrations": true,
        "ai_access": false,
        "geo_analytics": false,
        "smart_link_types": true
      }
    },
    "base_domain": "letl.ink"
  }
}
GET /usage

এই বিলিং মাসে প্রতিটি বরাদ্দের কতটা ব্যবহৃত হয়েছে। ট্র্যাক করা ক্লিকের সীমায় পৌঁছানোর আগে গ্রাহককে সতর্ক করতে এটি ব্যবহার করুন — সীমা ছাড়ালে রিডাইরেক্ট চালু থাকে, কিন্তু ক্লিক রেকর্ড হওয়া বন্ধ হয়ে যায়।

রেসপন্স 200
{
  "data": {
    "links": { "used": 42, "limit": 200, "remaining": 158, "percent_used": 21.0 },
    "clicks_this_month": { "used": 8140, "limit": 100000, "remaining": 91860, "percent_used": 8.1 },
    "custom_domains": { "used": 1, "limit": 3, "remaining": 2, "percent_used": 33.3 },
    "qr_codes": { "used": 4, "limit": 30, "remaining": 26, "percent_used": 13.3 }
  },
  "meta": { "plan": "growth", "period": "2026-09" }
}
GET /domains

ওয়ার্কস্পেসের কাস্টম ডোমেইন এবং প্রতিটির DNS ভেরিফিকেশন সম্পন্ন হয়েছে কিনা। লিংক তৈরির সময় domain ফিল্ডে কেবল ভেরিফাইড ডোমেইন ব্যবহার করা যায়।

GET /integrations

প্রোডাক্টের প্রতিটি ইন্টিগ্রেশন, আপনার প্ল্যানে তা আছে কিনা, এই ওয়ার্কস্পেস তা সংযুক্ত করেছে কিনা, এবং ডেলিভারি কেমন চলছে — শেষ স্ট্যাটাস, শেষ ত্রুটি ও পরপর ব্যর্থতার সংখ্যা। অনেকগুলো ওয়ার্কস্পেস পর্যবেক্ষণে কাজের।

লিংক

অ্যানালিটিক্স

GET /analytics/summary

পুরো ওয়ার্কস্পেসের মূল সংখ্যাগুলো: সর্বমোট ও নির্বাচিত সময়সীমার ক্লিক, ইউনিক ভিজিটর, QR স্ক্যান, সর্বোচ্চ দিন, এবং দিনের ঘণ্টা ও সপ্তাহের দিন অনুযায়ী বণ্টন। days গ্রহণ করে (ডিফল্ট 30, আপনার সংরক্ষণকালের মধ্যে সীমিত)।

রেসপন্স 200 (সংক্ষেপিত)
{
  "data": {
    "window_days": 30,
    "clicks": {
      "total": 24592, "window": 8140, "last_7_days": 2103,
      "daily_average": 271,
      "peak_day": { "date": "Sep 02", "clicks": 612 }
    },
    "visitors": { "unique_total": 18204, "unique_window": 6021 },
    "qr": { "scans_total": 940, "scans_window": 310 },
    "timing": {
      "by_hour": [12, 4, 2, …],
      "by_weekday": [1420, 1610, 1585, 1490, 1310, 480, 245],
      "peak_hour": { "peakHour": 14, "peakValue": 812, "label": "14:00–14:59" },
      "peak_weekday": { "peakDay": 1, "peakValue": 1610, "label": "Tuesday" }
    },
    "links": { "active": 42, "limit": 200 }
  },
  "meta": { "plan": "growth", "geo_included": true, "retention_days": 365 }
}
GET /analytics/timeseries

দৈনিক ক্লিকের সংখ্যা, চার্টের জন্য প্রস্তুত। একটি লিংকে সীমিত করতে link_id এবং সময়সীমা নির্ধারণ করতে days দিন। ট্রাফিক না থাকা দিনগুলো বাদ না দিয়ে শূন্য হিসেবে ফেরত দেওয়া হয়, তাই সিরিজটি সবসময় ধারাবাহিক থাকে।

রেসপন্স 200
{
  "data": [
    { "date": "Sep 04", "clicks": 22 },
    { "date": "Sep 05", "clicks": 11 }
  ],
  "meta": { "window_days": 7, "total": 33, "link_id": null }
}
GET /analytics/breakdown

একটি মাত্রা অনুযায়ী ভাগ করা ক্লিক, প্রতিটি সারির মোটের অংশসহ।

কোয়েরি প্যারামিটার

  • dimension string

    channel, referrer, device, browser, os, brand, variation বা country। browser, os, brand ও variation-এর জন্য একটি link_id দরকার।

    আবশ্যক
  • link_id integer

    একটি লিংকে সীমিত করুন। পুরো ওয়ার্কস্পেসের জন্য বাদ দিন।

    ঐচ্ছিক
  • limit integer

    1–100। ডিফল্ট 10।

    ঐচ্ছিক
রেসপন্স 200
{
  "data": [
    { "label": "Search", "value": 215, "share": 33.1 },
    { "label": "Social", "value": 201, "share": 30.9 },
    { "label": "Direct / none", "value": 142, "share": 21.8 }
  ],
  "meta": { "dimension": "channel", "link_id": 49, "total": 650 }
}
GET /events পেজিনেটেড

ওয়ার্কস্পেসের সব লিংকের কাঁচা ভিজিট ফিড, নতুনগুলো আগে। এটি GET /visits-এর আধুনিক বিকল্প: একই ডেটা, মানক এনভেলপ, limit ও offset সমর্থন।

রেসপন্স 200
{
  "data": [
    {
      "id": 2691,
      "link_id": 49,
      "short_code": "spring",
      "occurred_at": "2026-09-10T22:45:33+00:00",
      "ip_address": "203.0.113.7",
      "referrer": "https://twitter.com/",
      "browser": "Chrome",
      "os": "iOS",
      "device_type": "mobile",
      "device_brand": "Apple",
      "country": "US",
      "variation": "control"
    }
  ],
  "meta": { "limit": 50, "returned": 50, "geo_included": true }
}

ওয়েবহুক

GET /hooks

এই অ্যাকাউন্টে নিবন্ধিত ওয়েবহুক এন্ডপয়েন্ট।

POST /hooks

প্রতিটি রেকর্ড করা ক্লিকে JSON পেলোড পেতে একটি HTTPS এন্ডপয়েন্ট নিবন্ধন করুন। প্রতি অ্যাকাউন্টে সর্বোচ্চ 25টি। ব্যর্থ ডেলিভারি স্বয়ংক্রিয়ভাবে আবার চেষ্টা করা হয়।

JSON বডি

  • target_url

    অবশ্যই https:// হতে হবে।

    আবশ্যক
  • event

    ডিফল্ট link_visited, যা বর্তমানে একমাত্র ইভেন্ট।

    ঐচ্ছিক
POST cURL
curl -X POST https://letl.ink/api/v1/hooks \
  -H "X-API-KEY: YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"target_url": "https://example.com/hooks/clicks"}'
DELETE /hooks/{id}

একটি ওয়েবহুক এন্ডপয়েন্ট সরান। Zapier-এর REST Hook ফ্লোর জন্য POST /hooks/subscribe ও DELETE /hooks/unsubscribe/{id} চালু থাকে।

পুরোনো

GET /auth/me পুরোনো

মূল সংযোগ পরীক্ষা: আপনার ইউজার id, ইমেইল এবং ওয়ার্কস্পেসের id/নাম একটি ফ্ল্যাট অবজেক্ট হিসেবে ফেরত দেয়। GET /me একই পরিচয়ের সাথে আপনার প্ল্যানের সীমা ও ফিচার ফ্ল্যাগও ফেরত দেয়, এবং নতুন কোডের জন্য এটিই ভালো পছন্দ।

GET cURL
curl -H "X-API-KEY: YOUR_TOKEN" \
  https://letl.ink/api/v1/auth/me
রেসপন্স 200
{
  "id": 1,
  "email": "[email protected]",
  "workspace_id": 12,
  "workspace_name": "My Workspace"
}
GET /visits পুরোনো

পুরো ওয়ার্কস্পেসের সর্বশেষ 50টি ভিজিট, একটি খালি JSON অ্যারে হিসেবে — কোনো এনভেলপ ছাড়া — visit_id, visit_time, link_shortcode এবং visitor_* ফিল্ড নাম ব্যবহার করে। Zapier-এর REST Hook-এর “perform list” ধাপ এটিই পড়ে, তাই এর গঠন স্থির রাখা হয়েছে। নতুন কাজের জন্য GET /events ব্যবহার করুন।

POST /hooks/subscribe Zapier

REST Hook সাবস্ক্রাইব। target_url ও একটি ঐচ্ছিক event (ডিফল্ট link_visited) নেয় এবং তৈরি হওয়া সাবস্ক্রিপশন এনভেলপ ছাড়া সরাসরি ফেরত দেয়। স্ট্যান্ডার্ড রূপে একই কাজ হলো POST /hooks।

DELETE /hooks/unsubscribe/{id} Zapier

REST Hook আনসাবস্ক্রাইব, যা {"success": true} ফেরত দেয়। স্ট্যান্ডার্ড রূপে এর সমতুল্য হলো DELETE /hooks/{id}।

ত্রুটি

  • 400 invalid_request

    বডি কোনো JSON অবজেক্ট ছিল না, অথবা একটি আবশ্যক ফিল্ড অনুপস্থিত ছিল।

  • 400 invalid_parameter

    একটি কোয়েরি প্যারামিটার ভুল ফরম্যাটে ছিল বা অনুমোদিত মানের বাইরে ছিল। details.parameter সমস্যাযুক্ত প্যারামিটারের নাম জানায়।

  • 401 unauthenticated

    কোনো টোকেন পাঠানো হয়নি। X-API-KEY বা Authorization: Bearer যোগ করুন।

  • 401 invalid_token

    টোকেনটি কোনো অ্যাকাউন্টের সাথে মেলে না। হয়তো এটি নতুন করে তৈরি করা হয়েছে।

  • 403 plan_required

    অ্যাকাউন্টের প্ল্যানে এই এন্ডপয়েন্ট বা ফিচার অন্তর্ভুক্ত নেই। details.upgrade_url বিলিং পৃষ্ঠার দিকে নির্দেশ করে।

  • 403 forbidden

    অথেনটিকেটেড, কিন্তু অনুমতি নেই — যেমন কোনো সদস্য শুধু মালিকের জন্য নির্ধারিত কাজ করার চেষ্টা করলে।

  • 404 not_found

    এই ওয়ার্কস্পেসে এমন কোনো রিসোর্স নেই। অন্য ওয়ার্কস্পেসের id নিষিদ্ধ নয়, বরং পাওয়া যায়নি হিসেবে জানানো হয়।

  • 409 conflict

    অনুরোধটি বর্তমান অবস্থার সাথে সাংঘর্ষিক — ওয়েবহুকের সীমা পূর্ণ, অথবা অ্যাকাউন্টে এখনো কোনো ওয়ার্কস্পেস নেই।

  • 422

    ব্যাচের প্রতিটি সারি ব্যর্থ হলে POST /links/bulk এটি ফেরত দেয়। meta.errors দেখুন।

  • 429 rate_limited

    গত এক মিনিটে 600-এর বেশি অনুরোধ। Retry-After সেকেন্ড অপেক্ষা করুন।

পুরোনো GET /visits ও GET /links/{id}/visits এন্ডপয়েন্ট নিজস্ব ফিল্ড নামসহ একটি খালি JSON অ্যারে ফেরত দেয় এবং এগুলোর ওপর ইতিমধ্যে তৈরি Zapier ইন্টিগ্রেশনের জন্য স্থির রাখা হয়েছে। নতুন কোডে GET /events ও GET /links/{id}/events ব্যবহার করা উচিত, যেগুলো মানক এনভেলপ ব্যবহার করে এবং পেজিনেশন সমর্থন করে।

আরও প্রশ্ন আছে?

আমরা সাহায্য করতে এখানে আছি। যোগাযোগ করুন, যত দ্রুত সম্ভব আমরা উত্তর দেব।