डॉक्स

SublimeKeys को अपने ऐप में जोड़ने के लिए ज़रूरी सब कुछ। पढ़ने के लिए अकाउंट की ज़रूरत नहीं।

$SUBLIMEKEYS_API_KEY

नीचे हर रिक्वेस्ट इसे आपकी असली की के लिए प्लेसहोल्डर के रूप में इस्तेमाल करती है। साइन इन करें (मुफ़्त, बिना कार्ड) करें ताकि अपनी की पाएं और इन उदाहरणों को अपने ही प्रोडक्ट से भरा हुआ देखें।

क्विकस्टार्ट — 3 कॉल्स

1. अपना प्रोडक्ट रजिस्टर करें (एक बार, Products में किया जाता है)

curl -X POST https://api.sublimearts.io/v1/products \
  -H "Authorization: Bearer $SUBLIMEKEYS_API_KEY" \
  -d '{"slug":"my-app","key_prefix":"MYAPP"}'

2. हर बिक्री पर एक की जारी करें

curl -X POST https://api.sublimearts.io/v1/licenses \
  -H "Authorization: Bearer $SUBLIMEKEYS_API_KEY" \
  -d '{"product":"my-app","email":"buyer@mail.com","max_activations":3}'

→ {"key":"MYAPP-K3F7Q-9WZ2M-P8RT4-XN5CB", ...}
productअनिवार्य — स्टेप 1 से प्रोडक्ट slug
emailवैकल्पिक — आपके डैशबोर्ड की लाइसेंस लिस्ट में दिखता है
max_activationsवैकल्पिक, डिफ़ॉल्ट रूप से 1 — यह एक की एक साथ कितने अलग-अलग machine_id पर एक्टिव हो सकती है। इसे उसी हिसाब से सेट करें जो आपकी खुद की प्राइसिंग वादा करती है (जैसे "व्यक्तिगत उपयोग, 3 डिवाइस" टियर के लिए 3)। यह आपके अंतिम ग्राहक के नहीं, बल्कि आपके SublimeKeys प्लान से सीमित होता है — Free पर 5, Pro पर 25, Business पर 100 (मूल्य देखें)।
expires_atवैकल्पिक — ISO तारीख; लाइफटाइम की के लिए छोड़ दें
notesवैकल्पिक — फ्री टेक्स्ट, केवल आपके अपने संदर्भ के लिए

या इस कॉल को पूरी तरह छोड़ दें — नीचे AUTOMATE देखें।

3. अपने ऐप के भीतर वेरिफ़ाई करें

Python — आधिकारिक SDK (अनुशंसित)
# pip install sublimekeys
from sublimekeys import SublimeKeysClient

client = SublimeKeysClient(product_id="my-app")
result = client.activate(license_key=key)   # first run
result = client.verify(license_key=key)     # every launch after — offline-first,
                                             # verifies a signed lease locally,
                                             # zero network calls for up to 7 days
if result.valid:
    unlock_full_version()
Node.js / Electron — आधिकारिक SDK (अनुशंसित)
// npm install sublimekeys
import { SublimeKeysClient } from "sublimekeys";

const client = new SublimeKeysClient("my-app");
const activated = await client.activate(key);     // first run
const result = await client.verify(key);          // every launch after — offline-first,
                                                   // verifies a signed lease locally,
                                                   // zero network calls for up to 7 days
if (result.valid) unlockFullVersion();

Python या Node.js पर नहीं हैं, या खुद raw API कॉल करना चाहते हैं? PyPI पर Python SDK · npm पर Node.js SDK या नीचे दिए गए एंडपॉइंट्स सीधे इस्तेमाल करें।

Python — raw API
import requests

r = requests.post("https://api.sublimearts.io/activate", json={
    "license_key": key,
    "machine_id": machine_id,
    "product_id": "my-app",
})
if r.json()["valid"]:
    unlock_full_version()
Node.js — raw API
const r = await fetch("https://api.sublimearts.io/activate", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ license_key, machine_id, product_id: "my-app" }),
});
const { valid } = await r.json();
if (valid) unlockFullVersion();
cURL
curl -X POST https://api.sublimearts.io/activate \
  -d '{"license_key":"...","machine_id":"...","product_id":"my-app"}'
▸ यह नया लग रहा है? ये कॉल्स असल में आपके ऐप में कहां जाते हैं

ऊपर का उदाहरण सिर्फ /activate अकेले दिखाता है — असली ऐप में आप अलग-अलग पलों पर अलग-अलग एंडपॉइंट कॉल करते हैं:

