ملخص
واجهة برمجة تطبيقات HubSpot تمكن المطورين من التكامل برمجيًا مع مراكز إدارة علاقات العملاء (CRM)، والتسويق، والمبيعات، والخدمة. تستخدم مصادقة OAuth 2.0 والتطبيقات الخاصة، ونقاط نهاية RESTful لجهات الاتصال والشركات والصفقات والتذاكر والمزيد، مع قيود معدل بناءً على مستوى الاشتراك. يغطي هذا الدليل إعداد المصادقة، ونقاط النهاية الأساسية، وwebhooks، واستراتيجيات التكامل للإنتاج.
مقدمة
تدير HubSpot أكثر من 194,000 حساب عميل ومليارات من سجلات CRM. بالنسبة للمطورين الذين يبنون تكاملات CRM، أو أتمتة التسويق، أو أدوات المبيعات، فإن تكامل واجهة برمجة تطبيقات HubSpot ليس اختياريًا - بل هو ضروري للوصول إلى أكثر من 7 ملايين مستخدم.
هذه هي الحقيقة: الشركات تخسر 15-20 ساعة أسبوعيًا في إدخال البيانات يدويًا بين الأنظمة. يوفر تكامل قوي لواجهة برمجة تطبيقات HubSpot أتمتة لمزامنة جهات الاتصال، وتحديثات الصفقات، وسير عمل التسويق، والتقارير عبر المنصات.
ما هي واجهة برمجة تطبيقات 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 الخاص بك
قبل الوصول إلى واجهة برمجة التطبيقات:
- قم بزيارة بوابة مطوري HubSpot
- سجل الدخول باستخدام حسابك في HubSpot (أو أنشئ واحدًا)
- انتقل إلى التطبيقات في لوحة تحكم المطورين
- انقر على إنشاء تطبيق
الخطوة 2: اختيار طريقة المصادقة
تدعم HubSpot طريقتين للمصادقة:
| الطريقة | الأفضل لـ | مستوى الأمان |
|---|---|---|
| OAuth 2.0 | تطبيقات متعددة المستأجرين، تكاملات عامة | مرتفع (رموز مميزة محددة للمستخدم) |
| تطبيق خاص | تكاملات داخلية، بوابة واحدة | مرتفع (رمز مميز محدد للبوابة) |
الخطوة 3: إعداد تطبيق خاص (موصى به للتكاملات الداخلية)
أنشئ تطبيقًا خاصًا للوصول إلى بوابة واحدة:
- انتقل إلى الإعدادات > التكاملات > التطبيقات الخاصة
- انقر على إنشاء تطبيق خاص
- تكوين النطاقات (Scopes):
contacts
crm.objects.companies
crm.objects.deals
crm.objects.tickets
automation
webhooks
- إنشاء رمز الوصول
- النسخ والتخزين بأمان
# .env file
HUBSPOT_ACCESS_TOKEN="pat-na1-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
HUBSPOT_PORTAL_ID="12345678"
الخطوة 4: إعداد OAuth 2.0 (للتطبيقات متعددة المستأجرين)
قم بتكوين OAuth للوصول إلى بوابات متعددة:
- انتقل إلى التطبيقات > إنشاء تطبيق
- تكوين إعدادات المصادقة:
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;
}
}
قائمة التحقق من نشر الإنتاج
قبل الإطلاق الفعلي:
- [ ] استخدم مصادقة التطبيقات الخاصة أو OAuth 2.0
- [ ] قم بتخزين الرموز المميزة بأمان (قاعدة بيانات مشفرة)
- [ ] نفّذ تحديث الرمز المميز تلقائيًا
- [ ] قم بإعداد تحديد المعدل وتحديد الطلبات في قائمة الانتظار
- [ ] كوّن نقطة نهاية webhook باستخدام HTTPS
- [ ] نفّذ معالجة أخطاء شاملة
- [ ] أضف تسجيلًا لجميع مكالمات API
- [ ] راقب استخدام حدود المعدل
- [ ] أنشئ دليل تشغيل للمشكلات الشائعة
حالات استخدام واقعية
مزامنة CRM
شركة SaaS تقوم بمزامنة بيانات العملاء:
- التحدي: إدخال البيانات يدويًا بين التطبيق و HubSpot
- الحل: مزامنة في الوقت الفعلي عبر webhooks و API
- النتيجة: لا يوجد إدخال يدوي، دقة بيانات 100%
توجيه العملاء المحتملين
وكالة تسويق تقوم بأتمتة توزيع العملاء المحتملين:
- التحدي: أوقات استجابة بطيئة للعملاء المحتملين
- الحل: توجيه يتم تشغيله بواسطة webhook إلى مندوبي المبيعات
- النتيجة: وقت استجابة 5 دقائق، زيادة بنسبة 40% في التحويل
الخلاصة
توفر واجهة برمجة تطبيقات HubSpot إمكانات شاملة لإدارة علاقات العملاء وأتمتة التسويق. النقاط الرئيسية المستخلصة:
- استخدم OAuth 2.0 للتطبيقات متعددة المستأجرين، والتطبيقات الخاصة للتكاملات الداخلية
- تختلف حدود المعدل حسب المستوى (100-400 طلب/ثانية)
- تمكن Webhooks المزامنة في الوقت الفعلي
- تدعم كائنات CRM الروابط والخصائص المخصصة
- يُبسّط Apidog اختبار API وتعاون الفريق
قسم الأسئلة الشائعة
كيف أقوم بالمصادقة مع واجهة برمجة تطبيقات HubSpot؟
استخدم OAuth 2.0 للتطبيقات متعددة المستأجرين أو التطبيقات الخاصة للتكاملات أحادية البوابة. تم إهمال مصادقة مفتاح API.
ما هي حدود معدل HubSpot؟
تتراوح حدود المعدل من 100 طلب/ثانية (مجاني) إلى 400 طلب/ثانية (مؤسسي)، مع حدود يومية تتراوح من 100 ألف إلى مليون طلب.
كيف أقوم بإنشاء جهة اتصال في HubSpot؟
إرسال طلب POST إلى /crm/v3/objects/contacts مع الخصائص بما في ذلك البريد الإلكتروني، الاسم الأول، الاسم الأخير، وأي حقول مخصصة.
هل يمكنني إنشاء خصائص مخصصة؟
نعم، استخدم واجهة برمجة تطبيقات الخصائص (Properties API) لإنشاء حقول مخصصة لأي نوع كائن.
كيف تعمل Webhooks في HubSpot؟
قم بتكوين Webhooks في إعدادات تطبيقك. ترسل HubSpot طلبات POST إلى نقطة النهاية الخاصة بك عند وقوع أحداث محددة.
