Afterlog 开发者
把 Afterlog 旅程带入你的应用和服务。

嵌入组件
将 Before↔Current 滑块或旅程卡片放到任意网站。仅限公开旅程 —— 无需 API 密钥。
实时预览
脚本标签
添加 SDK 脚本和占位 div,组件会自动挂载并调整高度。
<script async src="https://afterlog.me/sdk/afterlog.js"></script>
<div data-afterlog-journey="JOURNEY_ID" data-afterlog-theme="light"></div>直接 iframe
无需 JavaScript 即可嵌入。使用 theme=light|dark 和 variant=slider|card。
<iframe
src="https://afterlog.me/embed/journey/JOURNEY_ID?theme=light&variant=slider"
width="480" height="520" style="border:0;max-width:100%"
scrolling="no" loading="lazy" title="Afterlog journey"></iframe>oEmbed
将旅程 URL 粘贴到 Slack、WordPress 等支持 oEmbed 的工具。
GET https://afterlog.me/api/oembed?url=https://afterlog.me/journey/JOURNEY_ID&format=json合作伙伴 API
面向已批准合作伙伴的只读 REST API。将公开历程、热门、搜索和资料引入你的产品。
身份验证
在 x-api-key 请求头中携带你的密钥。密钥在下方开发者控制台中签发。
curl https://api.afterlog.me/v1/partner/trending \
-H "x-api-key: ak_live_..."抢先体验
合作伙伴 API 目前仅限邀请。注册应用后,我们会先审核,再启用你的密钥。
403— 应用尚未批准,或密钥已吊销。401— x-api-key 缺失或无效。429— 超出速率限制 — 按 Retry-After 头等待后重试。
端点
所有路径均相对于 https://api.afterlog.me/v1 且为只读。热门与搜索通过 cursor 和 nextCursor 分页。
GET /partner/trending?category=&sort=trending|helpful&cursor=&limit=
GET /partner/search?q=&cursor=&limit=
GET /partner/journeys/:id
GET /partner/profiles/:username
GET /partner/profiles/:username/journeys?sort=recent|pinned响应结构
历程以其公开视图返回 — 封面、标签、统计和作者。不含查看者专属或私有字段。
{
"items": [
{
"id": "cmr576hhy000n5s6a1b2c3d4",
"userId": "cmr4qx8p0000ab12cd34",
"title": "코 성형 회복 여정",
"category": "BEAUTY",
"categoryCustom": null,
"startDate": "2026-01-15",
"privacy": "PUBLIC",
"status": "PUBLISHED",
"description": "붓기와 회복 과정을 매주 기록합니다.",
"tags": ["recovery", "beauty"],
"coverMediaId": "cmr58a4k0001...",
"coverUrl": "https://disk.afterlog.me/media/.../320.webp",
"captureSlots": [{ "key": "front", "label": "Front" }, { "key": "side", "label": "Side" }],
"heroSlot": "front",
"createdAt": "2026-01-15T09:12:00.000Z",
"updatedAt": "2026-07-14T02:31:00.000Z",
"stats": {
"daysCount": 180, "updatesCount": 12, "viewsCount": 3400,
"savesCount": 210, "followersCount": 95, "helpfulCount": 88,
"completedReadsCount": 40, "forksCount": 3, "helpfulnessScore": 0.82
},
"owner": {
"userId": "cmr4qx8p0000ab12cd34", "username": "riah_kim",
"displayName": "Riah", "avatarMediaId": null,
"avatarUrl": "https://disk.afterlog.me/media/.../320.webp"
},
"trendingScore": 128.4
}
],
"nextCursor": "eyJjIjoiMjAyNi0wNy0xNCJ9"
}准备好开发了吗?注册应用并签发你的第一个密钥。
打开开发者控制台用于用户数据的 OAuth
让用户连接其 Afterlog 账户,使你的应用可代表他们读取历程(包括私密)。Authorization Code + PKCE(S256)。
流程
- 1. 带上 PKCE challenge 和请求的 scope,将用户引导至授权 URL。
- 2. 用户在 Afterlog 上审阅并批准;我们带着一次性 code 和你的 state 重定向回 redirect_uri。
- 3. 在 token 端点用你原始的 code_verifier 将 code 换取令牌。
- 4. 用 Authorization: Bearer <access_token> 调用合作伙伴 API。访问令牌有效 1 小时,用 refresh 轮换。
权限范围
journeys.read | 读取已连接用户的历程与记录,包括私密内容。 |
profile.read | 读取已连接用户的公开资料。 |
授权 URL
将浏览器引导至此。redirect_uri 必须与应用中登记的完全一致,并且必须使用 method=S256 的 PKCE。
https://afterlog.me/oauth/authorize?response_type=code
&client_id=YOUR_APP_ID
&redirect_uri=https://your.app/callback
&scope=journeys.read%20profile.read
&state=RANDOM_CSRF
&code_challenge=BASE64URL_SHA256_OF_VERIFIER
&code_challenge_method=S256令牌换取
将 code 换取 access + refresh 令牌。机密客户端还需发送 client_secret。
curl -X POST https://api.afterlog.me/v1/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "authorization_code",
"client_id": "YOUR_APP_ID",
"code": "<code from redirect>",
"redirect_uri": "https://your.app/callback",
"code_verifier": "<original PKCE verifier>"
}'使用令牌
在合作伙伴 API 读取时以 Bearer 头发送访问令牌。带 journeys.read 时会包含已连接用户的私密历程。
curl https://api.afterlog.me/v1/partner/journeys/JOURNEY_ID \
-H "Authorization: Bearer <access_token>"Webhook
当已连接用户添加记录或公开历程时收到通知。载荷为轻信号——详情请从合作伙伴 API 获取。
管理端点
在开发者控制台按应用注册、列出与删除端点。签名 secret 仅在创建时显示一次。URL 必须为 https,且不得指向私有主机。
事件
journey.update.created | 已连接用户为历程添加了记录(Update)。 |
journey.published | 已连接用户公开了历程。 |
载荷
每次投递都带唯一 id(用于幂等)、event、时间戳和一个轻量 data 对象。
{
"id": "whd_5f3a1c...", // 배달 고유 id (수신측 idempotency 키)
"event": "journey.update.created",
"createdAt": "2026-07-19T09:00:00.000Z",
"data": {
"journeyId": "jr_...", "updateId": "up_...",
"username": "riah", "title": "코 성형 회복 여정"
}
}校验签名
每个请求带 X-Afterlog-Signature: t=<unix>,v1=<hex>,其中 v1 = "<t>.<原始正文>" 的 HMAC-SHA256。用原始正文重新计算并常量时间比较。
// header: X-Afterlog-Signature: t=<unix>,v1=<hex>
const [t, v1] = header.split(',').map((s) => s.split('=')[1]);
const expected = crypto
.createHmac('sha256', secret) // secret = whsec_...
.update(`${t}.${rawBody}`) // 받은 원문 바디 그대로 사용
.digest('hex');
const ok = crypto.timingSafeEqual(
Buffer.from(expected), Buffer.from(v1),
);
// t 가 최근(±5분)인지도 확인해 재전송(replay)을 막는다.重试与自动停用
2xx 为成功。失败与超时(10 秒)最多重试 3 次。累计失败 10 次后端点自动停用;重新创建以重新启用。