ऐप शुरू होता है
├─ अभी तक कोई लाइसेंस की सेव नहीं है (पहला रन)
│    → अपनी "लाइसेंस की डालें" स्क्रीन दिखाएं
│    → यूज़र इसे सबमिट करता है → एक बार /activate कॉल करें → नतीजा लोकल रूप से सेव करें
│
├─ एक लाइसेंस की पहले से सेव है (हर बाद का लॉन्च)
│    → इसके बजाय /verify कॉल करें (फिर से /activate नहीं) — पुष्टि करता है कि
│      यह अभी भी इस मशीन पर वैध है
│
├─ API तक पहुंच नहीं (यूज़र ऑफ़लाइन है)
│    → /activate और /verify दोनों एक साइन किया "lease" लौटाते हैं (7 दिन वैध)
│    → आख़िरी नतीजे पर आंख मूंदकर भरोसा करने के बजाय इसके सिग्नेचर को लोकल रूप से
│      वेरिफ़ाई करें — Python और Node.js SDK ऐसा अपने-आप करते हैं; अन्य
│      भाषाएं Ed25519 सिग्नेचर को खुद वेरिफ़ाई कर सकती हैं (पब्लिक की
│      GET /public-key पर)
│
└─ यूज़र अनइंस्टॉल करता है / साइन आउट करता है (वैकल्पिक)
     → /deactivate कॉल करें ताकि सीट दूसरी मशीन के लिए खाली हो जाए

Python या Node.js/Electron पर, आधिकारिक SDK (PyPI · npm) यह पहले से ही संभाल लेते हैं — ऑफ़लाइन lease के असली क्रिप्टोग्राफ़िक वेरिफ़िकेशन सहित। नीचे दिया गया raw वर्ज़न उस हिस्से को छोड़ देता है (यह ऑफ़लाइन रहते हुए बस आख़िरी सेव किए गए नतीजे पर भरोसा करता है) — आसान है, लेकिन क्रिप्टोग्राफ़िक रूप से जांचा नहीं गया। अगर आप Python/Node.js पर नहीं हैं या पूरा नियंत्रण चाहते हैं तो इसे इस्तेमाल करें।

Python — पूरा ऐप-स्टार्ट फ़्लो (raw API, बिना SDK)
import requests, json, os

STATE_FILE = "license_state.json"

def check_license(machine_id):
    saved = json.load(open(STATE_FILE)) if os.path.exists(STATE_FILE) else None

    try:
        if saved is None:
            # first run — ask the user for their key once
            key = prompt_for_license_key()
            r = requests.post("https://api.sublimearts.io/activate", json={
                "license_key": key, "machine_id": machine_id, "product_id": "my-app",
            }, timeout=5)
        else:
            # every later launch — re-check the saved key, don't ask again
            r = requests.post("https://api.sublimearts.io/verify", json={
                "license_key": saved["license_key"], "machine_id": machine_id, "product_id": "my-app",
            }, timeout=5)

        result = r.json()
        json.dump(result, open(STATE_FILE, "w"))
        return result["valid"]

    except requests.RequestException:
        # offline — trust the last known result instead of locking the user out
        return saved["valid"] if saved else False

यह कॉन्सेप्ट पहले से समझ में आ गया? इसे छोड़ दें — ऊपर दिए गए कॉल्स ही आपको चाहिए।

आधिकारिक SDKs

🐍 Python — sublimekeys

पूरी API को रैप करता है और आपके लिए ऑफ़लाइन वेरिफ़िकेशन करता है — साइन किए गए lease के साथ activate/verify/deactivate जो लोकल रूप से जांचा जाता है, इसलिए ज़्यादातर लॉन्च में कोई नेटवर्क कॉल नहीं होती, साथ ही ट्रायल चेक्स जो ऑफ़लाइन अवधि में भी टिके रहते हैं। यह टर्मिनल से इंटीग्रेशन टेस्ट करने के लिए एक sublimekeys CLI भी इंस्टॉल करता है।

pip install sublimekeys
PyPI पर देखें →

⚡ Node.js / Electron — sublimekeys

वही ऑफ़लाइन-सक्षम डिज़ाइन, ज़ीरो रनटाइम डिपेंडेंसीज़ — Ed25519 वेरिफ़िकेशन Node के बिल्ट-इन crypto का इस्तेमाल करता है, इसलिए Electron की asar पैकेजिंग के लिए कुछ भी अटकने वाला नहीं है।

npm install sublimekeys
npm पर देखें →

