AFTERLOG

Afterlog para desenvolvedores

Leve as jornadas do Afterlog para seus apps e serviços.

Widgets incorporáveis

Coloque um slider Before↔Current ou um cartão de jornada em qualquer site. Apenas jornadas públicas — sem API key.

Prévia ao vivo

Tag de script

Adicione o script do SDK e um div de marcação; o widget se monta e se redimensiona sozinho.

<script async src="https://afterlog.me/sdk/afterlog.js"></script>
<div data-afterlog-journey="JOURNEY_ID" data-afterlog-theme="light"></div>

iframe direto

Incorpore sem JavaScript. Use theme=light|dark e 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

Cole uma URL de jornada no Slack, WordPress e outras ferramentas com oEmbed.

GET https://afterlog.me/api/oembed?url=https://afterlog.me/journey/JOURNEY_ID&format=json

API de parceiros

Uma API REST somente leitura para parceiros aprovados. Traga jornadas públicas, tendências, busca e perfis para o seu produto.

Autenticação

Envie sua chave no cabeçalho x-api-key. Emita chaves no console do desenvolvedor abaixo.

curl https://api.afterlog.me/v1/partner/trending \
  -H "x-api-key: ak_live_..."

Acesso antecipado

A API de parceiros é por convite por enquanto. Cadastre um app e nós o revisamos antes de ativar suas chaves.

  • 403App ainda não aprovado, ou chave revogada.
  • 401x-api-key ausente ou inválida.
  • 429Limite de requisições excedido — aguarde conforme o cabeçalho Retry-After e tente novamente.

Endpoints

Todos os caminhos são relativos a https://api.afterlog.me/v1 e somente leitura. Tendências e busca paginam com cursor e 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

Formato da resposta

Uma jornada é retornada como sua visão pública — capa, tags, estatísticas e autor. Sem campos privados ou específicos do espectador.

{
  "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"
}

Pronto para construir? Cadastre um app e emita sua primeira chave.

Abrir console do desenvolvedor

OAuth para dados do usuário

Deixe os usuários conectarem a conta Afterlog para seu app ler as jornadas deles — incluindo as privadas — em nome deles. Authorization Code + PKCE (S256).

Fluxo

  1. 1. Envie o usuário para a URL de autorização com seu PKCE challenge e os escopos solicitados.
  2. 2. O usuário revisa e aprova no Afterlog; redirecionamos de volta ao seu redirect_uri com um code de uso único e o seu state.
  3. 3. Troque o code por tokens no endpoint de token, enviando seu code_verifier original.
  4. 4. Chame a API de parceiros com Authorization: Bearer <access_token>. Tokens de acesso duram 1 hora; use refresh para rotacionar.

Escopos

journeys.readLer as jornadas e registros do usuário conectado, incluindo os privados.
profile.readLer o perfil público do usuário conectado.

URL de autorização

Redirecione o navegador para cá. O redirect_uri deve corresponder exatamente a um registrado no seu app, e PKCE com method=S256 é obrigatório.

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

Troca de token

Troque o code por um token de acesso + refresh. Clientes confidenciais também enviam 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>"
  }'

Usando o token

Envie o token de acesso como cabeçalho Bearer nas leituras da API de parceiros. Com journeys.read, as jornadas privadas do usuário conectado são incluídas.

curl https://api.afterlog.me/v1/partner/journeys/JOURNEY_ID \
  -H "Authorization: Bearer <access_token>"

Webhooks

Seja notificado quando um usuário conectado adiciona um registro ou publica uma jornada. Os payloads são sinais finos — busque detalhes na API de parceiros.

Gerenciar endpoints

Registre, liste e exclua endpoints por app no console do desenvolvedor. O secret de assinatura é mostrado uma vez na criação. As URLs devem ser https e não apontar para hosts privados.

Eventos

journey.update.createdUm usuário conectado adicionou um registro (Update) a uma jornada.
journey.publishedUm usuário conectado publicou uma jornada.

Payload

Cada entrega tem um id único (use para idempotência), um evento, um timestamp e um objeto data fino.

{
  "id": "whd_5f3a1c...",                     // 배달 고유 id (수신측 idempotency 키)
  "event": "journey.update.created",
  "createdAt": "2026-07-19T09:00:00.000Z",
  "data": {
    "journeyId": "jr_...", "updateId": "up_...",
    "username": "riah", "title": "코 성형 회복 여정"
  }
}

Verificar a assinatura

Cada requisição traz X-Afterlog-Signature: t=<unix>,v1=<hex>, onde v1 = HMAC-SHA256 de "<t>.<corpo bruto>". Recalcule sobre o corpo bruto e compare em tempo constante.

// 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)을 막는다.

Novas tentativas e desativação automática

Um 2xx é sucesso. Falhas e timeouts (10s) são retentados até 3 vezes. Após 10 falhas acumuladas o endpoint é desativado automaticamente; recrie-o para reativar.

Afterlog para desenvolvedores | Afterlog