{"openapi":"3.1.0","info":{"title":"TintSense License API","version":"1.0.0","description":"Cloudflare Workers API for TintSense license activation, validation, Polar billing, and legacy LemonSqueezy webhook synchronization."},"servers":[{"url":"/"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"EntitlementSnapshot":{"type":"object","properties":{"tier":{"type":"string","enum":["free","pro"]},"status":{"type":"string","enum":["active","expired","revoked","inactive"]},"features":{"type":"object","additionalProperties":{"type":"boolean"}},"expiresAt":{"type":["string","null"],"format":"date-time"},"graceUntil":{"type":["string","null"],"format":"date-time"},"lastValidatedAt":{"type":"string","format":"date-time"},"licenseKeyHint":{"type":["string","null"]}},"required":["tier","status","features","expiresAt","graceUntil","lastValidatedAt","licenseKeyHint"]}}},"paths":{"/health":{"get":{"summary":"Health check","responses":{"200":{"description":"Worker and database are reachable","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"result":{"type":"object","properties":{"status":{"type":"string"},"service":{"type":"string"},"time":{"type":"string","format":"date-time"},"database":{"type":"string"},"licenseCount":{"type":"integer"}},"required":["status","service","time","database","licenseCount"]}},"required":["success","result"],"example":{"success":true,"result":{"status":"ok","service":"tintsense-license-api","time":"2026-03-14T00:00:00.000Z","database":"ok","licenseCount":12}}}}}}}}},"/v1/licenses/activate":{"post":{"summary":"Activate a TintSense license key","description":"Activates a license key for a device, registers the device if allowed, and returns a persistent session token that can be revoked from account device settings plus entitlement snapshot.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["activationKey","deviceFingerprint"],"properties":{"activationKey":{"type":"string","example":"ABCD-EFGH-IJKL-MNOP"},"deviceFingerprint":{"type":"string","example":"figma-macos-device-fingerprint"},"deviceLabel":{"type":"string","example":"Figma Desktop"},"pluginVersion":{"type":"string","example":"1.0.0"},"platform":{"type":"string","example":"macOS"}}}}}},"responses":{"200":{"description":"Activation succeeded","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"result":{"type":"object","properties":{"token":{"type":"string"},"snapshot":{"$ref":"#/components/schemas/EntitlementSnapshot"}},"required":["token","snapshot"]}},"required":["success","result"],"example":{"success":true,"result":{"token":"eyJhbGciOiJI...","snapshot":{"tier":"pro","status":"active","features":{"colorSampling":true,"freeWorkspace":true,"batchExport":true,"advancedPalettes":true,"teamPresetSync":true,"pro":true},"expiresAt":"2027-03-14T00:00:00.000Z","graceUntil":"2026-03-17T00:00:00.000Z","lastValidatedAt":"2026-03-14T00:00:00.000Z","licenseKeyHint":"TS-****-2026"}}}}}}},"401":{"description":"Key is invalid","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"snapshot":{"$ref":"#/components/schemas/EntitlementSnapshot"}},"required":["success","error"],"example":{"success":false,"error":{"code":"activation_failed","message":"Activation key is invalid"},"snapshot":{"tier":"free","status":"inactive","features":{"colorSampling":true,"freeWorkspace":true,"pro":false},"expiresAt":null,"graceUntil":null,"lastValidatedAt":"2026-03-14T00:00:00.000Z","licenseKeyHint":null}}}}}},"403":{"description":"License is not active","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"snapshot":{"$ref":"#/components/schemas/EntitlementSnapshot"}},"required":["success","error"]}}}},"409":{"description":"Device limit reached","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"snapshot":{"$ref":"#/components/schemas/EntitlementSnapshot"}},"required":["success","error"]}}}}}}},"/v1/licenses/validate":{"post":{"summary":"Validate a session token and refresh entitlement snapshot","description":"Accepts a bearer token or JSON token field, re-checks the license in D1, and returns a refreshed token plus the current entitlement snapshot.","security":[{"bearerAuth":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string","example":"eyJhbGciOiJI..."},"deviceFingerprint":{"type":"string","example":"figma-macos-device-fingerprint"},"deviceLabel":{"type":"string","example":"Figma Desktop"},"pluginVersion":{"type":"string","example":"1.0.1"},"platform":{"type":"string","example":"macOS"}}}}}},"responses":{"200":{"description":"Validation succeeded","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"result":{"type":"object","properties":{"token":{"type":"string"},"snapshot":{"$ref":"#/components/schemas/EntitlementSnapshot"}},"required":["token","snapshot"]}},"required":["success","result"],"example":{"success":true,"result":{"token":"eyJhbGciOiJI...","snapshot":{"tier":"pro","status":"active","features":{"colorSampling":true,"freeWorkspace":true,"batchExport":true,"advancedPalettes":true,"teamPresetSync":true,"pro":true},"expiresAt":"2027-03-14T00:00:00.000Z","graceUntil":"2026-03-17T00:00:00.000Z","lastValidatedAt":"2026-03-14T00:00:10.000Z","licenseKeyHint":"TS-****-2026"}}}}}}},"401":{"description":"Token is invalid or missing","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},"snapshot":{"$ref":"#/components/schemas/EntitlementSnapshot"}},"required":["success","error"]}}}}}}},"/webhooks/billing/{provider}":{"post":{"summary":"Receive billing webhooks","description":"Currently supports LemonSqueezy via `{provider} = lemonsqueezy`. The endpoint expects the raw webhook body and a valid `X-Signature` header.","parameters":[{"name":"provider","in":"path","required":true,"schema":{"type":"string","enum":["lemonsqueezy"]}},{"name":"X-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"HMAC SHA-256 signature generated by LemonSqueezy."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"meta":{"event_name":"license_key_created"},"data":{"id":"lk_123","type":"license-keys","attributes":{"key":"TS-PRO-XXXX-XXXX","order_id":200,"subscription_id":"sub_123","status":"active"}}}}}},"responses":{"202":{"description":"Webhook accepted","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"result":{"type":"object","properties":{"accepted":{"type":"boolean"},"duplicate":{"type":"boolean"},"eventId":{"type":"string"},"licenseId":{"type":["string","null"]},"ignored":{"type":"boolean"},"reason":{"type":["string","null"]}},"required":["accepted","duplicate","eventId","licenseId","ignored","reason"]}},"required":["success","result"],"example":{"success":true,"result":{"accepted":true,"duplicate":false,"eventId":"evt_db_123","licenseId":"11111111-1111-4111-8111-111111111111","ignored":false,"reason":null}}}}}},"400":{"description":"Unsupported provider","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["success","error"]}}}},"401":{"description":"Signature check failed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["success","error"],"example":{"success":false,"error":{"code":"invalid_webhook_signature","message":"Webhook signature check failed"}}}}}}}}}}}