API 参考

REST API
基于你的链接,构建更多。

使用 API 令牌进行身份验证,列出和创建链接,读取访问记录,并订阅 Webhook。

基础 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. 打开集成 → 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

约定

以下约定适用于下方所有端点。

响应结构

每个成功的响应都是一个带有 data 键的 JSON 对象,在需要说明结果时还会带有 meta 键——分页、实际使用的日期范围、是否包含地理位置。每个失败响应都是一个带有 error 键的对象,其中包含稳定的 code、供人阅读的 message,有时还有 details。请根据 code 分支处理,而不要依赖 message 文本。

形状
// 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,让你无需计算即可翻页:持续使用 offset = meta.next_offset 调用,直到 has_more 为 false。

遍历所有链接
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 时间戳)。超出限制将返回 429 rate_limited,并附带以秒为单位的 Retry-After 请求头。请根据 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

整个工作区的核心数据:累计点击和时间范围内的点击、独立访客、二维码扫描、高峰日,以及时段和星期分布。支持 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 可设置时间范围。没有流量的日期会返回 0 而不会被省略,因此序列始终是连续的。

响应 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 }
}

Webhook

GET /hooks

此账户上注册的 Webhook 端点。

POST /hooks

注册一个 HTTPS 端点,在每次记录点击时接收 JSON 数据。每个账户最多 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}

移除 Webhook 端点。POST /hooks/subscribe 和 DELETE /hooks/unsubscribe/{id} 仍可用于 Zapier 的 REST Hook 流程。

旧版

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

    请求与当前状态冲突——已达到 Webhook 数量上限,或账户尚无工作区。

  • 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,它们使用标准结构并支持分页。

还有疑问?

我们随时为你提供帮助。联系我们,我们会尽快回复。