كيفية استخدام HubSpot API في عام 2026

Ashley Innocent

Ashley Innocent

25 مارس 2026

كيفية استخدام HubSpot API في عام 2026

Apidog للمؤسسات

نشر محلي

SSO & RBAC

متوافق مع SOC 2

استكشاف Apidog Enterprise

ملخص

واجهة برمجة تطبيقات HubSpot تمكن المطورين من التكامل برمجيًا مع مراكز إدارة علاقات العملاء (CRM)، والتسويق، والمبيعات، والخدمة. تستخدم مصادقة OAuth 2.0 والتطبيقات الخاصة، ونقاط نهاية RESTful لجهات الاتصال والشركات والصفقات والتذاكر والمزيد، مع قيود معدل بناءً على مستوى الاشتراك. يغطي هذا الدليل إعداد المصادقة، ونقاط النهاية الأساسية، وwebhooks، واستراتيجيات التكامل للإنتاج.

مقدمة

تدير HubSpot أكثر من 194,000 حساب عميل ومليارات من سجلات CRM. بالنسبة للمطورين الذين يبنون تكاملات CRM، أو أتمتة التسويق، أو أدوات المبيعات، فإن تكامل واجهة برمجة تطبيقات HubSpot ليس اختياريًا - بل هو ضروري للوصول إلى أكثر من 7 ملايين مستخدم.

هذه هي الحقيقة: الشركات تخسر 15-20 ساعة أسبوعيًا في إدخال البيانات يدويًا بين الأنظمة. يوفر تكامل قوي لواجهة برمجة تطبيقات HubSpot أتمتة لمزامنة جهات الاتصال، وتحديثات الصفقات، وسير عمل التسويق، والتقارير عبر المنصات.

💡
يُبسّط Apidog اختبار تكامل API. اختبر نقاط نهاية HubSpot الخاصة بك، وتحقق من تدفقات OAuth، وافحص حمولات webhook، وقم بتصحيح أخطاء المصادقة في مساحة عمل واحدة. قم باستيراد مواصفات API، ومحاكاة الاستجابات، ومشاركة سيناريوهات الاختبار مع فريقك.
زر

ما هي واجهة برمجة تطبيقات HubSpot؟

توفر HubSpot واجهة برمجة تطبيقات (RESTful API) للوصول إلى بيانات CRM وميزات أتمتة التسويق. تتعامل واجهة برمجة التطبيقات مع:

الميزات الرئيسية

الميزة الوصف
تصميم RESTful طرق HTTP قياسية مع استجابات JSON
OAuth 2.0 + تطبيقات خاصة خيارات مصادقة مرنة
Webhooks إشعارات في الوقت الفعلي لتغييرات الكائنات
تحديد المعدل حدود قائمة على المستوى (100-400 طلب/ثانية)
كائنات CRM دعم الكائنات القياسية والمخصصة
الروابط ربط الكائنات ببعضها (جهة اتصال-شركة، صفقة-جهة اتصال)
الخصائص حقول مخصصة لأي نوع كائن
واجهة برمجة تطبيقات البحث تصفية وفرز معقدان

نظرة عامة على بنية API

تستخدم HubSpot واجهات برمجة تطبيقات REST ذات إصدارات:

https://api.hubapi.com/

مقارنة إصدارات API

الإصدار الحالة المصادقة حالة الاستخدام
CRM API v3 حالي OAuth 2.0، تطبيق خاص جميع التكاملات الجديدة
Automation API v4 حالي OAuth 2.0، تطبيق خاص تسجيل سير العمل
Marketing Email API حالي OAuth 2.0، تطبيق خاص حملات البريد الإلكتروني
Contacts API v1 مهمل مفتاح API (قديم) الترحيل إلى الإصدار 3
Companies API v1 مهمل مفتاح API (قديم) الترحيل إلى الإصدار 3

هام: أهملت HubSpot مصادقة مفتاح API لصالح OAuth 2.0 والتطبيقات الخاصة. يجب ترحيل جميع التكاملات فورًا.

البدء: إعداد المصادقة

الخطوة 1: إنشاء حساب مطور HubSpot الخاص بك

