{"openapi":"3.0.3","info":{"title":"Authsy Licensing API","version":"1.0.0","description":"Multi-tenant licensing backend. Tenants (developers) manage products, licenses, payments and user data; their shipped apps call the client API to activate and validate licenses. Client API responses are HMAC-SHA256 signed (canonical JSON, sorted keys) with the tenant signing secret; offline license files and grace tokens are Ed25519-signed with the tenant offline key."},"servers":[{"url":"https://authsy.net"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Tenant dashboard JWT (or manage-scope API key on management routes)."},"apiKeyAuth":{"type":"apiKey","in":"header","name":"X-Api-Key","description":"Tenant API key (lsk_...). client scope for the client API, manage scope for management."}}},"paths":{"/api/v1/plans":{"get":{"summary":"List plans (public)","responses":{"200":{"description":"OK"}}}},"/api/v1/openapi.json":{"get":{"summary":"This spec (public)","responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/register":{"post":{"summary":"Create a tenant account","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"org_name":{"type":"string"},"email":{"type":"string"},"password":{"type":"string","description":"min 10 chars"}},"required":["org_name","email","password"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/login":{"post":{"summary":"Sign in (owner or team member)","description":"When 2FA is enabled returns { requires_2fa, twofa_token } instead of a session token.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string"},"password":{"type":"string"}},"required":["email","password"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/auth/providers":{"get":{"summary":"List enabled social-login providers (public)","description":"Which OAuth providers (google, github) are configured for \"Continue with…\" sign-in.","responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/oauth/{provider}/start":{"get":{"summary":"Begin social login (public)","description":"Redirects to the provider consent screen; provider is google or github.","parameters":[{"name":"provider","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/oauth/{provider}/callback":{"get":{"summary":"Social login callback (public)","description":"Exchanges the code, finds/creates a tenant by verified email, and returns to /app#tk=<session token>.","parameters":[{"name":"provider","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/login/2fa":{"post":{"summary":"Complete a 2FA sign-in","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"twofa_token":{"type":"string"},"code":{"type":"string","description":"6-digit TOTP"}},"required":["twofa_token","code"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/me":{"get":{"summary":"Profile, plan, usage, signing/offline keys","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/rotate-signing-secret":{"post":{"summary":"Rotate the response signing secret","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/verify-email":{"post":{"summary":"Verify email with the emailed token","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string"}},"required":["token"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/resend-verification":{"post":{"summary":"Resend the verification email","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/password-reset/request":{"post":{"summary":"Request a password reset email","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string"}},"required":["email"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/password-reset/confirm":{"post":{"summary":"Set a new password with the emailed token","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string"},"password":{"type":"string"}},"required":["token","password"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/2fa/setup":{"post":{"summary":"Generate a TOTP secret (returns otpauth URL)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/2fa/enable":{"post":{"summary":"Enable 2FA by confirming a code","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"}},"required":["code"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/2fa/disable":{"post":{"summary":"Disable 2FA","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"}},"required":["code"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/upgrade":{"post":{"summary":"Buy/extend a paid plan (owner only; enterprise is contact-only)","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"plan_code":{"type":"string"},"provider":{"type":"string","description":"stripe | plisio"}},"required":["plan_code","provider"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/topup":{"post":{"summary":"Pay-as-you-go: buy user packs for this period (owner only)","description":"One pack = +1,000 monthly active users for the current billing period.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"packs":{"type":"integer","description":"1-1000"},"provider":{"type":"string","description":"stripe | plisio"}},"required":["packs","provider"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/plan-orders":{"get":{"summary":"Plan + top-up purchase history (owner only)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/commission":{"get":{"summary":"Ad-gate commission owed (owner only)","description":"This month + outstanding unbilled commission on verified ad-gate unlocks.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/commission/settle":{"post":{"summary":"Pay outstanding ad-gate commission (owner only)","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"provider":{"type":"string","description":"stripe | plisio"}},"required":["provider"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/adgates":{"get":{"summary":"List ad gates (with monthly unlocks + commission)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK"}}},"post":{"summary":"Create an ad gate (postback secret shown once)","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"product_id":{"type":"string"},"name":{"type":"string"},"unlock_hours":{"type":"integer","description":"e.g. 24 / 48"},"reward_value_usd":{"type":"number","description":"your eCPM per completed ad"},"max_unlocks_per_day":{"type":"integer"},"cooldown_min":{"type":"integer"}},"required":["product_id","name","unlock_hours","reward_value_usd"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/adgates/{id}":{"patch":{"summary":"Update / enable / disable an ad gate","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}},"delete":{"summary":"Delete an ad gate","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/adgate/postback/{gateId}":{"post":{"summary":"Ad network reward postback (public, signed)","description":"Server-to-server: X-Signature = hex HMAC-SHA256 of the raw body with the gate secret. Body { txn_id, machine_id }. Idempotent; issues an HWID-bound time-limited unlock and meters commission.","parameters":[{"name":"gateId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/client/adgate/status":{"post":{"summary":"App-side: is this device unlocked? returns key + expiry","security":[{"apiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"gate_id":{"type":"string"},"machine_id":{"type":"string"}},"required":["gate_id","machine_id"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/ks/plans":{"get":{"summary":"Key System plans (public)","description":"Free (500 keys/mo), Pro (3,000), Enterprise (unlimited, priced — purchasable unlike the licensing enterprise tier).","responses":{"200":{"description":"OK"}}}},"/api/v1/ks/activate":{"post":{"summary":"Activate the Key System on the free plan (owner only)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK"}}}},"/api/v1/ks/upgrade":{"post":{"summary":"Buy/extend a paid Key System plan (owner only)","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"plan_code":{"type":"string","description":"pro | enterprise"},"provider":{"type":"string","description":"stripe | plisio"}},"required":["plan_code","provider"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/ks/stats":{"get":{"summary":"Key System stats (enrolled): keys this month vs cap, active keys, session completions + blocked bypass attempts, sponsored ad views + revenue, 30-day series","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK"}}}},"/api/v1/ks/configs":{"get":{"summary":"List configured checkpoint gates (enrolled)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK"}}}},"/api/v1/ks/config/{productId}":{"put":{"summary":"Create/update a product checkpoint gate (enrolled)","description":"checkpoints: ordered [{ label, url }] ad links; key_hours: issued key lifetime; min_seconds: per-step dwell (anti-bypass); hwid_lock: bind key to device. authsy_ad_enabled / authsy_ad_slots (0-3) control Authsy sponsored steps — the free plan always carries at least one sponsor.","security":[{"bearerAuth":[]}],"parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"checkpoints":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"url":{"type":"string","description":"http(s) ad link"}},"required":["url"]}},"key_hours":{"type":"integer"},"min_seconds":{"type":"integer"},"hwid_lock":{"type":"boolean"},"authsy_ad_enabled":{"type":"boolean"},"authsy_ad_slots":{"type":"integer","description":"0-3 sponsored steps"}},"required":["checkpoints","key_hours"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/ks/keys":{"get":{"summary":"List issued keys (enrolled)","security":[{"bearerAuth":[]}],"parameters":[{"name":"product_id","in":"query","schema":{"type":"string"}},{"name":"active","in":"query","schema":{"type":"string","enum":["1"]}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/ks/keys/{id}/revoke":{"post":{"summary":"Revoke an issued key (enrolled)","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/ks/session/start":{"post":{"summary":"Start a gateway session (public)","description":"Called by the hosted gate page. Sets a signed, browser-bound session cookie and returns the first checkpoint. machine_id is the HWID the issued key will be locked to.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"product_id":{"type":"string"},"machine_id":{"type":"string"}},"required":["product_id","machine_id"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/ks/checkpoint/{productId}":{"get":{"summary":"Checkpoint return endpoint (public)","description":"Your ad links redirect here. Verifies the session and advances a step; anti-bypass (browser binding, per-step dwell, bypass-domain referer blocklist, session expiry) is enforced here. On the final step it issues the key. Redirects back to /gate/{productId} with ?done=1 or ?err=<reason>.","parameters":[{"name":"productId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/ks/session/status":{"get":{"summary":"Gateway session status (public, cookie-based)","description":"The gate page polls this: returns { state: none | open | flagged | done }, the next checkpoint (with `sponsored` + `view_seconds` when it is an Authsy sponsored step), or the issued key.","responses":{"200":{"description":"OK"}}}},"/api/v1/apay/enable":{"post":{"summary":"Enable Authsy Pay for this tenant (owner)","description":"Take payments through Authsy; we charge 2.9% + $0.30 per successful charge and pay out the net.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK"}}}},"/api/v1/apay/account":{"get":{"summary":"Pay account + fee schedule + live balance (enabled)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK"}}}},"/api/v1/apay/charges":{"get":{"summary":"List transactions (enabled)","security":[{"bearerAuth":[]}],"parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["pending","succeeded","failed","refunded"]}}],"responses":{"200":{"description":"OK"}}},"post":{"summary":"Create a charge; returns a hosted checkout_url (enabled)","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"amount":{"type":"number","description":"USD, min 0.50"},"description":{"type":"string"},"customer_email":{"type":"string"}},"required":["amount"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/apay/charges/{id}/refund":{"post":{"summary":"Refund a succeeded charge (enabled; processing fee retained)","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/apay/links":{"get":{"summary":"List payment links (enabled)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK"}}},"post":{"summary":"Create a reusable payment link (enabled)","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"amount":{"type":"number","description":"USD; omit for customer-chosen"},"description":{"type":"string"}}}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/apay/links/{id}/disable":{"post":{"summary":"Disable a payment link (enabled)","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/apay/payouts":{"get":{"summary":"List payouts (enabled)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK"}}},"post":{"summary":"Request a payout from the available balance (owner)","description":"method standard (free) or instant (1% fee).","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"amount":{"type":"number"},"method":{"type":"string","description":"standard | instant"}},"required":["amount"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/apay/public/charge/{id}":{"get":{"summary":"Hosted checkout data for a charge (public)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/apay/public/charge/{id}/pay":{"post":{"summary":"Pay a charge (public, sandbox test cards)","description":"4242… succeeds; 4000 0000 0000 0002 declines. Applies the Authsy fee and credits the merchant the net. Used when the processor is the built-in sandbox.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"card_number":{"type":"string"},"customer_email":{"type":"string"}},"required":["card_number"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/apay/public/charge/{id}/apilion/init":{"post":{"summary":"Start an Aktifbank Apilion checkout for a charge (public)","description":"Used when Apilion is the active processor; returns checkout_url to redirect the buyer to.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"customer_email":{"type":"string"},"customer_name":{"type":"string"}}}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/apay/public/charge/{id}/apilion/confirm":{"post":{"summary":"Confirm an Apilion charge with the bank (public)","description":"Re-checks the payment server-to-server and credits it if genuinely settled. Safe to call repeatedly; used when the buyer returns from the payment page.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/apay/apilion/callback/{chargeId}":{"post":{"summary":"Apilion payment callback (public)","description":"Apilion does not sign this callback, so the body is used only to identify the charge. The payment is then confirmed against Aktifbank over an authenticated channel before anything is credited.","parameters":[{"name":"chargeId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/apay/public/link/{id}":{"get":{"summary":"Payment link info (public)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/apay/public/link/{id}/charge":{"post":{"summary":"Mint a charge from a payment link (public)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"amount":{"type":"number","description":"required only for customer-chosen links"},"customer_email":{"type":"string"}}}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/operator/pay/payouts/{id}/settle":{"post":{"summary":"Operator: mark a payout paid","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/analytics":{"get":{"summary":"Daily activations / licenses / trials / revenue series","security":[{"bearerAuth":[]}],"parameters":[{"name":"days","in":"query","schema":{"type":"integer","default":30}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/api-keys":{"get":{"summary":"List API keys","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK"}}},"post":{"summary":"Create an API key (full key shown once)","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string"},"scope":{"type":"string","description":"client | manage"}}}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/api-keys/{id}":{"delete":{"summary":"Revoke an API key","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/members":{"get":{"summary":"List team members","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK"}}},"post":{"summary":"Invite a member (owner only)","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string"},"role":{"type":"string","description":"admin | viewer"}},"required":["email"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/members/accept":{"post":{"summary":"Accept an invite and set a password","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string"},"password":{"type":"string"}},"required":["token","password"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/members/{id}":{"delete":{"summary":"Remove a member (owner only)","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/webhooks":{"get":{"summary":"List outbound webhooks","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK"}}},"post":{"summary":"Add a webhook (secret shown once; X-Licensing-Signature = HMAC-SHA256 of body)","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"},"events":{"type":"string","description":"'*' or comma-separated event types"}},"required":["url"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/webhooks/{id}":{"delete":{"summary":"Delete a webhook","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/tenant/webhooks/{id}/deliveries":{"get":{"summary":"Recent delivery attempts","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/products":{"get":{"summary":"List products","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK"}}},"post":{"summary":"Create a product","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"platform":{"type":"string","description":"desktop|mobile|web|multi"},"key_prefix":{"type":"string"},"max_activations_default":{"type":"integer"},"heartbeat_window_min":{"type":"integer"},"trial_days_default":{"type":"integer"}},"required":["name"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/products/{id}":{"get":{"summary":"Get a product","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}},"patch":{"summary":"Update a product","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}},"delete":{"summary":"Archive a product","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/products/{id}/data":{"get":{"summary":"List data collections","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/products/{id}/data/{collection}":{"get":{"summary":"List records in a collection","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"collection","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/products/{id}/data/{collection}/{key}":{"get":{"summary":"Get a record","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"collection","in":"path","required":true,"schema":{"type":"string"}},{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}},"put":{"summary":"Upsert a record (JSON <= 16 KB)","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"collection","in":"path","required":true,"schema":{"type":"string"}},{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"responses":{"200":{"description":"OK"}}},"delete":{"summary":"Delete a record","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"collection","in":"path","required":true,"schema":{"type":"string"}},{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/licenses":{"get":{"summary":"List licenses (filters: product_id, status, search, page, limit)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK"}}},"post":{"summary":"Generate licenses (bulk up to 500)","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"product_id":{"type":"string"},"type":{"type":"string","description":"perpetual|subscription|trial|floating"},"count":{"type":"integer"},"max_activations":{"type":"integer"},"expires_in_days":{"type":"integer"},"expires_at":{"type":"string","description":"ISO 8601"},"customer_email":{"type":"string"},"metadata":{},"entitlements":{"type":"object","properties":{}}},"required":["product_id"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/licenses/{key}":{"get":{"summary":"License detail + activations","security":[{"bearerAuth":[]}],"parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}},"patch":{"summary":"Suspend/resume/revoke, change expiry/seats/metadata/entitlements","security":[{"bearerAuth":[]}],"parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"action":{"type":"string","description":"suspend|resume|revoke"},"expires_at":{"type":"string"},"max_activations":{"type":"integer"},"metadata":{},"entitlements":{"type":"object","properties":{}}}}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/licenses/{key}/reset-activations":{"post":{"summary":"Deactivate every device","security":[{"bearerAuth":[]}],"parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/licenses/{key}/offline-file":{"get":{"summary":"Ed25519-signed offline license file","security":[{"bearerAuth":[]}],"parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/licenses/{key}/data":{"get":{"summary":"Per-license user data records","security":[{"bearerAuth":[]}],"parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/licenses/{key}/data/{recordKey}":{"put":{"summary":"Upsert a per-license record","security":[{"bearerAuth":[]}],"parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string"}},{"name":"recordKey","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"responses":{"200":{"description":"OK"}}},"delete":{"summary":"Delete a per-license record","security":[{"bearerAuth":[]}],"parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string"}},{"name":"recordKey","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/events":{"get":{"summary":"Audit event trail","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK"}}}},"/api/v1/payments/connections":{"get":{"summary":"List payment connections","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK"}}},"post":{"summary":"Connect stripe / plisio / custom","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"provider":{"type":"string","description":"stripe|plisio|custom"},"label":{"type":"string"},"secret_key":{"type":"string"},"webhook_secret":{"type":"string"}},"required":["provider"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/payments/connections/{id}":{"delete":{"summary":"Remove a connection","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/payments/offers":{"get":{"summary":"List offers","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK"}}},"post":{"summary":"Create a priced offer","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"product_id":{"type":"string"},"connection_id":{"type":"string"},"name":{"type":"string"},"amount":{"type":"number"},"currency":{"type":"string"},"license_type":{"type":"string"},"max_activations":{"type":"integer"},"expires_in_days":{"type":"integer"},"success_url":{"type":"string"},"cancel_url":{"type":"string"},"entitlements":{"type":"object","properties":{}}},"required":["product_id","connection_id","name","amount"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/payments/offers/{id}":{"patch":{"summary":"Update / enable / disable an offer","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}},"delete":{"summary":"Delete an offer","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/payments":{"get":{"summary":"Payment history","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK"}}}},"/api/v1/pay/webhook/{connectionId}":{"post":{"summary":"Provider webhook (public, signature-verified, idempotent)","parameters":[{"name":"connectionId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/client/activate":{"post":{"summary":"Activate a license on a device","security":[{"apiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"license_key":{"type":"string"},"machine_id":{"type":"string"},"machine_info":{},"nonce":{"type":"string"}},"required":["license_key","machine_id"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/client/validate":{"post":{"summary":"Validate a license (returns entitlements + offline grace token)","security":[{"apiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"license_key":{"type":"string"},"machine_id":{"type":"string"},"nonce":{"type":"string"}},"required":["license_key"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/client/deactivate":{"post":{"summary":"Deactivate this device","security":[{"apiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"license_key":{"type":"string"},"machine_id":{"type":"string"}},"required":["license_key","machine_id"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/client/heartbeat":{"post":{"summary":"Keep a floating seat alive","security":[{"apiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"license_key":{"type":"string"},"machine_id":{"type":"string"}},"required":["license_key","machine_id"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/client/trial":{"post":{"summary":"Self-serve trial (one per product per machine)","security":[{"apiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"product_id":{"type":"string"},"machine_id":{"type":"string"},"email":{"type":"string"}},"required":["product_id","machine_id"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/client/license-file":{"post":{"summary":"Signed offline license file for an activated device","security":[{"apiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"license_key":{"type":"string"},"machine_id":{"type":"string"}},"required":["license_key","machine_id"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/client/checkout":{"post":{"summary":"Create a hosted checkout for an offer","security":[{"apiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"offer_id":{"type":"string"},"customer_email":{"type":"string"},"success_url":{"type":"string"},"cancel_url":{"type":"string"}},"required":["offer_id"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/client/checkout/status":{"post":{"summary":"Poll a purchase for the issued license key","security":[{"apiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"external_id":{"type":"string"}},"required":["external_id"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/client/data/set":{"post":{"summary":"Save per-license user data (JSON <= 16 KB)","security":[{"apiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"license_key":{"type":"string"},"key":{"type":"string"},"data":{}},"required":["license_key","key"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/client/data/get":{"post":{"summary":"Read per-license user data","security":[{"apiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"license_key":{"type":"string"},"key":{"type":"string"}},"required":["license_key","key"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/client/data/list":{"post":{"summary":"List stored keys for a license","security":[{"apiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"license_key":{"type":"string"}},"required":["license_key"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/client/data/delete":{"post":{"summary":"Delete a per-license record","security":[{"apiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"license_key":{"type":"string"},"key":{"type":"string"}},"required":["license_key","key"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/public/offers/{id}":{"get":{"summary":"Offer info for the hosted buy page (public)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/public/checkout":{"post":{"summary":"Start a purchase from a buy link (public)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"offer_id":{"type":"string"},"email":{"type":"string"}},"required":["offer_id","email"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/public/checkout/status":{"post":{"summary":"Poll a buy-link purchase (public)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"offer_id":{"type":"string"},"external_id":{"type":"string"}},"required":["offer_id","external_id"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/public/license":{"post":{"summary":"End-user device portal: look up a license by key (public)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"license_key":{"type":"string"}},"required":["license_key"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/public/license/deactivate":{"post":{"summary":"End-user device portal: free a device slot (public)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"license_key":{"type":"string"},"activation_id":{"type":"string"}},"required":["license_key","activation_id"]}}}},"responses":{"200":{"description":"OK"}}}},"/api/v1/operator/tenants":{"get":{"summary":"Operator: list tenants with usage","description":"Auth: X-Operator-Key header (OPERATOR_API_KEY env).","responses":{"200":{"description":"OK"}}}},"/api/v1/operator/tenants/{id}":{"patch":{"summary":"Operator: change plan / expiry / suspend","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v1/operator/stats":{"get":{"summary":"Operator: totals, plan revenue by month + key-system sponsored ad revenue","responses":{"200":{"description":"OK"}}}}}}