और भाषाएं रोडमैप में हैं। तब तक, नीचे दिया हर एंडपॉइंट एक सामान्य REST कॉल है — इसे किसी भी ऐसी चीज़ से कॉल करें जो HTTPS रिक्वेस्ट भेज सके।

एंडपॉइंट रेफ़रेंस — पब्लिक (आपके ऐप द्वारा कॉल किया गया)

POST /activate

body: { "license_key", "machine_id", "product_id" }

▸ विवरण

पहला रन — एक लाइसेंस की को एक machine_id से जोड़ता है। उसी मशीन पर दोबारा कॉल करना सुरक्षित है — यह कोई और एक्टिवेशन स्लॉट इस्तेमाल नहीं करेगा। अगर नहीं कर सकता (जैसे किसी दूसरी मशीन पर एक्टिवेशन लिमिट पूरी हो चुकी हो) तो एक मैसेज के साथ valid:false लौटाता है। सफल होने पर, यह रिस्पॉन्स के lease फ़ील्ड में एक साइन किया हुआ lease (7-दिन की ऑफ़लाइन ट्रस्ट विंडो) भी लौटाता है — Python SDK बाद के लॉन्च पर हर बार API कॉल करने के बजाय इसे लोकल रूप से वेरिफ़ाई करता है।

POST /verify

body: { "license_key", "machine_id", "product_id" }

▸ विवरण

हर बाद के लॉन्च पर — पुष्टि करता है कि की इस मशीन पर अभी भी वैध है। यह आपकी एक्टिवेशन गिनती को प्रभावित नहीं करता, तो इसे जितनी बार चाहें कॉल करें। हर सफल कॉल पर साइन किए गए lease (देखें /activate) को भी रीफ़्रेश करता है।

POST /deactivate

body: { "license_key", "machine_id", "product_id" }

▸ विवरण

यूज़र साइन आउट करता है / अनइंस्टॉल करता है — दूसरी मशीन के लिए सीट खाली कर देता है।

POST /trial/start

body: { "machine_id", "product_id" }

▸ विवरण

एक मशीन के लिए 7-दिन का ट्रायल पाता है या बनाता है। Idempotent — दोबारा इंस्टॉल करने से घड़ी कभी रीसेट नहीं होती, सिवाय इसके कि प्रोडक्ट पर Products पेज से ट्रायल-रीसेट आर्म किया गया हो और इस मशीन का ट्रायल शुरू होने के बाद कोई नया वर्शन शिप हुआ हो।

POST /trial/status

body: { "machine_id", "product_id" }

▸ विवरण

सिर्फ़-पढ़ने वाला ट्रायल चेक — कभी एक शुरू नहीं करता।