قبل الوصول إلى واجهة برمجة التطبيقات:

  1. قم بزيارة بوابة مطوري HubSpot
  2. سجل الدخول باستخدام حسابك في HubSpot (أو أنشئ واحدًا)
  3. انتقل إلى التطبيقات في لوحة تحكم المطورين
  4. انقر على إنشاء تطبيق

الخطوة 2: اختيار طريقة المصادقة

تدعم HubSpot طريقتين للمصادقة:

الطريقة الأفضل لـ مستوى الأمان
OAuth 2.0 تطبيقات متعددة المستأجرين، تكاملات عامة مرتفع (رموز مميزة محددة للمستخدم)
تطبيق خاص تكاملات داخلية، بوابة واحدة مرتفع (رمز مميز محدد للبوابة)

الخطوة 3: إعداد تطبيق خاص (موصى به للتكاملات الداخلية)

أنشئ تطبيقًا خاصًا للوصول إلى بوابة واحدة:

  1. انتقل إلى الإعدادات > التكاملات > التطبيقات الخاصة
  2. انقر على إنشاء تطبيق خاص
  3. تكوين النطاقات (Scopes):
contacts
crm.objects.companies
crm.objects.deals
crm.objects.tickets
automation
webhooks
  1. إنشاء رمز الوصول
  2. النسخ والتخزين بأمان
# .env file
HUBSPOT_ACCESS_TOKEN="pat-na1-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
HUBSPOT_PORTAL_ID="12345678"

الخطوة 4: إعداد OAuth 2.0 (للتطبيقات متعددة المستأجرين)

قم بتكوين OAuth للوصول إلى بوابات متعددة:

  1. انتقل إلى التطبيقات > إنشاء تطبيق
  2. تكوين إعدادات المصادقة:
const HUBSPOT_CLIENT_ID = process.env.HUBSPOT_CLIENT_ID;
const HUBSPOT_CLIENT_SECRET = process.env.HUBSPOT_CLIENT_SECRET;
const HUBSPOT_REDIRECT_URI = process.env.HUBSPOT_REDIRECT_URI;

// Build authorization URL
const getAuthUrl = (state) => {
  const params = new URLSearchParams({
    client_id: HUBSPOT_CLIENT_ID,
    redirect_uri: HUBSPOT_REDIRECT_URI,
    scope: 'crm.objects.contacts.read crm.objects.contacts.write',
    state: state,
    optional_scope: 'crm.objects.deals.read'
  });

  return `https://app.hubspot.com/oauth/authorize?${params.toString()}`;
};

الخطوة 5: تبادل الرمز المميز لرمز الوصول

تعامل مع رد نداء OAuth:

const exchangeCodeForToken = async (code) => {
  const response = await fetch('https://api.hubspot.com/oauth/v1/token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: new URLSearchParams({
      grant_type: 'authorization_code',
      client_id: HUBSPOT_CLIENT_ID,
      client_secret: HUBSPOT_CLIENT_SECRET,
      redirect_uri: HUBSPOT_REDIRECT_URI,
      code: code
    })
  });

  const data = await response.json();

  return {
    accessToken: data.access_token,
    refreshToken: data.refresh_token,
    expiresIn: data.expires_in,
    portalId: data.hub_portal_id
  };
};

// Handle callback
app.get('/oauth/callback', async (req, res) => {
  const { code, state } = req.query;

  try {
    const tokens = await exchangeCodeForToken(code);

    // Store tokens in database
    await db.installations.create({
      portalId: tokens.portalId,
      accessToken: tokens.accessToken,
      refreshToken: tokens.refreshToken,
      tokenExpiry: Date.now() + (tokens.expiresIn * 1000)
    });

    res.redirect('/success');
  } catch (error) {
    console.error('OAuth error:', error);
    res.status(500).send('Authentication failed');
  }
});

الخطوة 6: تحديث رمز الوصول

رموز الوصول تنتهي صلاحيتها بعد 6 ساعات:

