AFTERLOG

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應用程式尚未核准,或金鑰已撤銷。
  • 401x-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. 1. 帶上 PKCE challenge 與請求的 scope,將使用者導向授權 URL。
  2. 2. 使用者在 Afterlog 上檢視並核准;我們帶著一次性 code 與你的 state 重新導向回 redirect_uri。
  3. 3. 在 token 端點用你原始的 code_verifier 將 code 換取權杖。
  4. 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 次後端點自動停用;重新建立以重新啟用。

Afterlog 開發者 | Afterlog