इन पर कोई Authorization हेडर नहीं है — license_key खुद ही क्रेडेंशियल है। पूरी अकाउंट-स्कोप्ड API (create/list/revoke) /v1/* के अंतर्गत है, डैशबोर्ड देखें।

उन यूज़र्स को वापस पाना चाहते हैं जिनका ट्रायल पहले ही एक्सपायर हो चुका है? नीचे TRIAL RESET ON RELEASE देखें।

⚡ AUTOMATE — बिना बैकएंड के की डिलीवरी

ऊपर स्टेप 2 को पूरी तरह छोड़ दें। अपने पेमेंट प्रोवाइडर के वेबहुक को अपने प्रोडक्ट के URL पर पॉइंट करें और हर बिक्री पर अपने-आप एक की जारी होकर आपके खरीदार को ईमेल हो जाती है।

  1. Stripe Dashboard → Developers → Webhooks → Add endpoint
  2. अपने प्रोडक्ट का URL पेस्ट करें (अपना पाने के लिए साइन इन करें और एक प्रोडक्ट बनाएं)
  3. इवेंट चुनें: checkout.session.completed
  4. सेव करें। बस इतना ही — कोई सर्वर नहीं, कोई कोड नहीं।
  5. वैकल्पिक लेकिन अनुशंसित: Stripe उसके तुरंत बाद एक Signing secret दिखाता है — इसे Products पेज पर "Signature verification" में पेस्ट करें, ताकि हम उस हर चीज़ को अस्वीकार करें जो वाक़ई Stripe से नहीं आई (सिर्फ़ इसलिए नहीं कि किसी के पास यह URL है)।

🔔 हर बिक्री पर खुद भी एक ईमेल चाहते हैं? Products पेज पर इस ब्लॉक के बगल में "Notify me" टॉगल करें।

TRIAL RESET ON RELEASE

आमतौर पर एक्सपायर हो चुका ट्रायल हमेशा के लिए खत्म हो जाता है — रीइंस्टॉल करने से जानबूझकर कभी टाइमर रीसेट नहीं होता। यह एकमात्र जानबूझकर किया गया अपवाद है: एक ऑप्ट-इन, वन-शॉट तरीका जिससे आप कुछ नया शिप करते समय एक्सपायर हो चुकी मशीनों के लिए ट्रायल विंडो दोबारा खोल सकते हैं, बिना उन लोगों को छुए जिनका ट्रायल अभी भी एक्टिव है।

  1. अपने प्रोडक्ट का current_version वह वर्शन सेट करें जिसे आप शिप करने वाले हैं।
  2. इसे आर्म करें: उसी कॉल में PATCH trial_reset_enabled: true भेजें, या पहले अलग से — क्रम मायने नहीं रखता।
  3. जिस पल दोनों शर्तें एक साथ सच होती हैं — वर्शन वाकई बदला है AND आर्म ऑन है — यह ट्रिगर हो जाता है: हर एक्सपायर हो चुकी मशीन को अगले चेक-इन पर एक नया 7-दिन का ट्रायल मिलता है, और आर्म खुद-ब-खुद वापस बंद हो जाता है। जिस अगली रिलीज़ पर इसे लागू करना चाहते हैं, उसके लिए इसे फिर से ऑन करें।

उदाहरण — एक ही कॉल में वर्शन सेट करें और आर्म करें

curl -X PATCH https://api.sublimearts.io/v1/products/my-app \
  -H "Authorization: Bearer $SUBLIMEKEYS_API_KEY" \
  -d '{"current_version":"1.2.0","trial_reset_enabled":true}'

→ {"slug":"my-app","current_version":"1.2.0","trial_reset_enabled":false, ...}

ध्यान दें कि trial_reset_enabled पहले से ही false वापस आता है — यह उसी रिस्पॉन्स में हो रहा ऑटो-डिसआर्म है, कोई बग नहीं। अगर उस कॉल में आपने सिर्फ टॉगल बदला हो बिना current_version बदले, तो यह आर्म्ड (true) ही रहता है, उस वर्शन बदलाव का इंतज़ार करते हुए जो इसे वाकई ट्रिगर करेगा।

UI पसंद करते हैं? Products पेज पर सीधे "इस रिलीज़ पर एक्सपायर हो चुके ट्रायल रीसेट करें" टॉगल करें — हर प्रोडक्ट कार्ड पर RELEASES सेक्शन देखें।

GUMROAD, KEYGEN या अपने सर्वर से माइग्रेट करें

अपने मौजूदा ग्राहकों को एक email कॉलम वाली CSV में एक्सपोर्ट करें, फिर इसे हर प्रोडक्ट के लिए एक बार चलाएं। यह हर पंक्ति के लिए एक नई SublimeKeys लाइसेंस बल्क में जारी करता है, आपके ब्रांड के प्रीफ़िक्स के साथ।

migrate.py
import csv, os, requests

API_KEY = os.environ["SUBLIMEKEYS_API_KEY"]
PRODUCT = "my-app"

with open("customers.csv") as f:
    for row in csv.DictReader(f):
        r = requests.post("https://api.sublimearts.io/v1/licenses",
            headers={"Authorization": f"Bearer {API_KEY}"},
            json={"product": PRODUCT, "email": row["email"]})
        print(row["email"], "->", r.json()["key"])

यह बिल्कुल नई कीज़ जारी करता है — यह आपकी पुरानी की स्ट्रिंग्स को सुरक्षित नहीं रखता (हम डिज़ाइन के अनुसार कस्टम की वैल्यूज़ स्वीकार नहीं करते)। ग्राहकों को उनकी नई की ईमेल करें, या पुराने सिस्टम को हटाने से पहले एक ट्रांज़िशन विंडो के लिए अपने ऐप में दोनों चेक्स साथ-साथ चलाएं।

प्लान लिमिट्स

FREE

1 प्रोडक्ट · 100 कीज़ · 5 डिवाइस/की

PRO

5 प्रोडक्ट्स · 1,000 कीज़ · 25 डिवाइस/की

BUSINESS

असीमित प्रोडक्ट्स और कीज़ · 100 डिवाइस/की

लिमिट तक पहुंचने से मौजूदा कीज़ कभी नहीं टूटतीं — वे हमेशा के लिए वेरिफ़ाई होती रहती हैं। बस आप अपग्रेड करने तक नई जारी नहीं कर सकते। डाउनग्रेड करना या कैंसिल करना भी कभी कुछ डिलीट नहीं करता।