{
  "components": {
    "schemas": {
      "ActivationInfo": {
        "description": "What was activated. Echoes your request, so you rarely need to read it.",
        "properties": {
          "identifier": {
            "description": "Echo of the identifier that was activated.",
            "title": "Identifier",
            "type": "string"
          },
          "type": {
            "$ref": "#/components/schemas/ActivationType",
            "description": "Echo of the request: seat or domain."
          }
        },
        "required": [
          "type",
          "identifier"
        ],
        "title": "ActivationInfo",
        "type": "object"
      },
      "ActivationListItem": {
        "properties": {
          "activation_id": {
            "format": "uuid",
            "title": "Activation Id",
            "type": "string"
          },
          "activation_type": {
            "$ref": "#/components/schemas/ActivationType"
          },
          "first_seen_at": {
            "format": "date-time",
            "title": "First Seen At",
            "type": "string"
          },
          "identifier": {
            "title": "Identifier",
            "type": "string"
          },
          "label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Label"
          },
          "last_seen_at": {
            "format": "date-time",
            "title": "Last Seen At",
            "type": "string"
          }
        },
        "required": [
          "activation_id",
          "activation_type",
          "identifier",
          "label",
          "first_seen_at",
          "last_seen_at"
        ],
        "title": "ActivationListItem",
        "type": "object"
      },
      "ActivationType": {
        "enum": [
          "seat",
          "domain"
        ],
        "title": "ActivationType",
        "type": "string"
      },
      "CheckoutResponse": {
        "properties": {
          "checkout_url": {
            "title": "Checkout Url",
            "type": "string"
          },
          "test_clock_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The Stripe test clock the buyer is on, when the checkout asked for one.",
            "title": "Test Clock Id"
          }
        },
        "required": [
          "checkout_url"
        ],
        "title": "CheckoutResponse",
        "type": "object"
      },
      "ErrorResponse": {
        "properties": {
          "error": {
            "title": "Error",
            "type": "string"
          },
          "message": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Message"
          }
        },
        "required": [
          "error"
        ],
        "title": "ErrorResponse",
        "type": "object"
      },
      "HTTPValidationError": {
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "title": "Detail",
            "type": "array"
          }
        },
        "title": "HTTPValidationError",
        "type": "object"
      },
      "LicenseActivateRequest": {
        "properties": {
          "activation_type": {
            "$ref": "#/components/schemas/ActivationType",
            "description": "seat to count a device or user, domain to count a website. Must match the activation mode of your product."
          },
          "identifier": {
            "description": "What is being activated: a device or user ID for seat, or the website domain (for example myapp.com) for domain. Use the same value every time from the same machine.",
            "maxLength": 512,
            "minLength": 1,
            "title": "Identifier",
            "type": "string"
          },
          "label": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional friendly name shown to you and the customer, for example the computer name.",
            "title": "Label"
          },
          "license_key": {
            "description": "The license key the customer pasted into your product.",
            "maxLength": 128,
            "minLength": 8,
            "title": "License Key",
            "type": "string"
          },
          "plugin_slug": {
            "description": "The slug of your product, shown in the dashboard under Products.",
            "maxLength": 64,
            "minLength": 1,
            "title": "Plugin Slug",
            "type": "string"
          }
        },
        "required": [
          "license_key",
          "plugin_slug",
          "activation_type",
          "identifier"
        ],
        "title": "LicenseActivateRequest",
        "type": "object"
      },
      "LicenseActivateResponse": {
        "properties": {
          "activation": {
            "$ref": "#/components/schemas/ActivationInfo",
            "description": "What was activated (an echo of your request). Informational only."
          },
          "activation_id": {
            "description": "Save this. You need it to deactivate later, when the customer moves to another device.",
            "format": "uuid",
            "title": "Activation Id",
            "type": "string"
          },
          "feature_flags": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional. Custom settings you defined on the plan.",
            "title": "Feature Flags"
          }
        },
        "required": [
          "activation_id",
          "activation"
        ],
        "title": "LicenseActivateResponse",
        "type": "object"
      },
      "LicenseActivationsResponse": {
        "properties": {
          "activations": {
            "items": {
              "$ref": "#/components/schemas/ActivationListItem"
            },
            "title": "Activations",
            "type": "array"
          },
          "license_id": {
            "format": "uuid",
            "title": "License Id",
            "type": "string"
          }
        },
        "required": [
          "license_id",
          "activations"
        ],
        "title": "LicenseActivationsResponse",
        "type": "object"
      },
      "LicenseDeactivateRequest": {
        "properties": {
          "activation_id": {
            "description": "The activation_id returned when you activated.",
            "format": "uuid",
            "title": "Activation Id",
            "type": "string"
          },
          "license_key": {
            "description": "The license key the customer is removing from this device or website.",
            "maxLength": 128,
            "minLength": 8,
            "title": "License Key",
            "type": "string"
          }
        },
        "required": [
          "license_key",
          "activation_id"
        ],
        "title": "LicenseDeactivateRequest",
        "type": "object"
      },
      "LicenseDeactivateResponse": {
        "properties": {
          "deactivated": {
            "description": "true once the seat or website is freed up.",
            "title": "Deactivated",
            "type": "boolean"
          }
        },
        "required": [
          "deactivated"
        ],
        "title": "LicenseDeactivateResponse",
        "type": "object"
      },
      "LicenseDetails": {
        "description": "Information about the license. Nothing here decides access; it is safe to ignore.",
        "properties": {
          "activation_mode": {
            "anyOf": [
              {
                "enum": [
                  "seat",
                  "domain"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "How this product limits use: seat = a number of devices or users, domain = a number of websites.",
            "title": "Activation Mode"
          },
          "expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the license expires. null means it never expires.",
            "title": "Expires At"
          },
          "max_domains": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Websites allowed. null means unlimited.",
            "title": "Max Domains"
          },
          "max_seats": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Devices or users allowed. null means unlimited.",
            "title": "Max Seats"
          },
          "plan_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "ID of the plan the customer bought.",
            "title": "Plan Id"
          },
          "seats_in_use": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Devices or users currently activated.",
            "title": "Seats In Use"
          }
        },
        "title": "LicenseDetails",
        "type": "object"
      },
      "LicenseStatus": {
        "enum": [
          "active",
          "inactive",
          "expired"
        ],
        "title": "LicenseStatus",
        "type": "string"
      },
      "LicenseTokenDetails": {
        "description": "How to verify and when to refresh an offline token.",
        "properties": {
          "algorithm": {
            "description": "Signing algorithm of the token (EdDSA).",
            "title": "Algorithm",
            "type": "string"
          },
          "expires_at": {
            "description": "When the token stops being accepted. Refresh online before this.",
            "format": "date-time",
            "title": "Expires At",
            "type": "string"
          },
          "issued_at": {
            "description": "When the token was issued.",
            "format": "date-time",
            "title": "Issued At",
            "type": "string"
          },
          "jwks_url": {
            "description": "Where to fetch the public keys that verify the token.",
            "title": "Jwks Url",
            "type": "string"
          },
          "kid": {
            "description": "ID of the signing key. Matches the `kid` in the token header.",
            "title": "Kid",
            "type": "string"
          }
        },
        "required": [
          "algorithm",
          "kid",
          "issued_at",
          "expires_at",
          "jwks_url"
        ],
        "title": "LicenseTokenDetails",
        "type": "object"
      },
      "LicenseTokenResponse": {
        "description": "A signed, offline-verifiable snapshot of a license entitlement.\n\n``token`` is an EdDSA-signed JWT whose claims mirror the validate\nresponse; verify it locally against the plugin's JWKS\n(``details.jwks_url``) using the ``kid`` in the JWT header. Short-lived\nby design: refresh online before ``details.expires_at`` since offline\ntokens carry no revocation.",
        "properties": {
          "details": {
            "$ref": "#/components/schemas/LicenseTokenDetails",
            "description": "How to verify the token and when it expires. Your SDK handles this for you."
          },
          "token": {
            "description": "The signed token. Store it and verify it locally when offline.",
            "title": "Token",
            "type": "string"
          }
        },
        "required": [
          "token",
          "details"
        ],
        "title": "LicenseTokenResponse",
        "type": "object"
      },
      "LicenseValidateRequest": {
        "properties": {
          "license_key": {
            "description": "The license key the customer pasted into your product.",
            "maxLength": 128,
            "minLength": 8,
            "title": "License Key",
            "type": "string"
          },
          "plugin_slug": {
            "description": "The slug of your product, shown in the dashboard under Products. Must match the API key.",
            "maxLength": 64,
            "minLength": 1,
            "title": "Plugin Slug",
            "type": "string"
          }
        },
        "required": [
          "license_key",
          "plugin_slug"
        ],
        "title": "LicenseValidateRequest",
        "type": "object"
      },
      "LicenseValidateResponse": {
        "description": "Result of checking a license key.\n\nThe top level holds what your product acts on. Only ``valid`` decides\nwhether to unlock: ``true`` means unlock, ``false`` means stay locked.\n``license`` holds information about the license (plan, limits, expiry)\nthat you can show the customer but never need for the unlock decision.",
        "properties": {
          "entitlement": {
            "default": "none",
            "description": "Optional. full = valid license, limited = expired but a fallback plan keeps reduced access, none = no access. Ignore it unless you offer reduced access after expiry.",
            "enum": [
              "full",
              "limited",
              "none"
            ],
            "title": "Entitlement",
            "type": "string"
          },
          "feature_flags": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional. Custom settings you defined on the plan, for example {\"max_projects\": 5}. Use them to unlock features per plan.",
            "title": "Feature Flags"
          },
          "license": {
            "$ref": "#/components/schemas/LicenseDetails",
            "description": "Information about the license: plan, device or website limits, and expiry. Informational only; do not use it to decide whether to unlock."
          },
          "status": {
            "$ref": "#/components/schemas/LicenseStatus",
            "description": "Why the license is in this state: active, inactive (revoked or refunded), or expired. Use it to pick the message you show the customer, not to decide access."
          },
          "valid": {
            "description": "The answer you gate on. true = unlock your product. false = keep it locked, for any reason (expired, inactive, unknown key). It is also false while a post-expiry fallback is active; read `entitlement` if you want to offer limited access then.",
            "title": "Valid",
            "type": "boolean"
          }
        },
        "required": [
          "valid",
          "status",
          "license"
        ],
        "title": "LicenseValidateResponse",
        "type": "object"
      },
      "PaymentProvider": {
        "description": "Which payment backend a tenant (Group) sells through.\n\n* ``stripe`` \u2014 Stripe Connect (the default; platform billing always uses it).\n* ``mercadopago`` \u2014 Mercado Pago via bring-your-own-credentials, for LATAM\n  tenants where Stripe has no merchant support. The tenant supplies their\n  own access token; the platform only orchestrates.\n* ``paypal`` \u2014 PayPal via bring-your-own-credentials (REST app client id +\n  secret + webhook id), for buyer trust and the long tail of merchant\n  countries Stripe cannot onboard. The platform only orchestrates.\n* ``razorpay`` \u2014 Razorpay via bring-your-own-credentials, for Indian tenants\n  where Stripe has no general merchant onboarding. The tenant supplies their\n  own API keys (``key_id``/``key_secret``); the platform only orchestrates.",
        "enum": [
          "stripe",
          "mercadopago",
          "paypal",
          "razorpay"
        ],
        "title": "PaymentProvider",
        "type": "string"
      },
      "PluginCheckoutRequest": {
        "description": "Public-API checkout request \u2014 authenticated by plugin API key.\n\nThe plugin runtime POSTs this when its user clicks Buy. We use\n``plan_id`` (our internal UUID) instead of raw ``price_id`` so the\nplugin doesn't need to know about Stripe pricing internals \u2014 and so\nwe can enforce that the plan actually belongs to the calling plugin.\n\n``success_url`` / ``cancel_url`` are optional. When provided, they\nmust be ``https://`` URLs whose origin appears in the plugin's\n``allowed_origins``. Otherwise we fall back to\n``FRONTEND_URL/checkout/{success,cancel}``.",
        "properties": {
          "cancel_url": {
            "anyOf": [
              {
                "format": "uri",
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cancel Url"
          },
          "customer_email": {
            "format": "email",
            "title": "Customer Email",
            "type": "string"
          },
          "plan_id": {
            "format": "uuid",
            "title": "Plan Id",
            "type": "string"
          },
          "success_url": {
            "anyOf": [
              {
                "format": "uri",
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Success Url"
          },
          "test_clock": {
            "default": false,
            "description": "Test keys only. Put the buyer on a new Stripe test clock, which you advance in Stripe.",
            "title": "Test Clock",
            "type": "boolean"
          }
        },
        "required": [
          "plan_id",
          "customer_email"
        ],
        "title": "PluginCheckoutRequest",
        "type": "object"
      },
      "SellerCustomer": {
        "properties": {
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "email": {
            "title": "Email",
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          }
        },
        "required": [
          "id",
          "email",
          "created_at"
        ],
        "title": "SellerCustomer",
        "type": "object"
      },
      "SellerCustomerList": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/SellerCustomer"
            },
            "title": "Items",
            "type": "array"
          }
        },
        "required": [
          "items"
        ],
        "title": "SellerCustomerList",
        "type": "object"
      },
      "SellerLicense": {
        "properties": {
          "customer_email": {
            "title": "Customer Email",
            "type": "string"
          },
          "expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expires At"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "issued_at": {
            "format": "date-time",
            "title": "Issued At",
            "type": "string"
          },
          "key_prefix": {
            "description": "The key's first characters, enough to tell keys apart. Never the key.",
            "title": "Key Prefix",
            "type": "string"
          },
          "max_domains": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Max Domains"
          },
          "max_seats": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Max Seats"
          },
          "plan_id": {
            "format": "uuid",
            "title": "Plan Id",
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/LicenseStatus"
          },
          "subscription_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subscription Id"
          }
        },
        "required": [
          "id",
          "key_prefix",
          "status",
          "plan_id",
          "customer_email",
          "subscription_id",
          "max_seats",
          "max_domains",
          "expires_at",
          "issued_at"
        ],
        "title": "SellerLicense",
        "type": "object"
      },
      "SellerLicenseIssueRequest": {
        "properties": {
          "customer_email": {
            "format": "email",
            "title": "Customer Email",
            "type": "string"
          },
          "expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Must be in the future. Omit for no expiry.",
            "title": "Expires At"
          },
          "max_domains": {
            "anyOf": [
              {
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Defaults to the plan's limit.",
            "title": "Max Domains"
          },
          "max_seats": {
            "anyOf": [
              {
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Defaults to the plan's limit.",
            "title": "Max Seats"
          },
          "plan_id": {
            "format": "uuid",
            "title": "Plan Id",
            "type": "string"
          },
          "send_email": {
            "default": true,
            "description": "Email the key to the customer. Ignored when your server sends license emails.",
            "title": "Send Email",
            "type": "boolean"
          }
        },
        "required": [
          "customer_email",
          "plan_id"
        ],
        "title": "SellerLicenseIssueRequest",
        "type": "object"
      },
      "SellerLicenseIssued": {
        "description": "Returned only at issuance \u2014 ``key`` cannot be retrieved later.",
        "properties": {
          "key": {
            "title": "Key",
            "type": "string"
          },
          "license": {
            "$ref": "#/components/schemas/SellerLicense"
          }
        },
        "required": [
          "license",
          "key"
        ],
        "title": "SellerLicenseIssued",
        "type": "object"
      },
      "SellerLicenseList": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/SellerLicense"
            },
            "title": "Items",
            "type": "array"
          },
          "total": {
            "title": "Total",
            "type": "integer"
          }
        },
        "required": [
          "items",
          "total"
        ],
        "title": "SellerLicenseList",
        "type": "object"
      },
      "SellerSubscription": {
        "properties": {
          "canceled_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Canceled At"
          },
          "current_period_end": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Current Period End"
          },
          "customer_email": {
            "title": "Customer Email",
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "plan_id": {
            "format": "uuid",
            "title": "Plan Id",
            "type": "string"
          },
          "provider": {
            "$ref": "#/components/schemas/PaymentProvider"
          },
          "status": {
            "$ref": "#/components/schemas/SubscriptionStatus"
          }
        },
        "required": [
          "id",
          "status",
          "provider",
          "plan_id",
          "customer_email",
          "current_period_end",
          "canceled_at"
        ],
        "title": "SellerSubscription",
        "type": "object"
      },
      "SellerSubscriptionList": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/SellerSubscription"
            },
            "title": "Items",
            "type": "array"
          },
          "total": {
            "title": "Total",
            "type": "integer"
          }
        },
        "required": [
          "items",
          "total"
        ],
        "title": "SellerSubscriptionList",
        "type": "object"
      },
      "StoreCatalogResponse": {
        "properties": {
          "group": {
            "$ref": "#/components/schemas/StoreGroupBranding"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/StorePluginEntry"
            },
            "title": "Items",
            "type": "array"
          }
        },
        "required": [
          "group",
          "items"
        ],
        "title": "StoreCatalogResponse",
        "type": "object"
      },
      "StoreCheckoutRequest": {
        "description": "Public store checkout request \u2014 no auth, plan_id-based.\n\nUnlike ``PluginCheckoutRequest`` we do **not** accept caller-supplied\nredirect URLs. Buyers always come back to our own\n``FRONTEND_URL/checkout/{success,cancel}`` pages so the surface for\nopen-redirect abuse is zero.",
        "properties": {
          "customer_email": {
            "format": "email",
            "title": "Customer Email",
            "type": "string"
          },
          "plan_id": {
            "format": "uuid",
            "title": "Plan Id",
            "type": "string"
          }
        },
        "required": [
          "plan_id",
          "customer_email"
        ],
        "title": "StoreCheckoutRequest",
        "type": "object"
      },
      "StoreGroupBranding": {
        "description": "Group-level branding surfaced on the public buy page.\n\ncontact_email is intentionally excluded \u2014 it is an internal admin\nfield and must not be sent to unauthenticated buyers.",
        "properties": {
          "accent_color": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Accent Color"
          },
          "buyer_portal_enabled": {
            "default": true,
            "title": "Buyer Portal Enabled",
            "type": "boolean"
          },
          "logo_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Logo Url"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "payment_provider": {
            "default": "stripe",
            "title": "Payment Provider",
            "type": "string"
          },
          "slug": {
            "title": "Slug",
            "type": "string"
          },
          "social_facebook": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Social Facebook"
          },
          "social_instagram": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Social Instagram"
          },
          "social_linkedin": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Social Linkedin"
          },
          "tagline": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tagline"
          }
        },
        "required": [
          "name",
          "slug",
          "tagline",
          "logo_url",
          "accent_color"
        ],
        "title": "StoreGroupBranding",
        "type": "object"
      },
      "StorePlan": {
        "description": "A purchasable plan rendered on the public store page.\n\nDeliberately omits ``stripe_price_id`` \u2014 buyers don't need it, and\nkeeping it server-side narrows the blast radius if we later want to\nrotate prices without re-deploying the frontend.",
        "properties": {
          "billing_interval": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Billing Interval"
          },
          "billing_type": {
            "title": "Billing Type",
            "type": "string"
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "max_domains": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Max Domains"
          },
          "max_seats": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Max Seats"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "trial_duration_days": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Trial Duration Days"
          },
          "unit_amount": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Amount"
          }
        },
        "required": [
          "id",
          "name",
          "billing_type",
          "billing_interval",
          "unit_amount",
          "currency",
          "max_seats",
          "max_domains"
        ],
        "title": "StorePlan",
        "type": "object"
      },
      "StorePluginEntry": {
        "description": "One plugin in the public store catalog, with its active plans.",
        "properties": {
          "activation_mode": {
            "title": "Activation Mode",
            "type": "string"
          },
          "banner_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Banner Url"
          },
          "client_kind": {
            "title": "Client Kind",
            "type": "string"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "plans": {
            "items": {
              "$ref": "#/components/schemas/StorePlan"
            },
            "title": "Plans",
            "type": "array"
          },
          "screenshot_urls": {
            "default": [],
            "items": {
              "type": "string"
            },
            "title": "Screenshot Urls",
            "type": "array"
          },
          "slug": {
            "title": "Slug",
            "type": "string"
          }
        },
        "required": [
          "id",
          "slug",
          "name",
          "description",
          "activation_mode",
          "client_kind",
          "plans"
        ],
        "title": "StorePluginEntry",
        "type": "object"
      },
      "SubscriptionStatus": {
        "enum": [
          "active",
          "trialing",
          "past_due",
          "canceled",
          "unpaid",
          "incomplete"
        ],
        "title": "SubscriptionStatus",
        "type": "string"
      },
      "ValidationError": {
        "properties": {
          "ctx": {
            "title": "Context",
            "type": "object"
          },
          "input": {
            "title": "Input"
          },
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "title": "Location",
            "type": "array"
          },
          "msg": {
            "title": "Message",
            "type": "string"
          },
          "type": {
            "title": "Error Type",
            "type": "string"
          }
        },
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError",
        "type": "object"
      }
    },
    "securitySchemes": {
      "HTTPBearer": {
        "scheme": "bearer",
        "type": "http"
      }
    }
  },
  "info": {
    "description": "The calls your product makes to Licensr. Most integrations only need the three in **Licensing (required)**: activate a key, validate it, and deactivate it. The other sections are optional extras. New here? Start with the quick start guide first. The admin panel and customer portal use a different login and are not part of this API.",
    "title": "Licensr License API",
    "version": "0.1.0"
  },
  "openapi": "3.1.0",
  "paths": {
    "/v1/billing/checkout": {
      "post": {
        "description": "Create a Stripe Checkout session for a plan owned by the calling plugin.\n\nValidates that:\n  - ``plan_id`` exists and belongs to ``ctx.plugin``\n  - any caller-supplied ``success_url`` / ``cancel_url`` points at a\n    host listed in ``plugin.allowed_origins``\n\nStamps ``plan_id`` and ``customer_id`` on the Stripe session metadata\nso the corresponding ``checkout.session.completed`` webhook can issue\nthe license without a slug-lookup round-trip. A test key sells the\nplan's Stripe test price, and the license lands in the test pool.",
        "operationId": "billing_checkout_v1_billing_checkout_post",
        "parameters": [
          {
            "in": "header",
            "name": "Origin",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Origin"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PluginCheckoutRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CheckoutResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Bad Request"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Conflict"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ],
        "summary": "Start a checkout from inside your product",
        "tags": [
          "In-app checkout"
        ]
      }
    },
    "/v1/license/activate": {
      "post": {
        "description": "Register one device, user or website against the license so it counts toward the plan's limit. Call it once when the customer first enters their key, then validate.",
        "operationId": "activate_license_v1_license_activate_post",
        "parameters": [
          {
            "in": "header",
            "name": "Origin",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Origin"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LicenseActivateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LicenseActivateResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ],
        "summary": "Activate a license on a device or website",
        "tags": [
          "Licensing (required)"
        ]
      }
    },
    "/v1/license/activations": {
      "get": {
        "operationId": "list_activations_v1_license_activations_get",
        "parameters": [
          {
            "in": "query",
            "name": "license_key",
            "required": true,
            "schema": {
              "title": "License Key",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "plugin_slug",
            "required": true,
            "schema": {
              "title": "Plugin Slug",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "Origin",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Origin"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LicenseActivationsResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ],
        "summary": "List a license's activations",
        "tags": [
          "Licensing (optional)"
        ]
      }
    },
    "/v1/license/deactivate": {
      "post": {
        "description": "Free up a seat or website so the customer can use their key somewhere else. Wire it to a Deactivate button in your license screen.",
        "operationId": "deactivate_license_v1_license_deactivate_post",
        "parameters": [
          {
            "in": "header",
            "name": "Origin",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Origin"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LicenseDeactivateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LicenseDeactivateResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ],
        "summary": "Deactivate a device or website",
        "tags": [
          "Licensing (required)"
        ]
      }
    },
    "/v1/license/jwks/{group_slug}/{plugin_slug}.json": {
      "get": {
        "description": "Public JWKS for a plugin's group \u2014 lets offline verifiers fetch the key.\n\nUnauthenticated and verification-only: it exposes only public keys\n(active + retired, so tokens issued before a rotation still verify).\nThe group_slug + plugin_slug pair uniquely identifies the tenant's\nsigning keys (plugin slugs are only unique within a group).\nThe JWT ``kid`` disambiguates the exact key, so a verifier ignores any\nkeys it does not recognise.",
        "operationId": "license_jwks_v1_license_jwks__group_slug___plugin_slug__json_get",
        "parameters": [
          {
            "in": "path",
            "name": "group_slug",
            "required": true,
            "schema": {
              "title": "Group Slug",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "plugin_slug",
            "required": true,
            "schema": {
              "title": "Plugin Slug",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": {
                    "items": {
                      "additionalProperties": {
                        "type": "string"
                      },
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "title": "Response License Jwks V1 License Jwks  Group Slug   Plugin Slug  Json Get",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get the public keys for verifying offline tokens",
        "tags": [
          "Licensing (optional)"
        ]
      }
    },
    "/v1/license/jwks/{plugin_slug}.json": {
      "get": {
        "description": "Legacy JWKS path \u2014 slug alone is ambiguous across tenants.\n\nRemoved in favour of ``/v1/license/jwks/{group_slug}/{plugin_slug}.json``.\nReturns 410 Gone so existing integrations get a clear migration signal\nrather than silently receiving keys for the wrong tenant.",
        "operationId": "license_jwks_legacy_v1_license_jwks__plugin_slug__json_get",
        "parameters": [
          {
            "in": "path",
            "name": "plugin_slug",
            "required": true,
            "schema": {
              "title": "Plugin Slug",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get public keys (legacy path)",
        "tags": [
          "Licensing (optional)"
        ]
      }
    },
    "/v1/license/token": {
      "post": {
        "description": "Mint a short-lived, offline-verifiable signed license token (JWT).\n\nRuns the same validation as ``/validate``; on success it returns an\nEdDSA-signed JWT whose claims mirror the validate response. The\ncustomer's app verifies the token locally against the plugin's JWKS\n(no network call), trading freshness for offline resilience \u2014\n``/validate`` remains the authoritative, revocation-aware check.",
        "operationId": "issue_license_token_v1_license_token_post",
        "parameters": [
          {
            "in": "header",
            "name": "Origin",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Origin"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LicenseValidateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LicenseTokenResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ],
        "summary": "Get an offline license token",
        "tags": [
          "Licensing (optional)"
        ]
      }
    },
    "/v1/license/validate": {
      "post": {
        "description": "Check whether a license key is currently valid for your product. Call it when the customer enters their key, then again in the background about once a day (and at app launch). Unlock your product only when the response has `valid: true`.",
        "operationId": "validate_license_v1_license_validate_post",
        "parameters": [
          {
            "in": "header",
            "name": "Origin",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Origin"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LicenseValidateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LicenseValidateResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ],
        "summary": "Validate a license key",
        "tags": [
          "Licensing (required)"
        ]
      }
    },
    "/v1/seller/customers": {
      "get": {
        "description": "The buyer with this email, if they hold a license for this product.",
        "operationId": "find_customers_v1_seller_customers_get",
        "parameters": [
          {
            "description": "The buyer's email",
            "in": "query",
            "name": "email",
            "required": true,
            "schema": {
              "description": "The buyer's email",
              "minLength": 3,
              "title": "Email",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "Origin",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Origin"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SellerCustomerList"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ],
        "summary": "Look up a buyer",
        "tags": [
          "Seller API"
        ]
      }
    },
    "/v1/seller/customers/{customer_id}": {
      "delete": {
        "description": "Erase a buyer's personal data, e.g. on their request. Cannot be undone.\n\nTheir email becomes anonymous and their devices are released; licenses\nand payments stay as your sales records, and a paid license keeps\nworking. Refused with 409 while they have a subscription that is still\nbilling: cancel it first. Erasing an erased buyer again does nothing.",
        "operationId": "delete_customer_v1_seller_customers__customer_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "customer_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Customer Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "Origin",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Origin"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Conflict"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ],
        "summary": "Erase a buyer",
        "tags": [
          "Seller API"
        ]
      }
    },
    "/v1/seller/licenses": {
      "get": {
        "operationId": "list_licenses_v1_seller_licenses_get",
        "parameters": [
          {
            "description": "Only this buyer's licenses",
            "in": "query",
            "name": "customer_email",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this buyer's licenses",
              "title": "Customer Email"
            }
          },
          {
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "$ref": "#/components/schemas/LicenseStatus"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Status"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "maximum": 200,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "default": 0,
              "minimum": 0,
              "title": "Offset",
              "type": "integer"
            }
          },
          {
            "in": "header",
            "name": "Origin",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Origin"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SellerLicenseList"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ],
        "summary": "List licenses",
        "tags": [
          "Seller API"
        ]
      },
      "post": {
        "description": "Issue a license without a payment, e.g. for a sale made elsewhere. The key is returned once.",
        "operationId": "create_license_v1_seller_licenses_post",
        "parameters": [
          {
            "in": "header",
            "name": "Origin",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Origin"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SellerLicenseIssueRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SellerLicenseIssued"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Payment Required"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ],
        "summary": "Issue a license",
        "tags": [
          "Seller API"
        ]
      }
    },
    "/v1/seller/licenses/{license_id}": {
      "get": {
        "operationId": "get_license_v1_seller_licenses__license_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "license_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "License Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "Origin",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Origin"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SellerLicense"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ],
        "summary": "Get a license",
        "tags": [
          "Seller API"
        ]
      }
    },
    "/v1/seller/licenses/{license_id}/activations/{activation_id}/release": {
      "post": {
        "description": "Free a seat or domain, e.g. for a buyer who lost the device. Idempotent.",
        "operationId": "release_activation_v1_seller_licenses__license_id__activations__activation_id__release_post",
        "parameters": [
          {
            "in": "path",
            "name": "license_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "License Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "activation_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Activation Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "Origin",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Origin"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LicenseDeactivateResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ],
        "summary": "Release an activation",
        "tags": [
          "Seller API"
        ]
      }
    },
    "/v1/seller/licenses/{license_id}/regenerate-key": {
      "post": {
        "description": "Issue a new key for the license; the old key stops working. The new key is returned once.\n\nSends ``license.key_regenerated``, and emails the live buyer the same way issuing does.",
        "operationId": "regenerate_key_v1_seller_licenses__license_id__regenerate_key_post",
        "parameters": [
          {
            "in": "path",
            "name": "license_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "License Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "Origin",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Origin"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SellerLicenseIssued"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ],
        "summary": "Replace a license key",
        "tags": [
          "Seller API"
        ]
      }
    },
    "/v1/seller/licenses/{license_id}/revoke": {
      "post": {
        "description": "Turn an active license off: validate starts answering ``valid: false``.\n\nIdempotent, and an expired license stays expired: it is already off,\nand keeping its status says why.",
        "operationId": "revoke_license_v1_seller_licenses__license_id__revoke_post",
        "parameters": [
          {
            "in": "path",
            "name": "license_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "License Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "Origin",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Origin"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SellerLicense"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ],
        "summary": "Revoke a license",
        "tags": [
          "Seller API"
        ]
      }
    },
    "/v1/seller/subscriptions": {
      "get": {
        "operationId": "list_subscriptions_v1_seller_subscriptions_get",
        "parameters": [
          {
            "description": "Only this buyer's subscriptions",
            "in": "query",
            "name": "customer_email",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this buyer's subscriptions",
              "title": "Customer Email"
            }
          },
          {
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "$ref": "#/components/schemas/SubscriptionStatus"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Status"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "maximum": 200,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "default": 0,
              "minimum": 0,
              "title": "Offset",
              "type": "integer"
            }
          },
          {
            "in": "header",
            "name": "Origin",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Origin"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SellerSubscriptionList"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ],
        "summary": "List subscriptions",
        "tags": [
          "Seller API"
        ]
      }
    },
    "/v1/store/{group_slug}/branding": {
      "get": {
        "operationId": "store_group_branding_v1_store__group_slug__branding_get",
        "parameters": [
          {
            "in": "path",
            "name": "group_slug",
            "required": true,
            "schema": {
              "title": "Group Slug",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoreGroupBranding"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get a storefront's branding",
        "tags": [
          "Hosted storefront"
        ]
      }
    },
    "/v1/store/{group_slug}/checkout": {
      "post": {
        "operationId": "store_checkout_for_group_v1_store__group_slug__checkout_post",
        "parameters": [
          {
            "in": "path",
            "name": "group_slug",
            "required": true,
            "schema": {
              "title": "Group Slug",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "x-firebase-appcheck",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Firebase-Appcheck"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StoreCheckoutRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CheckoutResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Bad Request"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Conflict"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Bad Gateway"
          }
        },
        "summary": "Start a checkout from the storefront",
        "tags": [
          "Hosted storefront"
        ]
      }
    },
    "/v1/store/{group_slug}/plans": {
      "get": {
        "operationId": "store_list_plans_for_group_v1_store__group_slug__plans_get",
        "parameters": [
          {
            "in": "path",
            "name": "group_slug",
            "required": true,
            "schema": {
              "title": "Group Slug",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoreCatalogResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List the plans on sale",
        "tags": [
          "Hosted storefront"
        ]
      }
    }
  },
  "tags": [
    {
      "description": "**Start here. These three calls are what make licensing work in your product.**\n\n- **Activate** runs once, when the customer pastes their key. It registers their device or website, which is how the plan's device limit is enforced.\n- **Validate** answers one question: should my product unlock right now? Call it right after activation, at every launch, and about once a day. Unlock only when `valid` is `true`.\n- **Deactivate** runs when the customer clicks Deactivate. It frees their slot so they can use the key on a new computer.\n\nIf you only build these three, your licensing works.",
      "name": "Licensing (required)"
    },
    {
      "description": "**Extras for specific needs. Skip this whole section until you need one of them.**\n\n- **List activations** shows which devices or websites are using a key. Use it for a \"Manage my devices\" screen.\n- **Offline license token** lets your product keep working with no internet, by giving it a signed token it can check locally.\n- **Public keys** are what your product uses to verify that offline token really came from Licensr. You only need them if you use offline tokens.",
      "name": "Licensing (optional)"
    },
    {
      "description": "**Sell from inside your product.** Instead of sending customers to your buy page in a browser, your product calls this to start a purchase and gets back a payment link to open. Optional: the hosted buy page already works without any of this.",
      "name": "In-app checkout"
    },
    {
      "description": "**Manage your licenses from your own server.** List and look up licenses, buyers and subscriptions, issue a license for a sale made elsewhere, or revoke one. Needs a **full-access** API key (a Client key gets `403 insufficient_scope`, and so does a server key issued before the seller API existed: issue a new one), so never call it from code you ship to customers. Each key only sees its own product. A test key (`pk_test_`) only sees the test pool: same calls, separate customers and licenses, and it cannot start a checkout. Checkout always creates a live license.",
      "name": "Seller API"
    },
    {
      "description": "**Data behind the Licensr buy page.** These read-only calls return your branding and the plans on sale, and start a checkout from the storefront. You only need them if you build your own buy page instead of using the hosted one at `/buy/your-slug`.",
      "name": "Hosted storefront"
    }
  ]
}
