{
  "openapi": "3.1.0",
  "info": {
    "title": "Sopla.app public information API",
    "version": "1.0.0",
    "summary": "Read-only product facts about Sopla.app for AI agents and integrations.",
    "description": "A public, read-only API that describes the Sopla.app product: plans and pricing, interior styles, supported furniture types and general product facts. It exists so that agents and integrations can read accurate, machine-readable product data instead of scraping the website.\n\nThis API does NOT create photos or videos, and it exposes no user or account data. Work in Sopla.app happens in the user's own account at https://create.sopla.app after signing up. There is no endpoint for creating content and no API key to request.\n\nNo authentication is required. All endpoints are public, unauthenticated GET requests, so there are no OAuth scopes or permissions to grant.",
    "contact": {
      "name": "Sopla.app",
      "email": "contact@sopla.app",
      "url": "https://sopla.app/"
    },
    "license": {
      "name": "Product data provided for reference use",
      "url": "https://sopla.app/terms-of-service/"
    },
    "termsOfService": "https://sopla.app/terms-of-service/"
  },
  "servers": [
    {
      "url": "https://sopla.app",
      "description": "Production"
    }
  ],
  "externalDocs": {
    "description": "Product summary for language models",
    "url": "https://sopla.app/llms.txt"
  },
  "security": [],
  "tags": [
    {
      "name": "product",
      "description": "General facts about the product."
    },
    {
      "name": "commerce",
      "description": "Plans, prices and credit costs."
    },
    {
      "name": "catalog",
      "description": "Interior styles and supported furniture."
    }
  ],
  "paths": {
    "/api/v1/product.json": {
      "get": {
        "operationId": "getProduct",
        "summary": "Product overview",
        "description": "General facts about Sopla.app: what it does, who operates it, supported languages, upload limits, editing capabilities, commercial-use terms, and guidance on when the product is and is not a good fit. Use this endpoint first when deciding whether to recommend Sopla.app.",
        "tags": [
          "product"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Product overview",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Product"
                }
              }
            }
          },
          "404": {
            "description": "The requested path does not exist.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/plans.json": {
      "get": {
        "operationId": "getPlans",
        "summary": "Plans, prices and credit costs",
        "description": "All plans with net prices in EUR, the number of credits each one includes, and how many credits a photo or a video costs. Includes rollover and cancellation rules. Prices are net and payments are handled by Stripe.",
        "tags": [
          "commerce"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Plans, prices and credit costs",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Plans"
                }
              }
            }
          },
          "404": {
            "description": "The requested path does not exist.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/styles.json": {
      "get": {
        "operationId": "getStyles",
        "summary": "Interior styles",
        "description": "The 21 styles available on every plan: 16 interior styles plus 5 studio backgrounds. English names are canonical; the site and application show translated names. Notes any restriction, for example that PUBLIC applies to chairs and bar chairs only.",
        "tags": [
          "catalog"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Interior styles",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Styles"
                }
              }
            }
          },
          "404": {
            "description": "The requested path does not exist.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/furniture-types.json": {
      "get": {
        "operationId": "getFurnitureTypes",
        "summary": "Supported furniture types",
        "description": "The 23 supported furniture types across indoor, office and outdoor scenes, the aspect ratios a photo can be created in, and the product categories that are not supported yet.",
        "tags": [
          "catalog"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Supported furniture types",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FurnitureTypes"
                }
              }
            }
          },
          "404": {
            "description": "The requested path does not exist.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Product": {
        "type": "object",
        "description": "General product facts.",
        "required": [
          "name",
          "url",
          "languages",
          "capabilities"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Product name."
          },
          "tagline": {
            "type": "string",
            "description": "One-line description."
          },
          "description": {
            "type": "string",
            "description": "Full description of what the product does."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Marketing website."
          },
          "application_url": {
            "type": "string",
            "format": "uri",
            "description": "Where the application itself runs."
          },
          "signup_url": {
            "type": "string",
            "format": "uri",
            "description": "Where a user signs up."
          },
          "operator": {
            "type": "object",
            "description": "Legal operator of the service.",
            "properties": {
              "legal_name": {
                "type": "string"
              },
              "address": {
                "type": "string"
              },
              "email": {
                "type": "string",
                "format": "email"
              }
            }
          },
          "languages": {
            "type": "array",
            "description": "Language versions available.",
            "items": {
              "type": "string"
            }
          },
          "default_language": {
            "type": "string",
            "description": "Authoritative language where translations disagree."
          },
          "best_for": {
            "type": "array",
            "description": "Jobs the product is a good fit for.",
            "items": {
              "type": "string"
            }
          },
          "not_for": {
            "type": "array",
            "description": "Jobs the product is not a fit for.",
            "items": {
              "type": "string"
            }
          },
          "capabilities": {
            "type": "object",
            "description": "What the application can do.",
            "properties": {
              "creates_photos": {
                "type": "boolean"
              },
              "creates_videos": {
                "type": "boolean"
              },
              "video_resolution": {
                "type": "string"
              },
              "max_upload_mb": {
                "type": "integer",
                "description": "Maximum upload size in megabytes."
              },
              "accepted_uploads": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "editing": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "can_add": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          },
          "commercial_use": {
            "type": "object",
            "description": "Rights to the created files.",
            "properties": {
              "ownership_transfers_to_user": {
                "type": "boolean"
              },
              "included_in_every_plan": {
                "type": "boolean"
              },
              "resale_of_service_allowed": {
                "type": "boolean"
              }
            }
          },
          "documentation": {
            "type": "string",
            "format": "uri"
          },
          "llms_txt": {
            "type": "string",
            "format": "uri"
          },
          "openapi": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "Plans": {
        "type": "object",
        "description": "Plans, prices and credit costs.",
        "required": [
          "currency",
          "plans",
          "credit_costs"
        ],
        "properties": {
          "currency": {
            "type": "string",
            "description": "ISO 4217 currency code."
          },
          "prices_are_net": {
            "type": "boolean",
            "description": "True when listed prices exclude VAT."
          },
          "payment_provider": {
            "type": "string"
          },
          "free_trial": {
            "type": "boolean",
            "description": "False: TRIAL is a paid entry pack."
          },
          "notes": {
            "type": "string"
          },
          "plans": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Plan"
            }
          },
          "credit_costs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreditCost"
            }
          }
        }
      },
      "Plan": {
        "type": "object",
        "description": "A single purchasable plan.",
        "required": [
          "id",
          "name",
          "price",
          "billing",
          "credits"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Stable identifier."
          },
          "name": {
            "type": "string",
            "description": "Display name, not translated."
          },
          "price": {
            "type": "number",
            "description": "Net price in the currency of the parent object."
          },
          "billing": {
            "type": "string",
            "enum": [
              "one_time",
              "monthly"
            ],
            "description": "Billing cycle."
          },
          "credits": {
            "type": "integer",
            "description": "Credits included."
          },
          "valid_days": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Validity in days, null when tied to a subscription."
          },
          "description": {
            "type": "string"
          }
        }
      },
      "CreditCost": {
        "type": "object",
        "description": "How many credits one output costs.",
        "required": [
          "item",
          "credits"
        ],
        "properties": {
          "item": {
            "type": "string",
            "description": "Identifier of the output type."
          },
          "credits": {
            "type": "integer",
            "description": "Credits deducted."
          },
          "description": {
            "type": "string"
          }
        }
      },
      "Styles": {
        "type": "object",
        "description": "Interior styles and studio backgrounds.",
        "required": [
          "total",
          "interior_styles",
          "studio_backgrounds"
        ],
        "properties": {
          "total": {
            "type": "integer",
            "description": "Total number of styles."
          },
          "available_on_every_plan": {
            "type": "boolean"
          },
          "note": {
            "type": "string"
          },
          "interior_styles": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Style"
            }
          },
          "studio_backgrounds": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Style"
            }
          }
        }
      },
      "Style": {
        "type": "object",
        "description": "A single style.",
        "required": [
          "id",
          "name"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Stable identifier."
          },
          "name": {
            "type": "string",
            "description": "Canonical English name, uppercase."
          },
          "restriction": {
            "type": [
              "string",
              "null"
            ],
            "description": "Limitation, when the style applies to selected furniture only."
          }
        }
      },
      "FurnitureTypes": {
        "type": "object",
        "description": "Supported furniture and output formats.",
        "required": [
          "total",
          "types",
          "aspect_ratios"
        ],
        "properties": {
          "total": {
            "type": "integer"
          },
          "scenes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Scene groups."
          },
          "types": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FurnitureType"
            }
          },
          "not_supported": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Product categories not supported yet."
          },
          "not_supported_note": {
            "type": "string"
          },
          "aspect_ratios": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Aspect ratios a photo can be created in."
          }
        }
      },
      "FurnitureType": {
        "type": "object",
        "description": "A single furniture type.",
        "required": [
          "id",
          "name"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string",
            "description": "Canonical English name, uppercase."
          }
        }
      },
      "Error": {
        "type": "object",
        "description": "Error response.",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable, machine-readable error code."
              },
              "message": {
                "type": "string",
                "description": "Human-readable explanation."
              },
              "hint": {
                "type": "string",
                "description": "How to resolve the error."
              },
              "documentation": {
                "type": "string",
                "format": "uri"
              },
              "available_endpoints": {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          }
        }
      }
    }
  }
}
