elefymove

개발자 문서

ElefyMove Open API 가이드와 레퍼런스.

이 가이드는 현재 영어로만 제공됩니다.

Endpoints

메서드엔드포인트스코프설명
PUT/api/public/v1/webhookswebhooks:managewebhook 엔드포인트 URL을 설정하고, 선택적으로 이벤트 구독 목록을 교체합니다.
GET/api/public/v1/webhookswebhooks:manage현재 webhook 설정을 조회합니다. 서명 시크릿은 절대 반환되지 않습니다.
DELETE/api/public/v1/webhookswebhooks:managewebhook URL을 지우고 전송을 중단합니다.
POST/api/public/v1/webhooks/testwebhooks:manage현재 구독 여부와 관계없이 설정된 엔드포인트로 서명된 테스트 이벤트를 전송합니다.
GET/api/public/v1/webhook-deliverieswebhooks:manage본인의 webhook 전송 시도를 상태, 시각, 재시도 이력과 함께 나열합니다.
POST/api/public/v1/webhook-deliveries/{id}/redeliverwebhooks:manage실패했거나 데드레터 처리된 전송을 수동으로 재시도합니다.

Configuration

Set your HTTPS endpoint URL either through the API (PUT /webhooks) or from the dashboard’s Webhooks tab; both write the same configuration. 서명 시크릿 회전은 의도적으로 이 API에 포함되어 있지 않습니다 — 반드시 대시보드에서만 진행됩니다. 파트너가 키를 여전히 보유하고 있음을 증명하는 자격 증명을 스스로 회전시킬 수 없도록 하기 위해서입니다.

events on PUT /webhooks is optional and, when sent, replaces your subscription list. Omit it entirely to leave your existing subscription untouched. Send it as an empty array — the same as never setting it — to subscribe to every event; an empty list is not "no events". A non-empty list narrows delivery to exactly those event names. POST /webhooks/test always sends a signed ping, regardless of your subscription.

The delivery log (GET /webhook-deliveries) and manual redelivery (POST /webhook-deliveries/:id/redeliver) are also available through the API, mirroring the dashboard’s delivery log.

Events

받을 수 있는 이벤트설명
listing.approvedA listing you submitted passed moderation and is live.
listing.rejectedA listing you submitted was rejected by moderation.
availability.changedA listing’s calendar changed outside your own writes — a booking, block, or hold from another channel.
hold.createdA temporary hold was placed on one of your listings.
hold.releasedA hold was released before it expired.
hold.expiredA hold reached its TTL and expired.
booking.createdAn ElefyMove booking was confirmed on one of your listings (dates and references only).
booking.cancelledAn ElefyMove booking on one of your listings was cancelled.
pingManual test delivery — from the dashboard or POST /webhooks/test — same signing, no side effects.

Verifying signatures

Every delivery is a JSON POST carrying three headers: X-Elefy-Event, X-Elefy-Timestamp, and X-Elefy-Signature. The signature is hex(HMAC-SHA256(webhookSecret, timestamp + "." + rawBody)) — recompute it over the exact bytes you received and compare in constant time:

import { createHmac, timingSafeEqual } from "node:crypto";
import express from "express";

const app = express();

// Capture the RAW request bytes — a re-serialized JSON.stringify(body)
// may not byte-match what was signed.
app.post(
  "/webhooks/elefymove",
  express.raw({ type: "application/json" }),
  (req, res) => {
    const signature = req.header("X-Elefy-Signature") ?? "";
    const timestamp = req.header("X-Elefy-Timestamp") ?? "";
    const rawBody = req.body.toString("utf8");

    const expected = createHmac("sha256", process.env.ELEFY_WEBHOOK_SECRET)
      .update(`${timestamp}.${rawBody}`)
      .digest("hex");

    const valid =
      signature.length === expected.length &&
      timingSafeEqual(Buffer.from(signature), Buffer.from(expected));

    if (!valid) return res.status(401).end();

    // Optional hardening: reject timestamps older than a few minutes
    // to close the replay window.

    const event = JSON.parse(rawBody);
    console.log(event.event, event.data);

    // Acknowledge fast (2xx) — do heavy work asynchronously.
    res.status(200).end();
  },
);

Retries & redelivery

  • Respond with a 2xx quickly — anything else counts as a failed attempt.
  • Failed deliveries retry on a backoff of 1m, 5m, 30m, 2h, 12h, then dead-letter.
  • Failed and dead-lettered deliveries can be redelivered manually from the dashboard’s delivery log.
  • Deliveries can arrive more than once — key your processing on the delivery id or your own idempotency check.

Test deliveries

Use “Send test event” in the dashboard, or call POST /webhooks/test directly, to enqueue a signed ping delivery to your endpoint. Either way it goes through the exact same signing and retry pipeline as production events, with no side effects — the right way to verify your handler end to end. The response is 202 Accepted: queued for the next delivery cron run, not delivered synchronously.