const refreshAccessToken = async (refreshToken) => {
  const response = await fetch('https://api.hubspot.com/oauth/v1/token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: new URLSearchParams({
      grant_type: 'refresh_token',
      client_id: HUBSPOT_CLIENT_ID,
      client_secret: HUBSPOT_CLIENT_SECRET,
      refresh_token: refreshToken
    })
  });

  const data = await response.json();

  return {
    accessToken: data.access_token,
    refreshToken: data.refresh_token, // Always save new refresh token
    expiresIn: data.expires_in
  };
};

// Middleware to ensure valid token
const ensureValidToken = async (portalId) => {
  const installation = await db.installations.findByPortalId(portalId);

  // Refresh if expires within 30 minutes
  if (installation.tokenExpiry < Date.now() + 1800000) {
    const newTokens = await refreshAccessToken(installation.refreshToken);

    await db.installations.update(installation.id, {
      accessToken: newTokens.accessToken,
      refreshToken: newTokens.refreshToken,
      tokenExpiry: Date.now() + (newTokens.expiresIn * 1000)
    });

    return newTokens.accessToken;
  }

  return installation.accessToken;
};

الخطوة 7: إجراء مكالمات API المصادق عليها

إنشاء عميل API قابل لإعادة الاستخدام:

const HUBSPOT_BASE_URL = 'https://api.hubapi.com';

const hubspotRequest = async (endpoint, options = {}, portalId = null) => {
  const accessToken = portalId ? await ensureValidToken(portalId) : process.env.HUBSPOT_ACCESS_TOKEN;

  const response = await fetch(`${HUBSPOT_BASE_URL}${endpoint}`, {
    ...options,
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'Content-Type': 'application/json',
      ...options.headers
    }
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(`HubSpot API Error: ${error.message}`);
  }

  return response.json();
};

// Usage
const contacts = await hubspotRequest('/crm/v3/objects/contacts');

العمل مع كائنات CRM

إنشاء جهة اتصال

إنشاء أو تحديث جهة اتصال:

const createContact = async (contactData) => {
  const contact = {
    properties: {
      email: contactData.email,
      firstname: contactData.firstName,
      lastname: contactData.lastName,
      phone: contactData.phone,
      company: contactData.company,
      website: contactData.website,
      lifecyclestage: contactData.lifecycleStage || 'lead'
    }
  };

  const response = await hubspotRequest('/crm/v3/objects/contacts', {
    method: 'POST',
    body: JSON.stringify(contact)
  });

  return response;
};

// Usage
const contact = await createContact({
  email: 'john.doe@example.com',
  firstName: 'John',
  lastName: 'Doe',
  phone: '+1-555-0123',
  company: 'Acme Corp',
  lifecycleStage: 'customer'
});

console.log(`Contact created: ${contact.id}`);

خصائص جهة الاتصال

الخاصية النوع الوصف
email نص (String) البريد الإلكتروني الأساسي (معرّف فريد)
firstname نص (String) الاسم الأول
lastname نص (String) الاسم الأخير
phone نص (String) رقم الهاتف
company نص (String) اسم الشركة
website نص (String) عنوان URL للموقع الإلكتروني
lifecyclestage تعداد (Enum) عميل محتمل، عميل محتمل مؤهل تسويقيًا، عميل محتمل مؤهل مبيعاتيًا، فرصة، عميل، مبشر، مشترك
createdate تاريخ ووقت (DateTime) يتم إنشاؤه تلقائيًا
lastmodifieddate تاريخ ووقت (DateTime) يتم إنشاؤه تلقائيًا

الحصول على جهة اتصال

جلب جهة اتصال حسب المعرّف (ID):

const getContact = async (contactId) => {
  const response = await hubspotRequest(`/crm/v3/objects/contacts/${contactId}`);
  return response;
};

// Usage
const contact = await getContact('12345');
console.log(`${contact.properties.firstname} ${contact.properties.lastname}`);
console.log(`Email: ${contact.properties.email}`);

البحث عن جهات الاتصال

البحث باستخدام المرشحات:

const searchContacts = async (searchCriteria) => {
  const response = await hubspotRequest('/crm/v3/objects/contacts/search', {
    method: 'POST',
    body: JSON.stringify({
      filterGroups: searchCriteria,
      properties: ['firstname', 'lastname', 'email', 'company'],
      limit: 100
    })
  });

  return response;
};

