> ## Documentation Index
> Fetch the complete documentation index at: https://docs.livingsecurity.com/llms.txt
> Use this file to discover all available pages before exploring further.

# מגבלות קצב

> תקציבי בקשות עבור ה-API הציבורי של Living Security, חוזה התגובה 429, והאופן לבצע ניסיון חוזר באמצעות Retry-After.

ה-API של `/v1` אוכף שני תקציבי בקשות עצמאיים. בקשה נדחית
אם אחד מהתקציבים אזל.

| תקציב | חל על |
| - | - |
| לכל מפתח API | כל בקשה המציגה את המפתח הזה, מכל כתובת |
| לכל כתובת IP של לקוח | כל בקשה מאותה כתובת, בין אם היא מאומתת ובין אם לא |

התקציב לכל מפתח עוקב אחר המפתח בכל מקום שבו נעשה בו שימוש. התקציב לכל כתובת IP
הוא התקציב היחיד עבור תעבורה לא מאומתת, ותקרה שנייה עבור תעבורה מאומתת.

<Note>
  המגבלות נאכפות לפני האימות, ולכן גם בקשות עם אישורי גישה לא תקינים או חסרים
  נספרות במסגרת תקציב המקור. התקציבים המספריים המדויקים נקבעים על ידי המפעיל ועשויים להשתנות;
  חוזה התגובה שלהלן הוא הממשק היציב שעליו יש לבסס את הפיתוח.
</Note>

יש לבצע אימות באחד משני מבני אישורי ה-Basic — ראו
[התחלה מהירה](/he/developers/v1/quickstart) (`apikey:secret` או `secret:`).
יש להגדיר את `BASE` למארח האזורי של הארגון — ראו
[אזורים](/he/developers/v1/regions).

## תגובת 429

כאשר תקציב אזל, ה-API מחזיר `429 Too Many Requests` עם
כותרת `Retry-After` (בשניות) וגוף תקני של פרטי בעיה (problem details):

```json 429 Too Many Requests theme={null}
{
  "type": "https://docs.livingsecurity.com/developers/v1/errors/rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "detail": "Rate limit exceeded. Retry after the Retry-After interval.",
  "code": "rate_limited",
  "request_id": "req_...",
  "doc_url": "https://docs.livingsecurity.com/developers/v1/errors/rate_limited",
  "retryable": true
}
```

התגובה אינה מציינת איזה תקציב אזל. יש להתייחס לכל `429`
באותו אופן: להמתין ואז לנסות שוב.

## טיפול בתגובות 429

<Steps>
  <Step title="כיבוד Retry-After">
    יש להמתין לפחות את מספר השניות המצוין בכותרת `Retry-After` לפני
    ביצוע ניסיון חוזר. ניסיון חוזר מוקדם יותר רק צורך שוב תקציב בבקשות שיידחו.
  </Step>

  <Step title="האטה מעריכית בניסיונות חוזרים">
    אם ניסיון חוזר נדחה שוב, יש להגדיל את זמן ההמתנה ולהוסיף jitter אקראי
    כדי שעובדים מקבילים לא יבצעו ניסיונות חוזרים בו-זמנית. אין לקצר את `Retry-After` של השרת כדי להתאימו למגבלה מקומית. אם השרת מבקש להמתין זמן רב יותר ממה שתקציב הניסיונות החוזרים שלכם מאפשר,
    יש להפסיק ולתזמן את העבודה למועד מאוחר יותר.
  </Step>

  <Step title="החלקת קצב הבקשות">
    מומלץ להעדיף קצב בקשות יציב על פני פרצים. בקריאות נפח גדול, יש להשתמש בגודל העמוד המרבי
    (`limit=500`) כדי לכסות את האוסף בפחות בקשות — ראו
    [דפדוף](/he/developers/v1/pagination). כאשר כמה מעברי רשימה פועלים
    במקביל (לדוגמה, טבלאות Power BI), יש לשמור על רמת מקביליות מתונה ולכבד
    את `Retry-After` כדי ש-429 זמני לא יכשיל את הרענון כולו.
  </Step>
</Steps>

דוגמה זו מבצעת ניסיון חוזר רק בתגובות `429` עבור בקשת **GET**, עם לכל היותר
חמישה ניסיונות ולכל היותר 60 שניות המתנה בין ניסיון לניסיון. היא נעצרת
מיד בשגיאות אחרות. פסקי זמן ברשת מועברים אל הקורא. יש להגדיר
פסקי זמן ותקציבי ניסיונות חוזרים בהתאם לעומס העבודה שלכם. `requests` מפרש את פסק הזמן
לקריאה כזמן הסרק המרבי בעת קבלת נתונים, ולא כמועד יעד כולל.

יש לטעון את `LIVING_SECURITY_API_KEY` ממנהל הסודות שלכם. יש להתקין את `requests`
לפני הרצת הדוגמה. יש לקרוא ל-`get_with_retry("/organization")` כדי להשתמש בה.

```python Python theme={null}
import os
import random
import time
import requests

# US: BASE = "https://api.us-east-1.livingsecurity.ai/v1"
BASE = "https://api.eu-west-1.livingsecurity.ai/v1"
AUTH = ("apikey", os.environ["LIVING_SECURITY_API_KEY"])

def get_with_retry(path, params=None, max_attempts=5):
    if not 1 <= max_attempts <= 5:
        raise ValueError("max_attempts must be between 1 and 5")
    for attempt in range(max_attempts):
        response = requests.get(
            f"{BASE}{path}", auth=AUTH, params=params,
            headers={"Living-Security-Version": "2026-07-01"},
            timeout=(5, 30), allow_redirects=False,
        )
        if response.status_code != 429:
            response.raise_for_status()
            if not 200 <= response.status_code < 300:
                raise RuntimeError("Unexpected redirect; check your regional API URL")
            return response

        # The API returns Retry-After as a whole number of seconds.
        raw_wait = response.headers.get("Retry-After", "")
        request_id = response.headers.get("Request-Id", "unknown")
        response.close()
        if attempt == max_attempts - 1:
            raise RuntimeError(f"Retry budget exhausted; request_id={request_id}")
        if not raw_wait.isascii() or not raw_wait.isdigit() or len(raw_wait) > 6:
            raise RuntimeError(f"Invalid Retry-After; request_id={request_id}")

        wait = max(int(raw_wait), min(2 ** attempt, 30))
        delay = wait + random.uniform(0, 1)
        if delay > 60:
            raise RuntimeError(f"Retry-After exceeds wait budget; request_id={request_id}")
        time.sleep(delay)
```

אין להעתיק לולאה זו סביב פעולת כתיבה. פסק זמן לאחר כתיבה עשוי
לציין שהשרת ביצע את הפעולה לפני שהחיבור נכשל. יש לחזור על כתיבה רק
כאשר התיעוד של אותה פעולה מציין במפורש אידמפוטנטיות, תוך שמירה על אותו
מפתח ועל אותו מטען (payload). אחרת, יש ליישב את מצב המשאב לפני ביצוע ניסיון נוסף.

## לוח זמנים מומלץ לרענון

יש לקבוע את תדירות הרענון בהתאם לתקציב המפתח ולגודל העמוד. טעינה היסטורית מלאה
של אוסף גדול היא עלות חד-פעמית; מומלץ להעדיף חלונות מצטברים ברענונים
במצב יציב, כך שכל הרצה תישאר הרבה מתחת לתקציב. יש להגדיר תמיד
את `limit=500` במפורש — ברירת המחדל של 25 מכפילה את מספר הבקשות.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.