Afterlog 개발자
Afterlog 여정을 여러분의 앱과 서비스에 연결하세요.

임베드 위젯
Before↔Current 슬라이더나 여정 카드를 어떤 사이트에나 붙이세요. 공개 여정 전용 — API 키 불필요.
라이브 프리뷰
스크립트 태그
SDK 스크립트와 placeholder 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
Slack·WordPress 등 oEmbed 지원 도구에 여정 URL 을 붙여넣으세요.
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 챌린지와 요청 스코프를 담아 사용자를 인가 URL로 보냅니다.
- 2. 사용자가 Afterlog에서 검토·승인하면, 일회용 code와 state를 실어 redirect_uri로 돌려보냅니다.
- 3. 토큰 엔드포인트에서 원래의 code_verifier와 함께 code를 토큰으로 교환합니다.
- 4. Authorization: Bearer <access_token> 헤더로 파트너 API를 호출합니다. 액세스 토큰은 1시간, refresh로 회전합니다.
스코프
journeys.read | 연결한 사용자의 여정과 기록을 읽습니다(비공개 포함). |
profile.read | 연결한 사용자의 공개 프로필을 읽습니다. |
인가 URL
브라우저를 이 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 토큰으로 교환합니다. confidential 클라이언트는 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 read에 액세스 토큰을 Bearer 헤더로 보냅니다. journeys.read면 연결 사용자의 비공개 여정까지 포함됩니다.
curl https://api.afterlog.me/v1/partner/journeys/JOURNEY_ID \
-H "Authorization: Bearer <access_token>"웹훅
연결한 사용자가 기록을 추가하거나 여정을 공개하면 알림을 받습니다. 페이로드는 얇은 신호이며, 상세는 파트너 API로 조회합니다.
엔드포인트 관리
개발자 콘솔에서 앱별로 엔드포인트를 등록·조회·삭제합니다. 서명 secret은 생성 시 1회만 노출됩니다. URL은 https이며 사설 호스트를 가리키면 안 됩니다.
이벤트
journey.update.created | 연결한 사용자가 여정에 기록(Update)을 추가했습니다. |
journey.published | 연결한 사용자가 여정을 공개했습니다. |
페이로드
모든 배달에는 고유 id(idempotency 키), 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회면 엔드포인트가 자동 비활성되며, 다시 만들어 재활성합니다.