Afterlog untuk developer
Bawa perjalanan Afterlog ke aplikasi dan layanan Anda.

Widget sematan
Pasang slider Before↔Current atau kartu perjalanan di situs mana pun. Hanya perjalanan publik — tanpa API key.
Pratinjau langsung
Tag script
Tambahkan script SDK dan div placeholder; widget dipasang dan menyesuaikan tinggi otomatis.
<script async src="https://afterlog.me/sdk/afterlog.js"></script>
<div data-afterlog-journey="JOURNEY_ID" data-afterlog-theme="light"></div>iframe langsung
Sematkan tanpa JavaScript. Gunakan theme=light|dark dan 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
Tempel URL perjalanan ke Slack, WordPress, dan alat yang mendukung oEmbed.
GET https://afterlog.me/api/oembed?url=https://afterlog.me/journey/JOURNEY_ID&format=jsonPartner API
API REST hanya-baca untuk mitra yang disetujui. Tarik perjalanan publik, tren, pencarian, dan profil ke produk Anda.
Autentikasi
Kirim kunci Anda di header x-api-key. Terbitkan kunci dari konsol pengembang di bawah.
curl https://api.afterlog.me/v1/partner/trending \
-H "x-api-key: ak_live_..."Akses awal
API Mitra saat ini hanya dengan undangan. Daftarkan aplikasi, lalu kami tinjau sebelum kunci Anda aktif.
403— Aplikasi belum disetujui, atau kunci dicabut.401— x-api-key tidak ada atau tidak valid.429— Batas laju terlampaui — tunggu sesuai header Retry-After, lalu coba lagi.
Endpoint
Semua jalur relatif terhadap https://api.afterlog.me/v1 dan hanya-baca. Tren dan pencarian berpaginasi dengan cursor dan 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|pinnedBentuk respons
Perjalanan dikembalikan sebagai tampilan publiknya — sampul, tag, statistik, dan pemilik. Tanpa bidang khusus penonton atau bidang privat.
{
"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"
}Siap membangun? Daftarkan aplikasi dan terbitkan kunci pertama Anda.
Buka konsol pengembangOAuth untuk data pengguna
Biarkan pengguna menghubungkan akun Afterlog agar aplikasi Anda dapat membaca perjalanan mereka — termasuk yang privat — atas nama mereka. Authorization Code + PKCE (S256).
Alur
- 1. Arahkan pengguna ke URL otorisasi dengan PKCE challenge dan scope yang diminta.
- 2. Pengguna meninjau dan menyetujui di Afterlog; kami mengalihkan kembali ke redirect_uri Anda dengan code sekali pakai dan state Anda.
- 3. Tukar code dengan token di token endpoint, mengirim code_verifier asli Anda.
- 4. Panggil Partner API dengan Authorization: Bearer <access_token>. Token akses berlaku 1 jam; gunakan refresh untuk memutar.
Scope
journeys.read | Membaca perjalanan dan log pengguna yang terhubung, termasuk yang privat. |
profile.read | Membaca profil publik pengguna yang terhubung. |
URL otorisasi
Alihkan browser ke sini. redirect_uri harus sama persis dengan yang terdaftar di aplikasi Anda, dan PKCE dengan method=S256 wajib.
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=S256Tukar token
Tukar code dengan token access + refresh. Klien confidential juga mengirim 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>"
}'Menggunakan token
Kirim token akses sebagai header Bearer pada pembacaan Partner API. Dengan journeys.read, perjalanan privat pengguna yang terhubung ikut disertakan.
curl https://api.afterlog.me/v1/partner/journeys/JOURNEY_ID \
-H "Authorization: Bearer <access_token>"Webhook
Dapatkan notifikasi saat pengguna yang terhubung menambah log atau menerbitkan perjalanan. Payload adalah sinyal tipis — ambil detail dari Partner API.
Mengelola endpoint
Daftarkan, tampilkan, dan hapus endpoint per aplikasi di konsol pengembang. Secret penandatanganan ditampilkan sekali saat dibuat. URL harus https dan tidak boleh menunjuk host privat.
Peristiwa
journey.update.created | Pengguna yang terhubung menambah log (Update) ke perjalanan. |
journey.published | Pengguna yang terhubung menerbitkan perjalanan. |
Payload
Setiap pengiriman memiliki id unik (untuk idempotency), event, stempel waktu, dan objek data tipis.
{
"id": "whd_5f3a1c...", // 배달 고유 id (수신측 idempotency 키)
"event": "journey.update.created",
"createdAt": "2026-07-19T09:00:00.000Z",
"data": {
"journeyId": "jr_...", "updateId": "up_...",
"username": "riah", "title": "코 성형 회복 여정"
}
}Memverifikasi tanda tangan
Setiap permintaan membawa X-Afterlog-Signature: t=<unix>,v1=<hex>, dengan v1 = HMAC-SHA256 dari "<t>.<body mentah>". Hitung ulang atas body mentah dan bandingkan dalam waktu konstan.
// 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)을 막는다.Percobaan ulang dan nonaktif otomatis
2xx berarti sukses. Kegagalan dan timeout (10 dtk) dicoba ulang hingga 3 kali. Setelah 10 kegagalan kumulatif, endpoint dinonaktifkan otomatis; buat ulang untuk mengaktifkan lagi.