शॉर्ट लिंक और सीक्रेट, सीधे कोड से
एक bearer key, सादा JSON और डैशबोर्ड वाले ही प्लान नियम। एक्सटेंशन, CLI, MCP सर्वर और अंदरूनी टूल के लिए बना है।
अर्ली एक्सेस। v1 एंडपॉइंट एक-एक वर्कस्पेस के लिए चालू किए जा रहे हैं। अगर कोई कॉल 503 और कोड disabled लौटाए, तो आपके लिए API अभी चालू नहीं हुआ है। API keys आज ही बनाई जा सकती हैं और API चालू होते ही काम करने लगेंगी।
क्लाइंट लाइब्रेरी
सीक्रेट भेजे जाने से पहले एन्क्रिप्ट होते हैं, इसलिए हर क्लाइंट को यह काम खुद करना होता है। ये लाइब्रेरी इसे एक बार सही तरीके से करती हैं, उन्हीं कमिट किए गए टेस्ट वेक्टर के साथ जिन्हें वेब ऐप इस्तेमाल करता है। तीनों MIT लाइसेंस में हैं, CI से npm provenance के साथ पब्लिश होती हैं और स्टैंडर्ड लाइब्रेरी के अलावा किसी चीज़ पर निर्भर नहीं हैं।
TypeScript SDK
npmहर रूट के लिए टाइप वाला क्लाइंट। कोई डिपेंडेंसी नहीं, सिर्फ़ WebCrypto, इसलिए यह बिना बदलाव के Node 20+, Deno, Bun, ब्राउज़र और एज रनटाइम पर चलता है।
npm i @uselinkpilot/sdkकमांड लाइन
npmसीक्रेट को आर्गुमेंट के रूप में देने की जगह पाइप से भेजें: आर्गुमेंट आपकी शेल हिस्ट्री में चला जाता है और प्रोसेस लिस्ट में दिखता है।
npm i -g linkpilot
echo 'db password: hunter2' | linkpilot secret --ttl 1hMCP सर्वर
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 पर key बनाएं (वर्कस्पेस के ओनर और एडमिन)। असली key सिर्फ़ एक बार दिखती है; LinkPilot सिर्फ़ उसका SHA-256 हैश रखता है। इसे हर रिक्वेस्ट के साथ भेजें:
Authorization: Bearer lp_live_...API keys एक वर्कस्पेस से जुड़ी होती हैं, इसलिए कहीं भी tenant पैरामीटर नहीं है। वापस ली गई, एक्सपायर हो चुकी, अनजान और गलत फ़ॉर्मैट वाली, सभी keys एक ही 401 unauthorized लौटाती हैं। API keys कभी लॉग में नहीं लिखी जातीं।
बेस URL: https://khiydxamyihofmtmgvjz.supabase.co/functions/v1/api-v1
2. रूट
| मेथड | पाथ | यह क्या करता है |
|---|---|---|
| GET | /me | वर्कस्पेस, प्लान, सीमाएं, इस्तेमाल और आपकी key का रेट बजट |
| POST | /links | शॉर्ट लिंक बनाएं (url, और चाहें तो slug, domain, title, tags) |
| GET | /links | लिंक की सूची, सबसे नए पहले, कर्सर पेजिनेशन के साथ |
| 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 के साथ गुमनाम लिंक बनाएं, बिना key के |
| POST | /public/secrets | पढ़ते ही मिटने वाला गुमनाम सीक्रेट बनाएं, बिना key के |
सूचियां { 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"])बिना key के गुमनाम लिंक बनाएं
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 कलेक्शन और लिखित रेफ़रेंस। अपने कोड जनरेटर को सीधे OpenAPI URL पर लगाएं।
4. सीक्रेट कैसे स्टोर होते हैं
हम यहां बिल्कुल सटीक रहना चाहते हैं, क्योंकि API क्लाइंट को यहां असली काम करना होता है: API बिना एन्क्रिप्शन वाला payload बिल्कुल स्वीकार नहीं करता।
- एन्क्रिप्ट आप करते हैं, हम सिर्फ़ ब्लॉब स्टोर करते हैं।
ciphertext(AES-GCM-256,v1.<iv>.<ct>) कोenc_version: 1के साथ भेजें।payloadभेजने पर रिक्वेस्ट चुपचाप मान लेने की जगह ठुकरा दी जाती है। - कुंजी आपको खुद जोड़नी होगी। हम जो
secret_urlलौटाते हैं उसमें कुंजी नहीं होती और हो भी नहीं सकती: हमने उसे कभी देखा ही नहीं।#k=<base64url key>जोड़ें। ब्राउज़र#के बाद का हिस्सा कभी नहीं भेजते, इसलिए प्राप्तकर्ता अपने डिवाइस पर ही डिक्रिप्ट करता है। - वापस पाने का कोई तरीका नहीं है। कुंजी खो गई तो सीक्रेट हमेशा के लिए गया, आपके लिए भी और हमारे लिए भी। गारंटी इसी तरह काम करती है।
- पढ़े जाने, एक्सपायर होने या वापस लिए जाने पर मिट जाता है। स्टोर किया हुआ सिफ़रटेक्स्ट सर्वर पर ओवरराइट कर दिया जाता है।
- API इसे कभी नहीं लौटाता। कोई भी रूट कॉन्टेंट या सिफ़रटेक्स्ट वापस नहीं भेजता। इसे सिर्फ़ प्राप्तकर्ता का सीक्रेट खोलने वाला पेज पढ़ता है, और सीक्रेट के खुलने को भी वही दर्ज करता है।
- पासफ़्रेज़ (Pro और उससे ऊपर) असली दूसरा फ़ैक्टर हैं: इन्हें PBKDF2-SHA256 से स्ट्रेच करके HKDF से कुंजी में मिला दिया जाता है, इसलिए न अकेला लिंक डिक्रिप्ट कर सकता है, न अकेला पासफ़्रेज़। सिर्फ़
passphrase_hashभेजें, यानी NFKC में नॉर्मलाइज़ किए गए पासफ़्रेज़ का SHA-256 hex। असली पासफ़्रेज़ कभी न भेजें, क्योंकि वह कुंजी का आधा हिस्सा है। कुंजी भी इसी NFKC रूप से निकालें, ताकि किसी दूसरे कीबोर्ड पर टाइप किया गया पासफ़्रेज़ भी सीक्रेट खोल सके। - यह किससे नहीं बचाता। जिसके पास पूरा लिंक है, उसके पास कुंजी भी है, इसलिए छोटी एक्सपायरी और पढ़ते ही मिटना अब भी ज़रूरी हैं। फ़ाइल अटैचमेंट भी इसी तरह एन्क्रिप्ट होते हैं, उसी लिंक से निकली कुंजी से।
वायर फ़ॉर्मैट API रेफ़रेंस में दिया गया है। अगर आप इसे खुद नहीं लिखना चाहते, तो @uselinkpilot/sdk पूरा लेन-देन एक कॉल में कर देता है। यही मॉडल सिक्योरिटी आर्किटेक्चर पेज पर भी समझाया गया है।
5. प्लान की सीमाएं और रेट लिमिट
| सीमा | Free | Pro | Agency |
|---|---|---|---|
| लिंक | 50 | असीमित | असीमित |
| चालू सीक्रेट | 5 | 100 | 100 |
| पासफ़्रेज़ वाले सीक्रेट | नहीं | हां | हां |
| लिंक के लिए कस्टम डोमेन | पहले से वेरिफ़ाई किए गए डोमेन | 5 तक | असीमित |
| हर key से प्रति घंटे रिक्वेस्ट | 60 | 1,000 | 5,000 |
API डैशबोर्ड वाले ही प्लान नियम लागू करता है, उसी जगह से पढ़कर, इसलिए एजेंसी के तहत मिलने वाली सीमाएं यहां भी लागू होती हैं। GET /me आपके वर्कस्पेस के मौजूदा आंकड़े लौटाता है। ऑथेंटिकेशन वाले हर रिस्पॉन्स में X-RateLimit-Limit, X-RateLimit-Remaining और X-RateLimit-Reset होते हैं।
6. बिना key के पब्लिक रूट
POST /public/links और POST /public/secrets उन क्लाइंट के लिए हैं जो ब्राउज़र चैलेंज नहीं दिखा सकते: CLI, MCP सर्वर, लॉन्चर। ये एक ओपेक client_id लेते हैं (16 से 64 कैरेक्टर, हर इंस्टॉल पर एक बार बनाया गया) और वही गुमनाम पूल इस्तेमाल करते हैं जिसमें मुफ़्त वेब टूल के रिकॉर्ड बनते हैं।
- हर क्लाइंट से हर दिन 20 और हर नेटवर्क से हर घंटे 60 रिकॉर्ड, और इसके ऊपर पूल की अपनी प्रति-नेटवर्क सीमाएं।
- बाकी हर तरीके की तरह यहां भी थ्रेट फ़ीड से जांच, Google URL थ्रेट लुकअप और तय समय पर दोबारा जांच होती है।
- कस्टम डोमेन, कस्टम स्लग और पासफ़्रेज़ नहीं मिलते; पब्लिक सीक्रेट हमेशा एक बार पढ़े जाने के बाद मिट जाते हैं और 24 घंटे के अंदर एक्सपायर हो जाते हैं।
- रिस्पॉन्स में एक
claim_tokenहोता है, जिससे साइन इन किया हुआ यूज़र बाद में रिकॉर्ड को क्लेम करके अपने वर्कस्पेस से जोड़ सकता है। इसे क्रेडेंशियल की तरह संभालें।
7. एरर
हर एरर { "error": { "code", "message", "upgrade_url"? } } होता है। मैसेज में फ़ील्ड का नाम होता है, आपका डेटा कभी नहीं। दूसरे वर्कस्पेस के रिसोर्स पर 404 मिलता है, 403 नहीं।
| कोड | HTTP | कब |
|---|---|---|
| unauthorized | 401 | API key नहीं है, गलत फ़ॉर्मैट में है, अनजान है, वापस ली जा चुकी है या एक्सपायर हो चुकी है |
| disabled | 503 | इस डिप्लॉयमेंट के लिए API अभी चालू नहीं है |
| invalid_request | 400 | वैलिडेशन में गड़बड़ी, ब्लॉक किया गया डेस्टिनेशन, पहले से लिया हुआ स्लग, अनजान डोमेन |
| not_found | 404 | ऐसा कोई रूट नहीं है, या रिसोर्स आपके वर्कस्पेस में नहीं है |
| plan_limit | 402 | लिंक या चालू सीक्रेट की सीमा पूरी हो गई (upgrade_url साथ में) |
| pro_required | 402 | ऐसे प्लान पर पासफ़्रेज़ जिसमें यह सुविधा नहीं है (upgrade_url साथ में) |
| rate_limited | 429 | API key का घंटे का बजट या पब्लिक रूट की सीमा खत्म हो गई (Retry-After साथ में) |
डेवलपर अक्सर क्या पूछते हैं
- किन प्लान में API मिलता है?
- API keys डैशबोर्ड में /app/api-keys पर बनाई जाती हैं। हर key अपने वर्कस्पेस के प्लान की सीमाएं इस्तेमाल करती है: Free में 50 लिंक, 5 चालू सीक्रेट और हर घंटे 60 रिक्वेस्ट; Pro में असीमित लिंक, 100 चालू सीक्रेट, पासफ़्रेज़ वाले सीक्रेट और हर घंटे 1,000 रिक्वेस्ट; Agency प्लान में हर घंटे 5,000 रिक्वेस्ट।
- क्या सीक्रेट का कॉन्टेंट एंड-टू-एंड एन्क्रिप्टेड है?
- हां, और API बिना एन्क्रिप्शन वाला टेक्स्ट स्वीकार ही नहीं करता। आप AES-GCM-256 से एन्क्रिप्ट करके सिफ़रटेक्स्ट भेजते हैं; LinkPilot एक ब्लॉब स्टोर करता है जिसकी कुंजी उसके पास नहीं है और जिसे वह डिक्रिप्ट नहीं कर सकता। हम आपकी कुंजी कभी नहीं देखते, इसलिए हम जो secret_url लौटाते हैं उसमें कुंजी नहीं होती। उसे आप खुद #k= फ़्रैगमेंट के रूप में जोड़ते हैं, जिसे ब्राउज़र कभी नहीं भेजते। कुंजी खो गई तो सीक्रेट कोई भी वापस नहीं ला सकता, हम भी नहीं। फ़ाइल अटैचमेंट भी इसी तरह एन्क्रिप्ट होते हैं, उसी लिंक से निकली कुंजी से।
- क्या मैं API key के बिना लिंक बना सकता हूं?
- हां। POST /public/links और POST /public/secrets, key की जगह एक ओपेक client_id लेते हैं और रिकॉर्ड उसी गुमनाम पूल में बनाते हैं जिसमें मुफ़्त वेब टूल बनाते हैं: हर क्लाइंट से हर दिन 20, हर नेटवर्क से हर घंटे 60, कोई कस्टम डोमेन नहीं, कोई पासफ़्रेज़ नहीं, और सीक्रेट 24 घंटे के अंदर एक्सपायर हो जाते हैं।
- सीमा पूरी होने पर क्या होता है?
- प्लान की सीमा पर HTTP 402 मिलता है, जिसमें plan_limit या pro_required कोड और एक upgrade_url होता है। रेट लिमिट पर Retry-After हेडर के साथ 429 मिलता है। ऑथेंटिकेशन वाले हर रिस्पॉन्स में X-RateLimit-Limit, X-RateLimit-Remaining और X-RateLimit-Reset होते हैं, ताकि क्लाइंट ऐसा होने से पहले ही रफ़्तार कम कर सकें।
- क्या API स्थिर है?
- v1 रूट में ऐसा कोई बदलाव नहीं होगा जिससे आपका कोड टूटे। ऐसे बदलाव नए वर्शन में आते हैं। अर्ली एक्सेस के दौरान एंडपॉइंट एक-एक वर्कस्पेस के लिए चालू किए जा रहे हैं; disabled कोड वाले 503 रिस्पॉन्स का मतलब है कि आपके वर्कस्पेस के लिए API अभी चालू नहीं हुआ है।
बनाना शुरू करना चाहते हैं?
अपने वर्कस्पेस में key बनाएं या Free प्लान से शुरू करें।