// Usage - Find contacts at specific company
const results = await searchContacts({
  filterGroups: [
    {
      filters: [
        {
          propertyName: 'company',
          operator: 'EQ',
          value: 'Acme Corp'
        }
      ]
    }
  ]
});

results.results.forEach(contact => {
  console.log(`${contact.properties.email}`);
});

عوامل تشغيل تصفية البحث

العامل الوصف مثال
EQ يساوي company EQ 'Acme'
NEQ لا يساوي lifecyclestage NEQ 'subscriber'
CONTAINS_TOKEN يحتوي على email CONTAINS_TOKEN 'gmail'
NOT_CONTAINS_TOKEN لا يحتوي على email NOT_CONTAINS_TOKEN 'test'
GT أكبر من createdate GT '2026-01-01'
LT أقل من createdate LT '2026-12-31'
GTE أكبر من أو يساوي deal_amount GTE 10000
LTE أقل من أو يساوي deal_amount LTE 50000
HAS_PROPERTY يحتوي على قيمة phone HAS_PROPERTY
NOT_HAS_PROPERTY قيمة مفقودة phone NOT_HAS_PROPERTY

إنشاء شركة

إنشاء سجل شركة:

const createCompany = async (companyData) => {
  const company = {
    properties: {
      name: companyData.name,
      domain: companyData.domain,
      industry: companyData.industry,
      numberofemployees: companyData.employees,
      annualrevenue: companyData.revenue,
      city: companyData.city,
      state: companyData.state,
      country: companyData.country
    }
  };

  const response = await hubspotRequest('/crm/v3/objects/companies', {
    method: 'POST',
    body: JSON.stringify(company)
  });

  return response;
};

// Usage
const company = await createCompany({
  name: 'Acme Corporation',
  domain: 'acme.com',
  industry: 'Technology',
  employees: 500,
  revenue: 50000000,
  city: 'San Francisco',
  state: 'CA',
  country: 'USA'
});

ربط الكائنات

ربط جهات الاتصال بالشركات:

const associateContactWithCompany = async (contactId, companyId) => {
  const response = await hubspotRequest(
    `/crm/v3/objects/contacts/${contactId}/associations/companies/${companyId}`,
    {
      method: 'PUT',
      body: JSON.stringify({
        types: [
          {
            associationCategory: 'HUBSPOT_DEFINED',
            associationTypeId: 1 // Contact to Company
          }
        ]
      })
    }
  );

  return response;
};

// Usage
await associateContactWithCompany('12345', '67890');

أنواع الروابط

الرابط معرّف النوع الاتجاه
جهة اتصال → شركة 1 جهة الاتصال مرتبطة بالشركة
شركة → جهة اتصال 1 الشركة لديها جهة اتصال مرتبطة
صفقة → جهة اتصال 3 الصفقة مرتبطة بجهة اتصال
صفقة → شركة 5 الصفقة مرتبطة بالشركة
تذكرة → جهة اتصال 16 التذكرة مرتبطة بجهة اتصال
تذكرة → شركة 15 التذكرة مرتبطة بالشركة

إنشاء صفقة

إنشاء فرصة مبيعات:

const createDeal = async (dealData) => {
  const deal = {
    properties: {
      dealname: dealData.name,
      amount: dealData.amount.toString(),
      dealstage: dealData.stage || 'appointmentscheduled',
      pipeline: dealData.pipelineId || 'default',
      closedate: dealData.closeDate,
      dealtype: dealData.type || 'newbusiness',
      description: dealData.description
    }
  };

  const response = await hubspotRequest('/crm/v3/objects/deals', {
    method: 'POST',
    body: JSON.stringify(deal)
  });

  return response;
};

// Usage
const deal = await createDeal({
  name: 'Acme Corp - Enterprise License',
  amount: 50000,
  stage: 'qualification',
  closeDate: '2026-06-30',
  type: 'newbusiness',
  description: 'Enterprise annual subscription'
});

// Associate with company and contact
await hubspotRequest(
  `/crm/v3/objects/deals/${deal.id}/associations/companies/${companyId}`,
  { method: 'PUT', body: JSON.stringify({ types: [{ associationCategory: 'HUBSPOT_DEFINED', associationTypeId: 5 }] }) }
);

