Σύντομοι σύνδεσμοι και μυστικά, από κώδικα.
Ένα κλειδί bearer, απλό JSON και οι ίδιοι κανόνες πακέτου με τον πίνακα ελέγχου. Φτιαγμένο για επεκτάσεις, CLI, διακομιστές MCP και εσωτερικά εργαλεία.
Πρόωρη πρόσβαση. Τα endpoint της v1 ενεργοποιούνται σταδιακά, χώρο εργασίας προς χώρο εργασίας. Αν μια κλήση επιστρέφει 503 με κωδικό disabled, το API δεν έχει ενεργοποιηθεί ακόμη για εσάς. Μπορείτε να δημιουργήσετε κλειδιά από σήμερα και θα λειτουργήσουν μόλις ενεργοποιηθεί.
Βιβλιοθήκες πελάτη
Τα μυστικά κρυπτογραφούνται πριν σταλούν, οπότε κάθε πελάτης πρέπει να κάνει αυτό το κομμάτι μόνος του. Αυτές οι βιβλιοθήκες το κάνουν μία φορά και σωστά, με τα ίδια δεσμευμένα διανύσματα ελέγχου (test vectors) που χρησιμοποιεί η εφαρμογή web. Και οι τρεις έχουν άδεια MIT, δημοσιεύονται από το CI με npm provenance και δεν εξαρτώνται από τίποτα πέρα από την τυπική βιβλιοθήκη.
TypeScript SDK
npmΠελάτης με τύπους για κάθε διαδρομή. Χωρίς εξαρτήσεις, μόνο WebCrypto, οπότε τρέχει χωρίς αλλαγές σε Node 20+, Deno, Bun, προγράμματα περιήγησης και edge runtimes.
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_..." }
}
}
}Καλό είναι να το ξέρετε πριν το εγκαταστήσετε: το μη κρυπτογραφημένο κείμενο περνά από το πλαίσιο (context) του βοηθού, γιατί το μοντέλο πρέπει να δει ένα μυστικό για να το δημιουργήσει. Ο διακομιστής το προστατεύει κατά τη μεταφορά και κατά την αποθήκευση, και φροντίζει να ανοίγει μόνο μία φορά. Δεν μπορεί να το κρύψει από το ίδιο το μοντέλο.
Πηγαίος κώδικας: linkpilot-cli (SDK και CLI) και linkpilot-mcp.
1. Έλεγχος ταυτότητας
Δημιουργήστε ένα κλειδί στο /app/api-keys (κάτοχοι και διαχειριστές του χώρου εργασίας). Το πλήρες κλειδί εμφανίζεται μία φορά. Το LinkPilot κρατά μόνο το SHA-256 hash του. Στείλτε το σε κάθε αίτημα:
Authorization: Bearer lp_live_...Τα κλειδιά ανήκουν σε έναν χώρο εργασίας, οπότε δεν υπάρχει πουθενά παράμετρος tenant. Κλειδιά που έχουν ανακληθεί, έχουν λήξει, είναι άγνωστα ή λανθασμένα επιστρέφουν όλα το ίδιο 401 unauthorized. Τα κλειδιά δεν καταγράφονται ποτέ σε logs.
Βασικό URL: 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, passphrase_hash στο Pro) |
| 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, δηλαδή το SHA-256 σε hex της φράσης πρόσβασης κανονικοποιημένης κατά NFKC, και ποτέ την ίδια τη φράση, που είναι το μισό κλειδί. Παράγετε το κλειδί από την ίδια μορφή NFKC, ώστε η φράση να ανοίγει το μυστικό ακόμη κι αν πληκτρολογηθεί σε άλλο πληκτρολόγιο. - Τι δεν καλύπτει. Όποιος έχει ολόκληρο τον σύνδεσμο έχει και το κλειδί, οπότε η σύντομη λήξη και η διαγραφή μετά την ανάγνωση εξακολουθούν να μετράνε. Τα συνημμένα αρχεία κρυπτογραφούνται με τον ίδιο τρόπο, με κλειδί που παράγεται από τον ίδιο σύνδεσμο.
Η μορφή μετάδοσης περιγράφεται στην τεκμηρίωση του API, και το @uselinkpilot/sdk κάνει όλη την ανταλλαγή με μία κλήση, αν δεν θέλετε να την υλοποιήσετε μόνοι σας. Το ίδιο μοντέλο περιγράφεται στη σελίδα αρχιτεκτονικής ασφάλειας.
5. Όρια πακέτων και όρια αιτημάτων
| Όριο | Free | Pro | Agency |
|---|---|---|---|
| Σύνδεσμοι | 50 | Απεριόριστοι | Απεριόριστοι |
| Ενεργά μυστικά | 5 | 100 | 100 |
| Μυστικά με φράση πρόσβασης | Όχι | Ναι | Ναι |
| Δικά σας domain για συνδέσμους | Ήδη επαληθευμένα domain | Έως 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 χαρακτήρες, δημιουργείται μία φορά ανά εγκατάσταση) και δημιουργούν εγγραφές στην ίδια ανώνυμη δεξαμενή με τα δωρεάν εργαλεία web.
- 20 δημιουργίες ανά πελάτη την ημέρα και 60 ανά δίκτυο την ώρα, συν τα όρια ανά δίκτυο της ίδιας της δεξαμενής.
- Ο ίδιος έλεγχος σε λίστες απειλών, ο ίδιος έλεγχος URL στη Google και οι ίδιοι προγραμματισμένοι επανέλεγχοι με κάθε άλλο τρόπο δημιουργίας.
- Χωρίς δικό σας domain, χωρίς προσαρμοσμένη κατάληξη συνδέσμου, χωρίς φράση πρόσβασης. Τα δημόσια μυστικά διαγράφονται πάντα μετά από μία ανάγνωση και λήγουν μέσα σε 24 ώρες.
- Η απάντηση περιέχει ένα
claim_token, ώστε ένας συνδεδεμένος χρήστης να προσθέσει αργότερα την εγγραφή σε χώρο εργασίας. Χειριστείτε το ως διαπιστευτήριο.
7. Σφάλματα
Κάθε σφάλμα έχει τη μορφή { "error": { "code", "message", "upgrade_url"? } }. Τα μηνύματα αναφέρουν το πεδίο, ποτέ τα δεδομένα σας. Πόροι σε άλλους χώρους εργασίας επιστρέφουν 404, όχι 403.
| Κωδικός | HTTP | Πότε |
|---|---|---|
| unauthorized | 401 | Κλειδί που λείπει, είναι λανθασμένο, άγνωστο, έχει ανακληθεί ή έχει λήξει |
| disabled | 503 | Το API δεν έχει ενεργοποιηθεί ακόμη για αυτή την εγκατάσταση |
| invalid_request | 400 | Αποτυχία επικύρωσης, αποκλεισμένος προορισμός, κατάληξη που χρησιμοποιείται ήδη, άγνωστο domain |
| 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 που επιστρέφουμε δεν το περιέχει: το προσθέτετε εσείς ως fragment #k=, που τα προγράμματα περιήγησης δεν στέλνουν ποτέ. Αν χάσετε το κλειδί, κανείς δεν μπορεί να ανακτήσει το μυστικό, ούτε εμείς. Τα συνημμένα αρχεία κρυπτογραφούνται με τον ίδιο τρόπο, με κλειδί που παράγεται από τον ίδιο σύνδεσμο.
- Μπορώ να δημιουργήσω συνδέσμους χωρίς κλειδί API;
- Ναι. Τα POST /public/links και POST /public/secrets δέχονται ένα αδιαφανές client_id αντί για κλειδί και δημιουργούν εγγραφές στην ίδια ανώνυμη δεξαμενή με τα δωρεάν εργαλεία web: 20 δημιουργίες ανά πελάτη την ημέρα, 60 ανά δίκτυο την ώρα, χωρίς δικό σας domain, χωρίς φράση πρόσβασης, και τα μυστικά λήγουν μέσα σε 24 ώρες.
- Τι γίνεται όταν φτάσω ένα όριο;
- Τα όρια πακέτου επιστρέφουν HTTP 402 με κωδικό plan_limit ή pro_required και ένα upgrade_url. Τα όρια αιτημάτων επιστρέφουν 429 με κεφαλίδα Retry-After. Κάθε απάντηση σε αίτημα με έλεγχο ταυτότητας περιέχει X-RateLimit-Limit, X-RateLimit-Remaining και X-RateLimit-Reset, ώστε οι πελάτες να επιβραδύνουν πριν συμβεί αυτό.
- Είναι σταθερό το API;
- Οι διαδρομές της v1 δεν θα αλλάξουν με τρόπο που σπάει τη συμβατότητα. Τέτοιες αλλαγές θα κυκλοφορούν ως νέα έκδοση. Κατά την πρόωρη πρόσβαση τα endpoint ενεργοποιούνται σταδιακά, χώρο εργασίας προς χώρο εργασίας. Απάντηση 503 με κωδικό disabled σημαίνει ότι το API δεν έχει ενεργοποιηθεί ακόμη για τον χώρο εργασίας σας.
Έτοιμοι να ξεκινήσετε;
Δημιουργήστε ένα κλειδί στον χώρο εργασίας σας ή ξεκινήστε με το πακέτο Free.