پرش به محتوا

API برای توسعه‌دهندگان

دسترسی ماشینی برای مشتریان سازمانی. کلید API متعلق به یک workspace است، نه یک شخص — و همان قواعد محرمانگی سایت روی آن اعمال می‌شود.

قاعده‌ای که باید حولش طراحی کنید

دادهٔ محرمانه فقط برای آگهی‌هایی برمی‌گردد که workspace شما دسترسی زندهٔ اتاق دادهٔ آن‌ها را دارد. برای بقیه، فیلد confidential برابر null است و دلیلش در confidentialWithheldReason می‌آید. همچنین انتخاب فروشنده برای نمایش «بازه‌ای» یا «پنهان» بودن اعداد در API هم رعایت می‌شود — فیلد metrics.disclosure این را می‌گوید.

احراز هویت

کلید را از صفحهٔ workspace بسازید. کلید فقط یک بار نمایش داده می‌شود — ما فقط هش SHA-256 آن را نگه می‌داریم و راهی برای بازیابی‌اش نداریم. اگر گمش کردید، ابطال و کلید جدید.

curl https://exithunt.app/api/v1/opportunities?limit=50 \
  -H "Authorization: Bearer eh_live_..."

دامنه‌های دسترسی: opportunities:read, deals:read, webhooks:manage

GET /api/v1/opportunities

فرصت‌های فعال، با صفحه‌بندی مبتنی بر cursor. پارامترها: limit (حداکثر ۲۰۰)، cursor، businessType. پاسخ شامل data و nextCursor است.

Webhooks

رویدادها: LISTING_PUBLISHED، LISTING_UPDATED، OFFER_RECEIVED، DEAL_STAGE_CHANGED. هر تحویل امضا می‌شود؛ امضا را قبل از پردازش بررسی کنید.

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

// Headers: x-exithunt-event, x-exithunt-timestamp, x-exithunt-signature
function verify(secret, rawBody, timestamp, signature) {
  const expected = createHmac("sha256", secret)
    .update(`${timestamp}.${rawBody}`)
    .digest("hex");
  const a = Buffer.from(expected);
  const b = Buffer.from(signature);
  return a.length === b.length && timingSafeEqual(a, b);
}

صف تلاش مجدد وجود ندارد. اگر endpoint شما پاسخ ندهد، تحویل با کد پاسخش FAILED ثبت می‌شود و ما دوباره تلاش نمی‌کنیم — برای جبران، API را poll کنید. این را صریح می‌گوییم چون طراحی کردن روی فرض «حداقل یک بار تحویل» که وجود ندارد، بدتر از نداشتن webhook است.

برای دسترسی سازمانی، صفحهٔ قیمت‌گذاری را ببینید.