await hubspotRequest(
  `/crm/v3/objects/deals/${deal.id}/associations/contacts/${contactId}`,
  { method: 'PUT', body: JSON.stringify({ types: [{ associationCategory: 'HUBSPOT_DEFINED', associationTypeId: 3 }] }) }
);

مراحل الصفقة (مسار العمل الافتراضي)

المرحلة القيمة الداخلية
المواعيد المحددة appointmentscheduled
مؤهل للشراء qualifiedtobuy
تم تحديد موعد العرض presentationscheduled
صاحب القرار موافق decisionmakerboughtin
تم إرسال العقد contractsent
تم الفوز بالصفقة closedwon
تم خسارة الصفقة closedlost

Webhooks

تكوين Webhooks

إعداد Webhooks للإشعارات في الوقت الفعلي:

const createWebhook = async (webhookData) => {
  const response = await hubspotRequest('/webhooks/v3/my-app/webhooks', {
    method: 'POST',
    body: JSON.stringify({
      webhookUrl: webhookData.url,
      eventTypes: webhookData.events,
      objectType: webhookData.objectType,
      propertyName: webhookData.propertyName // Optional: filter by property change
    })
  });

  return response;
};

// Usage
const webhook = await createWebhook({
  url: 'https://myapp.com/webhooks/hubspot',
  events: [
    'contact.creation',
    'contact.propertyChange',
    'company.creation',
    'deal.creation',
    'deal.stageChange'
  ],
  objectType: 'contact'
});

console.log(`Webhook created: ${webhook.id}`);

أنواع أحداث Webhook

نوع الحدث المشغل
contact.creation تم إنشاء جهة اتصال جديدة
contact.propertyChange تم تحديث خاصية جهة الاتصال
contact.deletion تم حذف جهة اتصال
company.creation تم إنشاء شركة جديدة
company.propertyChange تم تحديث خاصية الشركة
deal.creation تم إنشاء صفقة جديدة
deal.stageChange تغيرت مرحلة الصفقة
deal.propertyChange تم تحديث خاصية الصفقة
ticket.creation تم إنشاء تذكرة جديدة
ticket.propertyChange تم تحديث خاصية التذكرة

التعامل مع Webhooks

const express = require('express');
const crypto = require('crypto');
const app = express();

app.post('/webhooks/hubspot', express.json(), async (req, res) => {
  const signature = req.headers['x-hubspot-signature'];
  const payload = JSON.stringify(req.body);

  // Verify webhook signature
  const isValid = verifyWebhookSignature(payload, signature, process.env.HUBSPOT_CLIENT_SECRET);

  if (!isValid) {
    console.error('Invalid webhook signature');
    return res.status(401).send('Unauthorized');
  }

  const events = req.body;

  for (const event of events) {
    console.log(`Event: ${event.eventType}`);
    console.log(`Object: ${event.objectType} - ${event.objectId}`);
    console.log(`Property: ${event.propertyName}`);
    console.log(`Value: ${event.propertyValue}`);

    // Route to appropriate handler
    switch (event.eventType) {
      case 'contact.creation':
        await handleContactCreation(event);
        break;
      case 'contact.propertyChange':
        await handleContactUpdate(event);
        break;
      case 'deal.stageChange':
        await handleDealStageChange(event);
        break;
    }
  }

  res.status(200).send('OK');
});

function verifyWebhookSignature(payload, signature, clientSecret) {
  const expectedSignature = crypto
    .createHmac('sha256', clientSecret)
    .update(payload)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature, 'hex'),
    Buffer.from(expectedSignature, 'hex')
  );
}

تحديد المعدل (Rate Limiting)

فهم حدود المعدل

تفرض HubSpot حدودًا على المعدل بناءً على مستوى الاشتراك:

المستوى الطلبات/الثانية الطلبات/اليوم
مجاني/مبتدئ 100 100,000
احترافي 200 500,000
مؤسسي 400 1,000,000

تجاوز الحدود يؤدي إلى استجابات HTTP 429 (طلبات كثيرة جدًا).

رؤوس تحديد المعدل

