קישורים מקוצרים וסודות, ישירות מהקוד
מפתח bearer אחד, JSON רגיל ואותם כללי תוכנית כמו בלוח הבקרה. מיועד לתוספים, לכלי CLI, לשרתי MCP ולכלים פנימיים.
גישה מוקדמת. נקודות הקצה של v1 מופעלות בהדרגה, סביבת עבודה אחר סביבת עבודה. אם קריאה מחזירה 503 עם הקוד disabled, ה-API עדיין לא הופעל אצלכם. אפשר ליצור מפתחות כבר היום, והם יעבדו ברגע שה-API יופעל.
ספריות לקוח
הסודות מוצפנים לפני השליחה, ולכן כל תוכנת לקוח צריכה להצפין אותם בעצמה. הספריות האלה עושות את זה פעם אחת ובצורה נכונה, ונבדקות מול אותם וקטורי בדיקה ששמורים במאגר הקוד ושאפליקציית האינטרנט נבדקת מולם. שלושתן ברישיון MIT, מתפרסמות מה-CI עם npm provenance ולא תלויות בשום דבר מלבד הספרייה הסטנדרטית.
SDK ל-TypeScript
npmלקוח עם טיפוסים לכל נתיב. בלי תלויות, רק WebCrypto, ולכן הוא רץ בלי שינוי על Node 20+, Deno, Bun, בדפדפנים ובסביבות edge.
npm i @uselinkpilot/sdkשורת הפקודה
npmהעבירו את הסוד דרך pipe ולא כארגומנט: ארגומנט נשמר בהיסטוריית ה-shell ונראה ברשימת התהליכים.
npm i -g linkpilot
echo 'db password: hunter2' | linkpilot secret --ttl 1hשרת MCP
npmעוזר AI יכול למסור למישהו פרטי התחברות בלי שהם יישארו ביומן הצ'אט. הוסיפו את זה ל-Claude Desktop, ל-Claude Code, ל-Cursor או לכל לקוח MCP:
{
"mcpServers": {
"linkpilot": {
"command": "npx",
"args": ["-y", "@uselinkpilot/mcp"],
"env": { "LINKPILOT_API_KEY": "lp_live_..." }
}
}
}כדאי לדעת לפני ההתקנה: הטקסט הגלוי עובר דרך ההקשר של העוזר, כי המודל חייב לראות את הסוד כדי ליצור אותו. השרת מגן עליו בזמן ההעברה ובזמן האחסון, ובכך שאפשר לפתוח אותו פעם אחת בלבד. מהמודל עצמו הוא לא יכול להסתיר אותו.
קוד המקור: linkpilot-cli (SDK ו-CLI) וגם linkpilot-mcp.
1. אימות
צרו מפתח בכתובת /app/api-keys (לבעלים ולמנהלים של סביבת העבודה). המפתח עצמו מוצג פעם אחת בלבד, ו-LinkPilot שומר רק את ה-hash שלו ב-SHA-256. שלחו אותו בכל בקשה:
Authorization: Bearer lp_live_...כל מפתח קשור לסביבת עבודה אחת, ולכן אין בשום מקום פרמטר tenant. מפתח שבוטל, שפג תוקפו, שאינו מוכר או שאינו תקין מחזיר תמיד את אותה תגובה, 401 unauthorized. מפתחות אף פעם לא נכתבים ליומנים.
כתובת בסיס: https://khiydxamyihofmtmgvjz.supabase.co/functions/v1/api-v1
2. נתיבים
| שיטה | נתיב | מה הוא עושה |
|---|---|---|
| GET | /me | סביבת העבודה, התוכנית, המגבלות, השימוש ותקציב הבקשות של המפתח |
| POST | /links | יצירת קישור מקוצר (url, ואופציונלית גם slug, domain, title ו-tags) |
| GET | /links | רשימת קישורים, מהחדש לישן, עם דפדוף לפי cursor |
| GET | /links/{id} | שליפת קישור אחד |
| DELETE | /links/{id} | מחיקת קישור |
| POST | /secrets | יצירת קישור סודי (ciphertext, enc_version, ttl_seconds, burn_after_read, ובתוכנית Pro גם passphrase_hash) |
| GET | /secrets | רשימת המטא-נתונים של הסודות (אף פעם לא התוכן) |
| DELETE | /secrets/{id} | ביטול הקישור הסודי והשמדת התוכן שלו |
| POST | /public/links | יצירת קישור אנונימי עם client_id, בלי מפתח |
| POST | /public/secrets | יצירת סוד אנונימי עם מחיקה לאחר קריאה, בלי מפתח |
רשימות מחזירות { data, next_cursor }. כדי להמשיך, שלחו את next_cursor בחזרה בתור cursor. הערך של limit הוא בין 1 ל-100.
3. דוגמאות
יצירת קישור עם curl
curl -X POST "https://khiydxamyihofmtmgvjz.supabase.co/functions/v1/api-v1/links" \
-H "Authorization: Bearer $LINKPILOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com/launch","slug":"launch","tags":["campaign"]}'יצירת סוד מ-JavaScript
const b64u = (b) => btoa(String.fromCharCode(...new Uint8Array(b)))
.replace(/+/g, "-").replace(///g, "_").replace(/=+$/, "");
// 1. Encrypt locally. This key is generated here and never sent anywhere.
const key = crypto.getRandomValues(new Uint8Array(32));
const iv = crypto.getRandomValues(new Uint8Array(12));
const k = await crypto.subtle.importKey("raw", key, "AES-GCM", false, ["encrypt"]);
const ct = await crypto.subtle.encrypt(
{ name: "AES-GCM", iv, tagLength: 128 },
k,
new TextEncoder().encode("staging db password"),
);
const ciphertext = `v1.${b64u(iv)}.${b64u(ct)}`;
// 2. Store the blob. LinkPilot cannot read it.
const res = await fetch("https://khiydxamyihofmtmgvjz.supabase.co/functions/v1/api-v1/secrets", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.LINKPILOT_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ ciphertext, enc_version: 1, ttl_seconds: 3600 }),
});
if (!res.ok) throw new Error((await res.json()).error.code);
const { secret_url } = await res.json();
// 3. Attach the key. Without this the link can never be opened, by anyone.
const shareUrl = `${secret_url}#k=${b64u(key)}`;רשימת קישורים מ-Python
import os, requests
r = requests.get(
"https://khiydxamyihofmtmgvjz.supabase.co/functions/v1/api-v1/links",
params={"limit": 20},
headers={"Authorization": f"Bearer {os.environ['LINKPILOT_API_KEY']}"},
)
r.raise_for_status()
for link in r.json()["data"]:
print(link["short_url"], "->", link["url"])
print("remaining this hour:", r.headers["X-RateLimit-Remaining"])יצירת קישור אנונימי בלי מפתח
curl -X POST "https://khiydxamyihofmtmgvjz.supabase.co/functions/v1/api-v1/public/links" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com","client_id":"my-cli-0123456789abcdef"}'החוזה הפורמלי מתפרסם כאן ולא במאגר קוד: מסמך OpenAPI 3.1, אוסף Postman וגם התיעוד הכתוב. כוונו את מחולל הקוד ישירות לכתובת ה-URL של OpenAPI.
4. איך הסודות נשמרים
כאן חשוב לדייק, כי ללקוח API יש עבודה אמיתית לעשות: ה-API לא מקבל בכלל payload בטקסט גלוי.
- אתם מצפינים, אנחנו שומרים blob. שלחו
ciphertext(AES-GCM-256,v1.<iv>.<ct>) עםenc_version: 1. בקשה עםpayloadנדחית, ולא מתקבלת בשקט. - את המפתח צריך להוסיף בעצמכם. ב-
secret_urlשאנחנו מחזירים אין מפתח, וגם לא יכול להיות: אף פעם לא ראינו אותו. הוסיפו#k=<base64url key>. דפדפנים אף פעם לא שולחים את החלק של הקישור שאחרי הסימן#, ולכן הנמען מפענח את הסוד אצלו במכשיר. - אין שחזור. אם המפתח אבד, הסוד אבד, גם לכם וגם לנו. ככה ההבטחה עובדת.
- מושמד אחרי הקריאה, כשפג התוקף או כשהקישור מבוטל. הטקסט המוצפן השמור נדרס בצד השרת.
- ה-API אף פעם לא מחזיר אותו. אף נתיב לא מחזיר תוכן או טקסט מוצפן. הקורא היחיד הוא דף ההצגה של הנמען, שרושם את הצפייה.
- ביטויי סיסמה (מתוכנית Pro ומעלה) הם גורם שני אמיתי: הם עוברים מתיחה עם PBKDF2-SHA256 ומשולבים במפתח עם HKDF, כך שלא הקישור לבדו ולא ביטוי הסיסמה לבדו מספיקים לפענוח. שלחו רק את
passphrase_hash, ה-hex של SHA-256 על ביטוי הסיסמה אחרי נרמול NFKC, ואף פעם לא את ביטוי הסיסמה עצמו, שהוא חצי מהמפתח. גזרו את המפתח מאותה צורת NFKC, כדי שביטוי סיסמה שהוקלד במקלדת אחרת עדיין יפתח את הסוד. - ממה זה לא מגן. מי שמחזיק בקישור המלא מחזיק גם במפתח, ולכן תוקף קצר ומחיקה לאחר קריאה עדיין חשובים. קבצים מצורפים מוצפנים באותה דרך, עם מפתח שנגזר מאותו קישור.
פורמט ההעברה מתואר בתיעוד ה-API, והחבילה @uselinkpilot/sdk מבצעת את כל התהליך בקריאה אחת אם אתם לא רוצים לכתוב אותו בעצמכם. אותו מודל מתואר גם בעמוד ארכיטקטורת האבטחה.
5. מגבלות תוכנית ומגבלות קצב
| מגבלה | Free | Pro | Agency |
|---|---|---|---|
| קישורים | 50 | ללא הגבלה | ללא הגבלה |
| סודות פעילים | 5 | 100 | 100 |
| סודות עם ביטוי סיסמה | לא | כן | כן |
| דומיינים מותאמים לקישורים | דומיינים מאומתים קיימים | עד 5 | ללא הגבלה |
| בקשות למפתח בשעה | 60 | 1,000 | 5,000 |
ה-API מפעיל את אותם כללי תוכנית כמו לוח הבקרה, מאותו מקור, ולכן גם המגבלות המאוחדות של תוכניות Agency חלות כאן. הנתיב GET /me מחזיר את המספרים העדכניים של סביבת העבודה. כל תגובה מאומתת כוללת את X-RateLimit-Limit, X-RateLimit-Remaining ו-X-RateLimit-Reset.
6. נתיבים ציבוריים בלי מפתח
הנתיבים POST /public/links ו-POST /public/secrets נועדו ללקוחות שלא יכולים להציג אתגר בדפדפן: כלי CLI, שרתי MCP וה-launcher. הם מקבלים client_id אטום (16 עד 64 תווים, נוצר פעם אחת לכל התקנה) ויוצרים רשומות באותו מאגר אנונימי שבו משתמשים הכלים החינמיים באתר.
- 20 יצירות ללקוח ביום ו-60 לרשת בשעה, וגם המגבלות של המאגר עצמו לכל רשת.
- אותו סינון מול מקורות מידע על איומים, אותה בדיקת URL מול Google ואותן בדיקות חוזרות מתוזמנות כמו בכל דרך יצירה אחרת.
- בלי דומיין מותאם, בלי סיומת מותאמת אישית ובלי ביטוי סיסמה. סודות ציבוריים תמיד נמחקים אחרי קריאה אחת, ותוקפם פג תוך 24 שעות.
- התגובה כוללת
claim_token, כדי שמשתמש מחובר יוכל לשייך את הרשומה לסביבת עבודה מאוחר יותר. התייחסו אליו כמו לפרטי התחברות.
7. שגיאות
כל שגיאה היא { "error": { "code", "message", "upgrade_url"? } }. ההודעות מציינות את השדה, אף פעם לא את הנתונים שלכם. משאב בסביבת עבודה אחרת מחזיר 404, לא 403.
| קוד | HTTP | מתי |
|---|---|---|
| unauthorized | 401 | מפתח חסר, לא תקין, לא מוכר, מבוטל או שפג תוקפו |
| disabled | 503 | ה-API עדיין לא הופעל בפריסה הזאת |
| invalid_request | 400 | שגיאת אימות נתונים, יעד חסום, סיומת תפוסה, דומיין לא מוכר |
| not_found | 404 | אין נתיב כזה, או שהמשאב לא נמצא בסביבת העבודה שלכם |
| plan_limit | 402 | הגעתם למכסת הקישורים או הסודות הפעילים (כולל upgrade_url) |
| pro_required | 402 | ביטוי סיסמה בתוכנית שלא כוללת אותו (כולל upgrade_url) |
| rate_limited | 429 | תקציב הבקשות השעתי של המפתח או המכסה הציבורית נוצלו (כולל Retry-After) |
שאלות שמפתחים שואלים
- אילו תוכניות כוללות את ה-API?
- יוצרים מפתחות API מלוח הבקרה, בנתיב /app/api-keys. כל מפתח פועל לפי מגבלות התוכנית של סביבת העבודה שלו: ב-Free יש 50 קישורים ו-5 סודות פעילים עם 60 בקשות בשעה; ב-Pro יש קישורים ללא הגבלה, 100 סודות פעילים, סודות מוגנים בביטוי סיסמה ו-1,000 בקשות בשעה; תוכניות Agency מקבלות 5,000 בקשות בשעה.
- האם תוכן הסודות מוצפן מקצה לקצה?
- כן, וה-API לא מקבל טקסט גלוי בכלל. אתם מצפינים עם AES-GCM-256 ושולחים טקסט מוצפן; LinkPilot שומר blob שאין לו מפתח אליו ולא יכול לפענח אותו. מכיוון שאנחנו אף פעם לא רואים את המפתח, ב-secret_url שאנחנו מחזירים אין מפתח. אתם מוסיפים אותו בעצמכם בחלק של הקישור שאחרי הסימן #, בצורה #k=, ודפדפנים אף פעם לא שולחים את החלק הזה. אם המפתח אבד, אף אחד לא יכול לשחזר את הסוד, גם לא אנחנו. קבצים מצורפים מוצפנים באותה דרך, עם מפתח שנגזר מאותו קישור.
- אפשר ליצור קישורים בלי מפתח API?
- כן. הנתיבים POST /public/links ו-POST /public/secrets מקבלים client_id אטום במקום מפתח ויוצרים רשומות באותו מאגר אנונימי שבו משתמשים הכלים החינמיים באתר: 20 יצירות ללקוח ביום, 60 לרשת בשעה, בלי דומיין מותאם ובלי ביטוי סיסמה, ותוקף הסודות פג תוך 24 שעות.
- מה קורה כשמגיעים למגבלה?
- מגבלות תוכנית מחזירות HTTP 402 עם הקוד plan_limit או pro_required ועם upgrade_url. מגבלות קצב מחזירות 429 עם הכותרת Retry-After. כל תגובה מאומתת כוללת את X-RateLimit-Limit, את X-RateLimit-Remaining ואת X-RateLimit-Reset, כדי שלקוחות יוכלו להאט לפני שזה קורה.
- האם ה-API יציב?
- נתיבי v1 לא ישתנו באופן ששובר תאימות. שינויים שוברי תאימות יוצאים כגרסה חדשה. בתקופת הגישה המוקדמת נקודות הקצה מופעלות סביבת עבודה אחר סביבת עבודה; תגובת 503 עם הקוד disabled פירושה שה-API עדיין לא הופעל בסביבת העבודה שלכם.
מוכנים להתחיל לפתח?
צרו מפתח בסביבת העבודה שלכם, או התחילו בתוכנית Free.