{"openapi":"3.1.0","info":{"title":"MemoryLayer License Server","version":"0.1.0"},"paths":{"/modules/blob/{name}/{version}":{"get":{"tags":["modules"],"summary":"Get Module Blob","description":"Public endpoint — returns the encrypted blob + RS256 signature for a module version.\nNo auth required: blobs are AES-256-GCM ciphertext, useless without the entitlement-\ngated key from POST /modules/key. Clients cache the response locally (ciphertext only).","operationId":"get_module_blob_modules_blob__name___version__get","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","title":"Name"}},{"name":"version","in":"path","required":true,"schema":{"type":"string","title":"Version"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/modules/key":{"post":{"tags":["modules"],"summary":"Get Module Key","operationId":"get_module_key_modules_key_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeyRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/license/lease":{"post":{"tags":["lease"],"summary":"Issue Lease","operationId":"issue_lease_license_lease_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeaseRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/license/lease/reconcile":{"post":{"tags":["lease"],"summary":"Reconcile","operationId":"reconcile_license_lease_reconcile_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReconcileRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/device/start":{"post":{"tags":["device"],"summary":"Device Start","operationId":"device_start_device_start_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/device/poll":{"post":{"tags":["device"],"summary":"Device Poll","operationId":"device_poll_device_poll_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PollRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/device/confirm":{"post":{"tags":["device"],"summary":"Device Confirm","operationId":"device_confirm_device_confirm_post","parameters":[{"name":"x-internal-secret","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Internal-Secret"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/health":{"get":{"summary":"Health","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/license/validate":{"post":{"summary":"Validate","operationId":"validate_license_validate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/license/usage":{"post":{"summary":"Usage","description":"Fire-and-forget ping — always returns 200. Never blocks the caller.","operationId":"usage_license_usage_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/license/key":{"get":{"summary":"Get Key For Email","operationId":"get_key_for_email_license_key_get","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string","title":"Email"}},{"name":"x-internal-secret","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Internal-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/license/usage-logs":{"get":{"summary":"Usage Logs","operationId":"usage_logs_license_usage_logs_get","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string","title":"Email"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"x-internal-secret","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Internal-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/license/account":{"delete":{"summary":"Delete Account","operationId":"delete_account_license_account_delete","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string","title":"Email"}},{"name":"x-internal-secret","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Internal-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/license/rotate":{"post":{"summary":"Rotate","operationId":"rotate_license_rotate_post","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string","title":"Email"}},{"name":"x-internal-secret","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Internal-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/test-email":{"post":{"summary":"Test Email","description":"Send test emails for all lifecycle events. Admin only.","operationId":"test_email_admin_test_email_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/license/issue":{"post":{"summary":"Issue","operationId":"issue_license_issue_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssueRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/subscriptions/pending":{"post":{"summary":"Create Pending Subscription","description":"Pre-registers a subscription's email/tier before Razorpay ever calls\nback. Called server-side by the web app's checkout route immediately\nafter creating a Razorpay subscription, so subscription.activated can\ntrust our own DB row instead of webhook-supplied notes.email for a\nbrand-new subscription_id (closes the spoofing gap noted at the top of\nthe webhook handler below).","operationId":"create_pending_subscription_subscriptions_pending_post","parameters":[{"name":"x-internal-secret","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Internal-Secret"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PendingSubscriptionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/razorpay/webhook":{"post":{"summary":"Razorpay Webhook","operationId":"razorpay_webhook_razorpay_webhook_post","parameters":[{"name":"x-razorpay-signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Razorpay-Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"ConfirmRequest":{"properties":{"user_code":{"type":"string","maxLength":16,"minLength":1,"title":"User Code"},"email":{"type":"string","maxLength":254,"minLength":3,"pattern":"^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$","title":"Email"}},"type":"object","required":["user_code","email"],"title":"ConfirmRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"IssueRequest":{"properties":{"email":{"type":"string","maxLength":254,"minLength":3,"pattern":"^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$","title":"Email"},"tier":{"type":"string","title":"Tier"},"stripe_customer_id":{"type":"string","title":"Stripe Customer Id","default":""},"admin_secret":{"type":"string","title":"Admin Secret"}},"type":"object","required":["email","tier","admin_secret"],"title":"IssueRequest"},"KeyRequest":{"properties":{"module":{"type":"string","title":"Module"},"version":{"type":"string","maxLength":32,"title":"Version"},"machine_id":{"type":"string","maxLength":128,"title":"Machine Id"},"client_version":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"title":"Client Version"}},"type":"object","required":["module","version","machine_id"],"title":"KeyRequest"},"LeaseRequest":{"properties":{"machine_id":{"type":"string","maxLength":128,"title":"Machine Id"},"want":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Want"}},"type":"object","required":["machine_id"],"title":"LeaseRequest"},"PendingSubscriptionRequest":{"properties":{"subscription_id":{"type":"string","maxLength":128,"minLength":1,"title":"Subscription Id"},"email":{"type":"string","maxLength":254,"minLength":3,"pattern":"^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$","title":"Email"},"tier":{"type":"string","pattern":"^(pro|pro_plus|enterprise)$","title":"Tier"}},"type":"object","required":["subscription_id","email","tier"],"title":"PendingSubscriptionRequest"},"PollRequest":{"properties":{"device_code":{"type":"string","maxLength":128,"minLength":1,"title":"Device Code"}},"type":"object","required":["device_code"],"title":"PollRequest"},"ReconcileRequest":{"properties":{"lease_id":{"type":"string","maxLength":64,"minLength":1,"title":"Lease Id"},"used":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Used"}},"type":"object","required":["lease_id","used"],"title":"ReconcileRequest"},"UsageRequest":{"properties":{"key":{"type":"string","title":"Key"},"machine_id":{"type":"string","maxLength":64,"pattern":"^[a-zA-Z0-9_\\-\\.]*$","title":"Machine Id","default":""},"op":{"type":"string","title":"Op"},"ts":{"type":"integer","title":"Ts"}},"type":"object","required":["key","op","ts"],"title":"UsageRequest"},"ValidateRequest":{"properties":{"key":{"type":"string","title":"Key"},"machine_id":{"type":"string","maxLength":64,"pattern":"^[a-zA-Z0-9_\\-\\.]*$","title":"Machine Id","default":""}},"type":"object","required":["key"],"title":"ValidateRequest"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}}}