Developer docs
Licensing & SDK
Sell your software, we handle the keys. After a webhook-confirmed payment we issue a license key; your software validates it against our API on launch. Keys are machine-bound and tied to the buyer's subscription — access ends automatically on cancellation, expiry, or refund.
How it works
- 1Customer buys your app — Stripe processes the payment.
- 2Our webhook confirms it and issues a unique license key instantly.
- 3Customer pastes the key into your software (or we provision web/TradingView/Discord access).
- 4Your software calls POST /api/licenses/validate on launch; bind to machine on first use.
- 5We keep the key valid while the subscription is active — and revoke it when it isn't.
Validate a key — drop-in snippets
Five lines in your stack. Replace YOUR_APP_ID with the ID from your developer dashboard.
JavaScript / TypeScript
// JavaScript / TypeScript / Node
async function validateLicense(licenseKey, machineId) {
const res = await fetch("https://www.tradingapps.ai/api/licenses/validate", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ licenseKey, machineId, appId: "YOUR_APP_ID" }),
});
const data = await res.json();
return data.valid === true; // also: license_status, expires_at, subscription_status
}Python
# Python (requests)
import requests
def validate_license(license_key: str, machine_id: str) -> bool:
r = requests.post(
"https://www.tradingapps.ai/api/licenses/validate",
json={"licenseKey": license_key, "machineId": machine_id, "appId": "YOUR_APP_ID"},
timeout=10,
)
data = r.json()
return data.get("valid") is TrueNinjaTrader / C#
// NinjaTrader / C# (System.Net.Http)
using System.Net.Http;
using System.Text;
async Task<bool> ValidateLicense(string licenseKey, string machineId)
{
using var http = new HttpClient();
var body = $"{{\"licenseKey\":\"{licenseKey}\",\"machineId\":\"{machineId}\",\"appId\":\"YOUR_APP_ID\"}}";
var res = await http.PostAsync(
"https://www.tradingapps.ai/api/licenses/validate",
new StringContent(body, Encoding.UTF8, "application/json"));
var json = await res.Content.ReadAsStringAsync();
return json.Contains("\"valid\":true");
}TradeStation EasyLanguage
{ TradeStation EasyLanguage — validate on first bar }
{ Requires "Allow sending of email / web access" enabled.
Use a small companion DLL or the built-in web component to POST:
https://www.tradingapps.ai/api/licenses/validate
body: {"licenseKey":"...","machineId":"...","appId":"YOUR_APP_ID"}
Gate your strategy/indicator logic on valid = true. }cURL
curl -X POST https://www.tradingapps.ai/api/licenses/validate \
-H "Content-Type: application/json" \
-d '{"licenseKey":"TA-XXXX-XXXX-XXXX","machineId":"abc123","appId":"YOUR_APP_ID"}'Validation response
Returns the minimum needed to gate access — no unnecessary customer data. Gate your logic on valid === true.
200 OK
{
"valid": true,
"app_id": "app_...",
"customer_id": "usr_...",
"license_status": "active", // active | trialing | past_due | expired | refunded | disputed | suspended
"subscription_status": "active",
"expires_at": "2026-07-14T00:00:00Z"
}