BuyPost API — מדריך למפתחים
קריאת המחירון, שליחת הזמנות, מעקב, אישור כתבות, וביטול או שינוי פרטים בשלבים שבהם האתר מאפשר — מהמערכת שלכם. הרכישה עצמה נעשית באתר (קרדיטים או כרטיס). אחרי התשלום ההזמנה עוברת בדיוק את אותו תהליך כמו הזמנה באתר.
הגישה פתוחה ללקוחות שאושרו: מגישים בקשה ויוצרים מפתח בעמוד API באזור האישי.
חיבור
- כתובת אחת:
https://ai.buypost.co.il/functions/customerApi, בקשותPOSTעם גוף JSON שכוללaction. - המפתח נשלח בכותרת
Authorization: Bearer bp_live_…בלבד — לא בכתובת ולא בגוף. השתמשו בו רק מהשרת שלכם. - תשובה מוצלחת:
{ "ok": true, "data": … }(בפעולות שליחה יש גםmessageבעברית). שגיאה:{ "ok": false, "error": { "code", "message", "hint", "details" } }—hintאומר מה לעשות. - סכומים בשקלים.
*_before_vat— לפני מע"מ (כמו הקרדיטים);*_incl_vat— כולל מע"מ (תשלום בכרטיס). המחיר תמיד מחושב אצלנו.
curl -X POST https://ai.buypost.co.il/functions/customerApi \
-H "Authorization: Bearer bp_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"action":"price_list","limit":20}'
מגבלות שימוש
- עד 10 בקשות בדקה ו-300 בקשות ביום לחשבון (כל המפתחות יחד). כל בקשה נספרת, גם ping. כמה נשאר היום — ב-
meta.requests_left_todayבכל תשובה. - מכסת כתבות ביום (ברירת מחדל 30) ומספר הזמנות שמחכות לתשלום בבת אחת (ברירת מחדל 5). המגבלות של החשבון מוחזרות ב-
balance; אפשר לבקש להגדיל. - 20 ניסיונות עם מפתח שגוי מאותה כתובת בתוך 10 דקות — חסימה ל-10 דקות.
- בלי בדיקות חוזרות: הגדירו webhook. כשצריך לבדוק —
list_itemsעםupdated_since(רק מה שהשתנה) אוget_items(עד 50 כתבות בבקשה אחת), ולא בקשה נפרדת לכל כתבה. - תשובות קריאה עשויות להגיע מזיכרון קצר (
meta.cached). כל שינוי שלכם, כל שינוי סטטוס של כתבה וכל קניית קרדיטים מרעננים אותו מיד.
פעולות
ping
בדיקת חיבור. מחזיר את החשבון שהמפתח שייך לו.
{ "action": "ping" }
balance
יתרת הקרדיטים (לפני מע"מ), מי משלם (חשבון אישי או סוכנות) ומגבלות השימוש של החשבון.
{ "action": "balance" }
price_list
המחירון — קריאה בלבד, עם כל מה שמוצג באתר: המחיר שלכם (מבצע / מחיר מיוחד / הנחה קבועה כבר מחושבים), מחיר המחירון ומחיר המבצע, DR ו-UR, לוגו, תיאור והערות, תווית דרגה, מאפיינים (למשל dofollow), "פרסום מיידי", כתבות לדוגמה, עיר ואזור, נושאים מומלצים, כללי כתיבה ופרסום, "בשיתוף עם", אישור תמונה, טיוטה מהאתר ופיקסל. בתשובה גם general_restrictions — ההגבלות הכלליות שמוצגות באתר מתחת לכל אתר. סינון: search, category, region, city, language, min_dr, tier, feature, on_sale, instant_publishing, max_price; מיון: sort = price_asc / price_desc / dr_desc; דפדוף: limit (עד 500), offset. מומלץ לשמור אצלכם — המחירון משתנה לעיתים רחוקות.
{ "action": "price_list", "search": "חדשות", "min_dr": 30, "sort": "price_asc", "limit": 50 }
quote
בדיקת הזמנה ומחיר — בלי ליצור כלום. אותם שדות כמו create_order. כתבה מוכנה בלי אף קישור (כל כתובת אתר, מייל או טלפון נחשבים קישור) מקבלת אזהרה שלא חוסמת (warnings, קוד no_external_link) — גם ב-create_order ועל הכתבה עצמה.
{ "action": "quote", "items": [ ... ] }
create_order
שליחת הזמנה עם כל פרטי הכתבות. ההזמנה נוצרת כממתינה לתשלום — לא מחויב כלום. הלקוח משלם באתר ב"הזמנות שלא שולמו" (קרדיטים או כרטיס), ואז הכתבות נכנסות לעבודה. חובה idempotency_key ייחודי: שליחה חוזרת עם אותו מפתח מחזירה את ההזמנה המקורית. עד 20 כתבות בהזמנה.
{
"action": "create_order",
"idempotency_key": "crm-order-10457",
"items": [
{
"website_id": "<id מתוך price_list>",
"content": { "type": "ai" },
"article_topic": "איך בוחרים צלם לחתונה בקיץ",
"writing_style": "seo_with_brand",
"brand_name": "סטודיו אור",
"keywords": "צילום חתונות",
"target_link": "https://example.co.il/weddings",
"scheduled_date": "2026-10-20",
"notes": "בלי להזכיר מחירים"
},
{
"website_id": "<id>",
"content": { "type": "html", "html": "<h1>כותרת</h1><p>הכתבה המוכנה שלכם...</p>" },
"keywords": "עורך דין גירושין",
"target_link": "https://example.co.il"
}
]
}
get_order
הזמנה אחת: האם שולמה (payment.status), הסכומים, והכתבות שלה עם השלבים ומצב התשלום של כל כתבה.
{ "action": "get_order", "order_id": "<id>" }
list_orders
כל ההזמנות של החשבון — מהאתר ומה-API, מהחדשה לישנה: מספר הזמנה, מצב תשלום, סכומים, מקור (site / api), כמה כתבות, כמה פורסמו, כמה ממתינות לכם, ספירה לפי שלב, ורשימת הכתבות עם השלב וקישור הפרסום. סינון: payment_status (paid / awaiting_payment / cancelled), source (site / api), created_from / created_to (YYYY-MM-DD), search (מספר הזמנה), updated_since; דפדוף: limit (עד 100), offset.
{ "action": "list_orders", "payment_status": "paid", "created_from": "2026-09-01" }
list_items
הכתבות של החשבון, מהחדשה לישנה, עם סטטוס, מצב תשלום, שלבים ותאריכים וכתובת הפרסום. סינון: status, order_id, created_from / created_to (YYYY-MM-DD), waiting_for_you: true (כל מה שמחכה לכם: אישור כתבה, טיוטה באתר, אישור תמונה, נושא שהוחזר לעדכון), awaiting_redemption: true (נקנו ושולמו ומחכות למימוש); updated_since — רק מה שהשתנה מאז הבדיקה הקודמת (שלחו את checked_at שקיבלתם); דפדוף: limit (עד 200), offset.
{ "action": "list_items", "updated_since": "2026-10-02T08:00:00Z" }
get_items
עד 50 כתבות בבקשה אחת — במקום בקשה לכל כתבה. חוסך בקשות מהמכסה.
{ "action": "get_items", "item_ids": ["<id1>", "<id2>"] }
list_redeemable
מה נקנה ועדיין לא נוצל: יתרת הקרדיטים ורכישות אחרונות, כתבות שנקנו ושולמו ומחכות למימוש (לפי אתר), הזמנות שממתינות לתשלום וכמה מהן היתרה מכסה, והמלצה לקנות קרדיטים כשהיתרה לא מספיקה. אותו מידע שמופיע באתר.
{ "action": "list_redeemable" }
get_item
כתבה אחת. כשהכתבה הגיעה לאישורכם מוחזר גם content_html — הטקסט לקריאה.
{ "action": "get_item", "item_id": "<id>" }
approve
אישור כתבה שממתינה לאישורכם (סטטוס review) — בדיוק כמו "מאשר כתבה" באתר.
{ "action": "approve", "item_id": "<id>" }
request_fix
בקשת תיקון מהצוות לכתבה שממתינה לאישורכם. הכתבה המתוקנת חוזרת אליכם.
{ "action": "request_fix", "item_id": "<id>", "note": "להוסיף פסקה על..." }
submit_edit
עריכה עצמית של כתבה שממתינה לאישורכם: שולחים את הטקסט המתוקן (HTML, 300 תווים לפחות). נשמר כמו בעורך באתר — עם קובץ Word תואם, כך שלאתר תמיד נשלחת הגרסה שערכתם. ברירת מחדל: עובר לבדיקת הצוות. keep_for_review: true — הכתבה נשארת אצלכם (כמו "שמירה" באתר) לקריאה ולעריכה נוספת, וכשתאשרו (approve) הצוות יבדוק את השינויים.
{ "action": "submit_edit", "item_id": "<id>", "content_html": "<p>...</p>", "keep_for_review": true }
ai_fix
תיקון באמצעות AI, כמו באתר: כותבים מה לשנות (instructions) וה-AI מתקן את הכתבה — שומר על המבנה, הסגנון, הקישורים ומילות המפתח. הכתבה המתוקנת חוזרת בתשובה (content_html) ונשארת אצלכם: אפשר לאשר, לתקן שוב, לערוך בעצמכם או לבקש מהצוות. אחרי האישור הצוות בודק את השינויים. עד 5 תיקונים לכתבה ו-20 ביממה לחשבון (התשובה מראה כמה נשארו). אם ה-AI נכשל — הכתבה לא משתנה.
{ "action": "ai_fix", "item_id": "<id>", "instructions": "לקצר את הפתיח ולהוסיף פסקה על שעות הפתיחה" }
replace_file
החלפת כתבה שממתינה לאישורכם בקובץ Word משלכם (עד 8MB).
{ "action": "replace_file", "item_id": "<id>", "filename": "article.docx", "file_base64": "..." }
reject_content
דחיית הכתבה שנכתבה: חוזרת לצוות לכתיבה מחדש עם הסיבה (חובה), והכתבה החדשה חוזרת לאישורכם. לביטול הכתבה עצמה — cancel, במקום שהאתר מאפשר.
{ "action": "reject_content", "item_id": "<id>", "reason": "הטון לא מתאים למותג" }
cancel
ביטול כתבה — באותם שלבים שבהם האתר מאפשר: לפני תחילת הכתיבה, או כשהצוות ביקש תיקון. כתבה בהזמנה שעוד לא שולמה אפשר לבטל תמיד (הסכום לתשלום יורד). זיכוי על כתבה ששולמה — לפי התקנון, לקרדיטים.
{ "action": "cancel", "item_id": "<id>", "reason": "..." }
update_item
שינוי פרטים — רק כשהאתר מאפשר: בהזמנה שעוד לא שולמה (כל פרטי הכתבה); תאריך פרסום (scheduled_date, או null לביטול התזמון) לפני שהכתבה נשלחה לאתר; פרטי כתבה כשהצוות החזיר את הנושא לעדכון; או מימוש כתבה שנקנתה ושולמה (redeem). שדות: article_topic, keywords, target_link, keywords_2, target_link_2, writing_style, brand_name, target_audience, notes, client_label, image, scheduled_date. האתר והמחיר לא משתנים. שדות נוספים: shared_with, shared_company_id, team_notes. כתבה של הזמנת אתר שלא שולמה או בוטלה מחזירה order_not_paid (הזמנת API שלא שולמה — אפשר לערוך בחופשיות).
{ "action": "update_item", "item_id": "<id>", "changes": { "scheduled_date": "2026-11-01" } }
redeem
מימוש כתבה שנקנתה מראש ושולמה (awaiting_redemption): שולחים נושא, מילת מפתח, קישור וסגנון כתיבה, ואפשר גם תאריך פרסום — והכתבה נכנסת לעבודה. תאריך לבד לא מממש (redeem_details_required).
{ "action": "redeem", "item_id": "<id>", "changes": { "article_topic": "איך בוחרים צלם לחתונה", "keywords": "צלם חתונות", "target_link": "https://example.co.il", "writing_style": "professional" } }
נעשה רק באתר (מחזיר site_only): תשלום, קניית קרדיטים והגדרת webhook. ביטול ושינוי פרטים בשלב שגם האתר לא מאפשר מחזירים not_cancellable / not_editable עם הסבר.
שדות של כתבה
- content.type:
ai— אנחנו כותבים (חובה article_topic של 3 מילים לפחות ו-writing_style);html— כתבה מוכנה כטקסט HTML (300 תווים לפחות, בלי script/iframe);docx— קובץ Word:filenameו-file_base64(עד 8MB). - writing_style:
professional, marketing, seo_no_brand, seo_with_brand, ai_engines. ל-seo_with_brand חובה brand_name. באתר "SEO בלבד" רק seo_no_brand. - keywords + target_link — חובה בכתבה שאנחנו כותבים (מילת מפתח אחת, בלי פסיקים). keywords_2 + target_link_2 — רק יחד, ולא באתרים שמתירים קישור אחד.
- scheduled_date (YYYY-MM-DD, לא בעבר, ראשון–חמישי) — פרסום מתוזמן. image:
{ "option": "auto_select" }— ברירת מחדל, אנחנו בוחרים תמונה. - client_label — שם הלקוח שלכם (לסוכנויות), notes — הערות לכותב, team_notes — הערות לצוות BuyPost בלבד.
- shared_with ("בשיתוף עם") — חובה באתרים שמסומנים במחירון
requires_shared_fields. shared_company_id (ח.פ) — רשות. - image עם תמונות שלכם:
{ "option": "upload", "images": [{ "url": "https://…", "credit": "יח"צ" }] }— עד 2 תמונות, קישור או קובץ (file_base64 + filename, jpg/png/webp עד 5MB), וקרדיט צילום חובה לכל תמונה. קישור לתמונה מוכנה:{ "option": "stock", "url": "https://…" }. - pixel — פיקסל מעקב, רק באתרים שמציעים (
pixel_option):{ "url": "https://…" }או קובץ. פיקסל בתשלום מתווסף למחיר. - redeem_later: true (+ quantity עד 20) — מימוש עתידי: קונים עכשיו עם website_id בלבד, ושולחים פרטים אחרי התשלום ב-redeem.
- תאריך פרסום — ראשון עד חמישי בלבד. כתבה מוכנה (html/docx) — מילת מפתח וקישור רשות, אבל תמיד יחד.
- המחירון והצעת המחיר מחזירים לכל אתר את כללי הכתיבה והפרסום שלו (writing_notes, publishing_restrictions) — הכותב שלנו פועל לפיהם. כל מחיר מסביר מאיפה הוא: מבצע / מחיר מיוחד / מחירון, וההנחה הקבועה שלכם.
- קופונים: הקופונים האישיים שלכם מוחלים אוטומטית, באותם כללים כמו בסל באתר. לקוד מסוים —
coupon_code; בלי קופונים אוטומטיים —apply_coupons: false. הצעת המחיר מראה אילו קופונים חלו וכמה הם חוסכים. הקופון מנוצל רק כשההזמנה משולמת; אם נוצל בינתיים במקום אחר, הסכום מתעדכן לפני התשלום. - בשגיאת פרטים ההודעה מפרטת מה חסר בכל כתבה, ו-
details[].errors[].fieldאומר איזה שדה לתקן. - אין לפרסם תכנים בנושאי הימורים, טבק/עישון, תכנים מיניים או שירותי ליווי.
סטטוסים
| pending | ממתין — לתשלום (payment_status) או לאישור הנושא על ידי הצוות |
| topic_approved / writing | הכנת תוכן |
| admin_review | בבדיקת הצוות |
| review | ממתין לאישור שלכם (approve / request_fix) |
| approved | אושר — לפני שליחה לאתר |
| awaiting_image_approval | נדרש אישור תמונה (נשלח במייל) |
| sent_to_publisher | נשלח לאתר |
| draft_review / publisher_draft_review | טיוטה באתר ממתינה לאישורכם — באתר BuyPost |
| published | פורסם — published_url |
| rejected | נדחה — זיכוי לפי התקנון |
מצב התשלום של כל כתבה: payment_status = awaiting_payment / paid / cancelled. הזמנה שלא שולמה לא נכתבת, לא נשלחת לאתר ולא מתפרסמת. awaiting_redemption: true = נקנתה ושולמה ומחכה לפרטים שלכם (redeem). waiting_for_you: true = ממתינה לאישור שלכם (ונשלחת הודעת article.waiting_for_approval); השדה available_actions אומר אילו פעולות אפשריות עכשיו — טיוטה באתר המפרסם מאשרים באתר BuyPost. לכל כתבה יש progress: שלב, תיאור בעברית, על מי היא ממתינה ומה הצעד הבא; כתבה שפורסמה — published_url ו-published_at.
עדכונים לשרת שלכם (webhook)
מגדירים כתובת בעמוד API באזור האישי. בכל שינוי סטטוס של כתבה נשלחת בקשת POST. סוגים: article.waiting_for_approval, article.published, article.rejected, article.status_changed, order.paid (הזמנת API שולמה באתר והכתבות נכנסו לעבודה), credits.added (נוספו קרדיטים — קראו list_redeemable). כל הודעה חתומה — ודאו את החתימה:
// Node.js — אימות הודעת webhook
import crypto from 'node:crypto';
function isFromBuyPost(rawBody, headers, secret) {
const ts = headers['x-buypost-timestamp'];
const sig = (headers['x-buypost-signature'] || '').replace('sha256=', '');
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false; // older than 5 minutes
const expected = crypto.createHmac('sha256', secret).update(`${ts}.${rawBody}`).digest('hex');
return sig.length === expected.length && crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
}
ענו בקוד 2xx תוך 5 שניות. הודעה שלא התקבלה נשלחת פעם נוספת; כל המשלוחים מופיעים ביומן בעמוד API.
שגיאות
| 401 | missing_or_malformed_key / invalid_key | מפתח חסר, שגוי או מבוטל |
| 403 | api_not_enabled | הגישה ל-API לא אושרה לחשבון |
| 403 | site_only | פעולה שנעשית רק באתר: תשלום, קניית קרדיטים, הגדרת webhook |
| 409 | not_waiting_for_approval / not_cancellable / not_editable | הכתבה לא בשלב שמאפשר את הפעולה — ההודעה מסבירה מתי כן |
| 422 | validation_failed | פרטי כתבה לא תקינים — details מפרט לכל כתבה (index) את הבעיות. לא נוצרה הזמנה |
| 422 | billing_profile_incomplete | חסרים שם וטלפון בפרופיל — יש להשלים פעם אחת באתר |
| 404 | order_not_found / item_not_found | ההזמנה או הכתבה לא קיימות או שאינן של החשבון |
| 409 | order_not_paid / redeem_details_required / redeem_after_payment | שינוי כתבה של הזמנת אתר שלא שולמה; תאריך בלי פרטי כתבה לכתבה שלא מומשה; מימוש עתידי לפני התשלום |
| 400 | note_required / reason_required / changes_missing / item_ids_missing | חסר שדה בבקשה — ההודעה אומרת איזה |
| 422 | scheduled_date_invalid / scheduled_date_weekend | תאריך פרסום בעבר, בפורמט לא נכון, או בשישי / שבת |
| 422 | coupon_not_found / coupon_unusable / coupon_min_order / coupon_not_combinable / coupon_not_applicable | קוד הקופון לא נמצא, לא בתוקף, מתחת למינימום, לא משתלב עם הנחה קבועה, או לא חל על הכתבות |
| 409 | coupon_changed | הקופון נוצל או פג לפני התשלום — הסכום עודכן, אשרו שוב |
| 409 | busy_try_again | פעולה אחרת של החשבון מתבצעת — נסו שוב בעוד כמה שניות |
| 429 | rate_limited / daily_request_limit | יותר מ-10 בקשות בדקה, או חריגה ממכסת הבקשות היומית (300 לחשבון) |
| 429 | daily_article_limit / too_many_unpaid_orders | חריגה ממכסת הכתבות היומית, או יותר מדי הזמנות שמחכות לתשלום |
| 429 | too_many_bad_keys | יותר מדי ניסיונות עם מפתח שגוי מאותה כתובת — חסימה ל-10 דקות |
| 500 | internal_error / order_failed | שגיאה אצלנו — נסו שוב (עם אותו idempotency_key, בלי חשש לכפילות) |