elefymove

开发者文档

ElefyMove Open API 的指南与参考。

这些指南目前仅提供英文版。

The master calendar

ElefyMove’s calendar is the single source of truth for anything bookable. Every date range carries a state — AVAILABLE, HELD, BOOKED, or BLOCKED — and conflicts resolve first-come-first-served across every channel.

方法端点权限范围用途
GET/api/public/v1/listings/{id}/availabilityavailability:read按日期区间读取房源的统一日历——可订、占位、已订或已封锁。
GET/api/public/v1/availabilityavailability:read一次调用读取最多 50 个房源的可订情况。你不拥有或不存在的 ID 会列入 notFound,而不会使整个请求失败。
GET/api/public/v1/listings/{id}/blocksavailability:read读取你自己在某房源上仍生效的外部渠道封锁,可选按日期区间缩小范围。
POST/api/public/v1/listings/{id}/blocksavailability:write创建或更新一条外部渠道封锁,用你自己的引用编号标识。
POST/api/public/v1/listings/{id}/blocks/batchavailability:write一次调用为同一房源创建或更新最多 100 条外部渠道封锁,每条都有各自的成功/失败结果。
DELETE/api/public/v1/listings/{id}/blocks/batchavailability:write一次调用为同一房源删除最多 100 条外部渠道封锁,每条都有各自的成功/失败结果。
DELETE/api/public/v1/listings/{id}/blocks/{externalRef}availability:write删除你此前写入的外部渠道封锁。
curl "https://elefymove.com/api/public/v1/listings/{listingId}/availability?from=2026-09-01&to=2026-09-30" \
  -H "X-Api-Key: efy_live_xxxxxxxxxxxxxxxxxxxxxxxx"

# Response — 200 OK
[
  { "from": "2026-09-01", "to": "2026-09-14", "state": "AVAILABLE" },
  { "from": "2026-09-15", "to": "2026-09-20", "state": "BLOCKED", "source": "partner-site", "externalRef": "HMXYZ123" },
  { "from": "2026-09-21", "to": "2026-09-30", "state": "AVAILABLE" }
]

Syncing a whole portfolio? GET /availability reads up to 50 listings in one call — pass their ids as a comma-separated listingIds. An id you don't own or that doesn't exist is folded into the response's notFound array rather than failing the whole request.

External blocks

When a stay is booked on your own platform, write a block carrying your reference. Blocks are dates + a reference only — no guest personal data crosses the API. GET /listings/:id/blocks reads your own active blocks back, optionally narrowed by from/to.

The batch endpoints write or delete up to 100 blocks on one listing in a single call. Each block gets its own result — check every item in the response rather than assuming the whole batch landed; one bad date range never rolls back the others.

Temporary holds

Place a short-lived hold (up to 10 minutes per call) while a guest completes checkout on your side, then either confirm it into a block or release it early. Not ready in time? POST /holds/:id/extend re-arms the expiry — but a hold's total lifetime, measured from when it was created (not from the extension), is capped at 30 minutes. An extension that would cross that cap is refused with a 409, so extending repeatedly cannot hold inventory indefinitely.

方法端点权限范围用途
GET/api/public/v1/holdsholds:write按最新排列列出你自己的占位。默认只显示 active 状态,可用 ?status=all 扩大范围。
GET/api/public/v1/holds/{id}holds:write按 ID 读取你的某个占位。
POST/api/public/v1/listings/{id}/holdsholds:write在客人于你这边完成结账期间占住日期区间。竞争失败的请求会收到带 SLOT_TAKEN 的 409。
POST/api/public/v1/holds/{id}/extendholds:write从当前时间起延长占位的到期时间。占位的总时长自创建起最多 30 分钟——超出该上限的延长请求会被 409 拒绝。
DELETE/api/public/v1/holds/{id}holds:write在到期前释放你的某个占位。
curl -X POST "https://elefymove.com/api/public/v1/listings/{listingId}/holds" \
  -H "X-Api-Key: efy_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"from": "2026-09-15", "to": "2026-09-20", "ttlSeconds": 300}'

# Response — 201 Created
{ "holdId": "hld_9f3a2c1b", "expiresAt": "2026-08-13T10:15:00Z" }

Losing a conflict

If another channel takes the dates first, the losing request gets a machine-readable 409 — surface it to your guest and refresh availability:

# Same request, the dates were just taken by another channel
# Response — 409 Conflict
{
  "code": "SLOT_TAKEN",
  "conflictingState": "HELD",
  "wonBy": "external"
}