الرأس الوصف
X-HubSpot-RateLimit-Second-Limit الحد الأقصى للطلبات في الثانية
X-HubSpot-RateLimit-Second-Remaining الطلبات المتبقية لهذه الثانية
X-HubSpot-RateLimit-Second-Reset الثواني حتى يتم إعادة تعيين حد الثانية
X-HubSpot-RateLimit-Daily-Limit الحد الأقصى للطلبات في اليوم
X-HubSpot-RateLimit-Daily-Remaining الطلبات المتبقية اليوم
X-HubSpot-RateLimit-Daily-Reset الثواني حتى يتم إعادة تعيين الحد اليومي

تطبيق معالجة تحديد المعدل

const makeRateLimitedRequest = async (endpoint, options = {}, maxRetries = 3) => {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const response = await hubspotRequest(endpoint, options);

      // Log rate limit info
      const remaining = response.headers.get('X-HubSpot-RateLimit-Second-Remaining');
      if (remaining < 10) {
        console.warn(`Low rate limit remaining: ${remaining}`);
      }

      return response;
    } catch (error) {
      if (error.message.includes('429') && attempt < maxRetries) {
        const delay = Math.pow(2, attempt) * 1000;
        console.log(`Rate limited. Retrying in ${delay}ms...`);
        await new Promise(resolve => setTimeout(resolve, delay));
      } else {
        throw error;
      }
    }
  }
};

// Rate limiter class
class HubSpotRateLimiter {
  constructor(requestsPerSecond = 90) { // Stay under limit
    this.queue = [];
    this.interval = 1000 / requestsPerSecond;
    this.processing = false;
  }

  async add(requestFn) {
    return new Promise((resolve, reject) => {
      this.queue.push({ requestFn, resolve, reject });
      this.process();
    });
  }

  async process() {
    if (this.processing || this.queue.length === 0) return;
    this.processing = true;

    while (this.queue.length > 0) {
      const { requestFn, resolve, reject } = this.queue.shift();
      try {
        const result = await requestFn();
        resolve(result);
      } catch (error) {
        reject(error);
      }
      if (this.queue.length > 0) {
        await new Promise(r => setTimeout(r, this.interval));
      }
    }
    this.processing = false;
  }
}

قائمة التحقق من نشر الإنتاج

قبل الإطلاق الفعلي:


حالات استخدام واقعية

مزامنة CRM

شركة SaaS تقوم بمزامنة بيانات العملاء:

توجيه العملاء المحتملين

وكالة تسويق تقوم بأتمتة توزيع العملاء المحتملين:

الخلاصة

توفر واجهة برمجة تطبيقات HubSpot إمكانات شاملة لإدارة علاقات العملاء وأتمتة التسويق. النقاط الرئيسية المستخلصة:

زر

قسم الأسئلة الشائعة

كيف أقوم بالمصادقة مع واجهة برمجة تطبيقات HubSpot؟

استخدم OAuth 2.0 للتطبيقات متعددة المستأجرين أو التطبيقات الخاصة للتكاملات أحادية البوابة. تم إهمال مصادقة مفتاح API.

ما هي حدود معدل HubSpot؟

تتراوح حدود المعدل من 100 طلب/ثانية (مجاني) إلى 400 طلب/ثانية (مؤسسي)، مع حدود يومية تتراوح من 100 ألف إلى مليون طلب.

كيف أقوم بإنشاء جهة اتصال في HubSpot؟

إرسال طلب POST إلى /crm/v3/objects/contacts مع الخصائص بما في ذلك البريد الإلكتروني، الاسم الأول، الاسم الأخير، وأي حقول مخصصة.

هل يمكنني إنشاء خصائص مخصصة؟

نعم، استخدم واجهة برمجة تطبيقات الخصائص (Properties API) لإنشاء حقول مخصصة لأي نوع كائن.

كيف تعمل Webhooks في HubSpot؟

قم بتكوين Webhooks في إعدادات تطبيقك. ترسل HubSpot طلبات POST إلى نقطة النهاية الخاصة بك عند وقوع أحداث محددة.

ممارسة تصميم API في Apidog

اكتشف طريقة أسهل لبناء واستخدام واجهات برمجة التطبيقات