{
    "openapi": "3.0.0",
    "info": {
        "title": "Bespoke API",
        "description": "Official reference for Bespoke API endpoints, including authentication, request and response formats, and error handling.\n",
        "version": "3.0.0"
    },
    "servers": [
        {
            "url": "https://api.rhinoartisan.com",
            "description": "API base URL"
        }
    ],
    "paths": {
        "/v3/admin/stats": {
            "get": {
                "tags": [
                    "Admin"
                ],
                "summary": "Account totals for the admin home",
                "operationId": "get_app_admin_apiadminaccounts_stats",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "403": {
                        "description": "ACCESS_DENIED"
                    }
                }
            }
        },
        "/v3/admin/users": {
            "get": {
                "tags": [
                    "Admin"
                ],
                "summary": "List users",
                "operationId": "get_app_admin_apiadminaccounts_listusers",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "description": "email, name or username",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "description": "1 active, -1 blocked, 0 pending",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "superuser",
                        "in": "query",
                        "description": "1 to keep superusers only",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "orphan",
                        "in": "query",
                        "description": "1 to keep users without organization",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "maximum": 200
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "items, total, page, limit"
                    }
                }
            }
        },
        "/v3/admin/users/{id}": {
            "get": {
                "tags": [
                    "Admin"
                ],
                "summary": "User profile, membership and developer keys",
                "operationId": "get_app_admin_apiadminaccounts_getuserdetail",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "404": {
                        "description": "USER_NOT_FOUND"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Admin"
                ],
                "summary": "Delete a user for good",
                "description": "Removes the user from the database (memberships included) and from Supabase Auth. 409 USER_HAS_CONTENT when the user owns designs or files: block the account instead.",
                "operationId": "delete_app_admin_apiadminaccounts_deleteuser",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Deleted"
                    },
                    "409": {
                        "description": "USER_HAS_CONTENT"
                    }
                }
            },
            "patch": {
                "tags": [
                    "Admin"
                ],
                "summary": "Update a user",
                "description": "Only the provided fields change. `status` -1 also bans the login in Supabase, 1 lifts the ban. `roles` are the global roles (ROLE_SUPERUSER, ROLE_ADMIN, ROLE_TRACKER, ROLE_STAFF).",
                "operationId": "patch_app_admin_apiadminaccounts_updateuser",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "status": {
                                        "type": "integer",
                                        "enum": [
                                            1,
                                            0,
                                            -1
                                        ]
                                    },
                                    "beta": {
                                        "type": "boolean"
                                    },
                                    "fullname": {
                                        "type": "string"
                                    },
                                    "jobtitle": {
                                        "type": "string"
                                    },
                                    "lang": {
                                        "type": "string"
                                    },
                                    "roles": {
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        }
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Updated user"
                    }
                }
            }
        },
        "/v3/admin/users/{id}/recovery": {
            "post": {
                "tags": [
                    "Admin"
                ],
                "summary": "Send a password recovery email",
                "operationId": "post_app_admin_apiadminaccounts_sendrecovery",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sent"
                    }
                }
            }
        },
        "/v3/admin/organizations": {
            "get": {
                "tags": [
                    "Admin"
                ],
                "summary": "List organizations",
                "operationId": "get_app_admin_apiadminaccounts_listorganizations",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "description": "name, email or VAT",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "pending",
                        "in": "query",
                        "description": "only self signups waiting for approval",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "1"
                            ]
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "maximum": 200
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "items, total, page, limit"
                    }
                }
            },
            "post": {
                "tags": [
                    "Admin"
                ],
                "summary": "Create an organization",
                "operationId": "post_app_admin_apiadminaccounts_createorganization",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "name": {
                                        "type": "string"
                                    },
                                    "owner_email": {
                                        "description": "Optional: added (or invited) as ROLE_OWNER",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Organization"
                    }
                }
            }
        },
        "/v3/admin/organizations/{id}": {
            "get": {
                "tags": [
                    "Admin"
                ],
                "summary": "Organization with its team",
                "operationId": "get_app_admin_apiadminaccounts_getorganization",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "404": {
                        "description": "ORGANIZATION_NOT_FOUND"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Admin"
                ],
                "summary": "Delete an organization",
                "description": "Members go with it; users stay. 409 ORGANIZATION_HAS_CONTENT when it still owns designs, files or stock.",
                "operationId": "delete_app_admin_apiadminaccounts_deleteorganization",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Deleted"
                    },
                    "409": {
                        "description": "ORGANIZATION_HAS_CONTENT"
                    }
                }
            },
            "patch": {
                "tags": [
                    "Admin"
                ],
                "summary": "Update an organization",
                "description": "Only the provided fields change. Third-party keys (falai_api_key, open_router_api_key) can be set or cleared with an empty string, never read back. Setting pending_approval to false approves a self signup: its members can use the app from then on and its owners get an email.",
                "operationId": "patch_app_admin_apiadminaccounts_updateorganization",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "name": {
                                        "type": "string"
                                    },
                                    "email": {
                                        "type": "string"
                                    },
                                    "phone": {
                                        "type": "string"
                                    },
                                    "address": {
                                        "type": "string"
                                    },
                                    "city": {
                                        "type": "string"
                                    },
                                    "stateOrProvince": {
                                        "type": "string"
                                    },
                                    "zip": {
                                        "type": "string"
                                    },
                                    "country": {
                                        "type": "string"
                                    },
                                    "vatNumber": {
                                        "type": "string"
                                    },
                                    "language": {
                                        "type": "string"
                                    },
                                    "currency": {
                                        "type": "string"
                                    },
                                    "ettoreModel": {
                                        "type": "string"
                                    },
                                    "ettoreInstructions": {
                                        "type": "string"
                                    },
                                    "assistantDailyBudget": {
                                        "description": "Assistant spend cap in USD per day (OpenRouter usage.cost over 24 h); null = platform default",
                                        "type": "number",
                                        "nullable": true
                                    },
                                    "falai_api_key": {
                                        "type": "string"
                                    },
                                    "open_router_api_key": {
                                        "type": "string"
                                    },
                                    "pending_approval": {
                                        "type": "boolean"
                                    },
                                    "is_catalogue": {
                                        "type": "boolean"
                                    },
                                    "is_vendor": {
                                        "description": "Vendor organization: its published capsules (with .gh) are offered to the stores it is given to",
                                        "type": "boolean"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Organization"
                    }
                }
            }
        },
        "/v3/admin/organizations/{id}/support-access": {
            "post": {
                "tags": [
                    "Admin"
                ],
                "summary": "Enter an organization as support",
                "description": "Records that the superuser enters the organization and returns the app URL that puts them inside it. For the next hours, their requests carrying the X-Support-Organization header with that organization id are resolved against it, as its owner. Every entry is listed in the organization detail.",
                "operationId": "post_app_admin_apiadminaccounts_opensupportaccess",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "url, valid_hours"
                    },
                    "404": {
                        "description": "ORGANIZATION_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/admin/organizations/{id}/vendor/retailers": {
            "post": {
                "tags": [
                    "Admin"
                ],
                "summary": "Give the vendor's capsules to a store",
                "description": "The store sees the published capsules (with .gh) of the vendor in Merchandising > Capsules, under Vendors, to add them as copies that get the vendor's updates. Only while the organization is marked as vendor.",
                "operationId": "post_app_admin_apiadminaccounts_addvendorretailer",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "organization_id": {
                                        "description": "The store",
                                        "type": "integer"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The vendor organization"
                    },
                    "400": {
                        "description": "SAME_ORGANIZATION"
                    },
                    "404": {
                        "description": "ORGANIZATION_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/admin/organizations/{id}/vendor/retailers/{retailerId}": {
            "delete": {
                "tags": [
                    "Admin"
                ],
                "summary": "Stop giving the vendor's capsules to a store",
                "description": "The capsules the store already added stay as its own.",
                "operationId": "delete_app_admin_apiadminaccounts_removevendorretailer",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "name": "retailerId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The vendor organization"
                    }
                }
            }
        },
        "/v3/admin/organizations/{id}/members": {
            "post": {
                "tags": [
                    "Admin"
                ],
                "summary": "Add or invite a member",
                "description": "An existing account joins right away; an unknown email gets a Supabase invitation. Any role can be granted here, confidential ones included.",
                "operationId": "post_app_admin_apiadminaccounts_addmember",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "email": {
                                        "type": "string"
                                    },
                                    "roles": {
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        }
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Organization"
                    },
                    "409": {
                        "description": "USER_ALREADY_IN_ORGANIZATION | EMAIL_ALREADY_INVITED"
                    }
                }
            }
        },
        "/v3/admin/members/{id}": {
            "delete": {
                "tags": [
                    "Admin"
                ],
                "summary": "Remove a member or cancel an invitation",
                "operationId": "delete_app_admin_apiadminaccounts_removemember",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Organization"
                    }
                }
            },
            "patch": {
                "tags": [
                    "Admin"
                ],
                "summary": "Set a member's roles",
                "operationId": "patch_app_admin_apiadminaccounts_updatemember",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "roles": {
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        }
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Organization"
                    }
                }
            }
        },
        "/v3/admin/members/{id}/ownership": {
            "post": {
                "tags": [
                    "Admin"
                ],
                "summary": "Make this member the only owner",
                "operationId": "post_app_admin_apiadminaccounts_transferownership",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Organization"
                    }
                }
            }
        },
        "/v3/admin/designs/{id}/template": {
            "put": {
                "tags": [
                    "Admin"
                ],
                "summary": "Publish or unpublish a design as a library template",
                "description": "Only the Bespoke team (superusers) can mark a design as a template. Drafts cannot be published.",
                "operationId": "put_app_admin_apiadminaccounts_settemplate",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "is_template": {
                                        "type": "boolean"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "{id, is_template}"
                    },
                    "404": {
                        "description": "DESIGN_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/admin/overview": {
            "get": {
                "tags": [
                    "Admin"
                ],
                "summary": "At-a-glance usage numbers for the admin home",
                "operationId": "get_app_admin_apiadminanalytics_overview",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "403": {
                        "description": "ACCESS_DENIED"
                    }
                }
            }
        },
        "/v3/admin/analytics": {
            "get": {
                "tags": [
                    "Admin"
                ],
                "summary": "Business analytics for a period",
                "description": "Totals for the period (with the previous period for comparison), weekly series, compute breakdown, storage, most active organizations and latest signups.",
                "operationId": "get_app_admin_apiadminanalytics_analytics",
                "parameters": [
                    {
                        "name": "days",
                        "in": "query",
                        "description": "Period length, default 30",
                        "schema": {
                            "type": "integer",
                            "enum": [
                                7,
                                30,
                                90,
                                365
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "403": {
                        "description": "ACCESS_DENIED"
                    }
                }
            }
        },
        "/v3/admin/bug-reports": {
            "get": {
                "tags": [
                    "Admin"
                ],
                "summary": "Latest bug reports",
                "operationId": "get_app_admin_apiadminbugreport_list",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "description": "Only this status; all when omitted",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "open",
                                "closed"
                            ]
                        }
                    },
                    {
                        "name": "linked",
                        "in": "query",
                        "description": "0 = without an issue (to triage), 1 = linked to an issue; both when omitted",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "0",
                                "1"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "403": {
                        "description": "ACCESS_DENIED"
                    }
                }
            }
        },
        "/v3/admin/bug-reports/{id}": {
            "get": {
                "tags": [
                    "Admin"
                ],
                "summary": "A bug report with its context and design copy",
                "operationId": "get_app_admin_apiadminbugreport_get",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "404": {
                        "description": "BUG_REPORT_NOT_FOUND"
                    }
                }
            },
            "put": {
                "tags": [
                    "Admin"
                ],
                "summary": "Close or reopen a bug report",
                "operationId": "put_app_admin_apiadminbugreport_update",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "status": {
                                        "type": "string",
                                        "enum": [
                                            "open",
                                            "closed"
                                        ]
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "404": {
                        "description": "BUG_REPORT_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/admin/organizations/{id}/catalogue/collections": {
            "get": {
                "tags": [
                    "Admin"
                ],
                "summary": "Collections of the organization that can go in a catalogue package",
                "operationId": "get_app_admin_apiadmincatalogue_collections",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "[{id, name, status, design_count}]"
                    }
                }
            }
        },
        "/v3/admin/organizations/{id}/catalogue/export": {
            "get": {
                "tags": [
                    "Admin"
                ],
                "summary": "Catalogue package (JSON) of some collections of the organization",
                "operationId": "get_app_admin_apiadmincatalogue_export",
                "parameters": [
                    {
                        "name": "collections",
                        "in": "query",
                        "description": "Collection ids \"1,5,7\" (default: every collection with designs)",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The package, as a download"
                    }
                }
            }
        },
        "/v3/admin/organizations/{id}/catalogue/plan": {
            "post": {
                "tags": [
                    "Admin"
                ],
                "summary": "What installing this package would do (body: the package)",
                "operationId": "post_app_admin_apiadmincatalogue_plan",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "{source, capsules, collections, designs}"
                    }
                }
            }
        },
        "/v3/admin/organizations/{id}/catalogue/install": {
            "post": {
                "tags": [
                    "Admin"
                ],
                "summary": "Install one batch of a catalogue package (body: the package)",
                "operationId": "post_app_admin_apiadmincatalogue_install",
                "parameters": [
                    {
                        "name": "offset",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "update_capsules",
                        "in": "query",
                        "description": "Capsules that exist with another .gh get the catalogue's",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "{total, offset, next_offset, created, existing, failed, warnings}"
                    }
                }
            }
        },
        "/v3/admin/compute-cache": {
            "get": {
                "tags": [
                    "Admin"
                ],
                "summary": "Compute cache: totals, engine version and one row per capsule",
                "operationId": "get_app_admin_apiadmincomputecache_overview",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "403": {
                        "description": "ACCESS_DENIED"
                    }
                }
            }
        },
        "/v3/admin/compute-cache/capsules/{id}": {
            "get": {
                "tags": [
                    "Admin"
                ],
                "summary": "Cache entries of a capsule (0 = entries without capsule)",
                "operationId": "get_app_admin_apiadmincomputecache_entries",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/v3/admin/compute-cache/purge": {
            "post": {
                "tags": [
                    "Admin"
                ],
                "summary": "Delete the cache entries of some capsules (or all); only the stale ones with stale_only",
                "operationId": "post_app_admin_apiadmincomputecache_purge",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "capsule_ids": {
                                        "description": "null = every capsule; 0 = entries without capsule",
                                        "type": "array",
                                        "items": {
                                            "type": "integer"
                                        },
                                        "nullable": true
                                    },
                                    "stale_only": {
                                        "description": "Only entries of an older .gh or another engine version",
                                        "type": "boolean"
                                    },
                                    "dry_run": {
                                        "type": "boolean"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "{entries, bytes}"
                    }
                }
            }
        },
        "/v3/admin/compute-cache/prune": {
            "post": {
                "tags": [
                    "Admin"
                ],
                "summary": "Delete entries unused for N days that no design uses",
                "operationId": "post_app_admin_apiadmincomputecache_prune",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "unused_days": {
                                        "type": "integer",
                                        "default": 90
                                    },
                                    "dry_run": {
                                        "type": "boolean"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "{entries, bytes}"
                    }
                }
            }
        },
        "/v3/admin/issues/board": {
            "get": {
                "tags": [
                    "Admin > Board"
                ],
                "summary": "The board: cards by column in order, who can be assigned, archived count",
                "description": "Columns: new, todo, in_progress, testing, done (done only shows the last two weeks).",
                "operationId": "get_app_admin_apiadminissue_board",
                "parameters": [
                    {
                        "name": "assignee",
                        "in": "query",
                        "description": "A user id or `me`",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "q",
                        "in": "query",
                        "description": "Text in title or description, or BE-12",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "403": {
                        "description": "ACCESS_DENIED"
                    }
                }
            }
        },
        "/v3/admin/issues/board/version": {
            "get": {
                "tags": [
                    "Admin > Board"
                ],
                "summary": "A fingerprint of the board: it changes whenever a card, comment or attachment does",
                "description": "The admin polls it every few seconds and reloads only when it changes.",
                "operationId": "get_app_admin_apiadminissue_version",
                "responses": {
                    "200": {
                        "description": "{version}"
                    }
                }
            }
        },
        "/v3/admin/issues/labels": {
            "get": {
                "tags": [
                    "Admin > Board"
                ],
                "summary": "The board's colour gomets (labels), in order",
                "operationId": "get_app_admin_apiadminissue_labels",
                "responses": {
                    "200": {
                        "description": "[{id, color, name}]"
                    }
                }
            },
            "post": {
                "tags": [
                    "Admin > Board"
                ],
                "summary": "Create a colour gomet: a palette colour and an optional name",
                "operationId": "post_app_admin_apiadminissue_createlabel",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "color": {
                                        "type": "string",
                                        "enum": [
                                            "green",
                                            "yellow",
                                            "orange",
                                            "red",
                                            "purple",
                                            "blue",
                                            "sky",
                                            "pink"
                                        ]
                                    },
                                    "name": {
                                        "type": "string",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "All the gomets"
                    },
                    "400": {
                        "description": "INVALID_LABEL_COLOR"
                    }
                }
            }
        },
        "/v3/admin/issues/labels/{labelId}": {
            "put": {
                "tags": [
                    "Admin > Board"
                ],
                "summary": "Change a gomet's colour or name (on every card that has it)",
                "operationId": "put_app_admin_apiadminissue_updatelabel",
                "parameters": [
                    {
                        "name": "labelId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "color": {
                                        "type": "string",
                                        "enum": [
                                            "green",
                                            "yellow",
                                            "orange",
                                            "red",
                                            "purple",
                                            "blue",
                                            "sky",
                                            "pink"
                                        ]
                                    },
                                    "name": {
                                        "type": "string",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "All the gomets"
                    },
                    "404": {
                        "description": "LABEL_NOT_FOUND"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Admin > Board"
                ],
                "summary": "Delete a gomet from the board and from every card",
                "operationId": "delete_app_admin_apiadminissue_deletelabel",
                "parameters": [
                    {
                        "name": "labelId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "All the gomets"
                    },
                    "404": {
                        "description": "LABEL_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/admin/issues/archived": {
            "get": {
                "tags": [
                    "Admin > Board"
                ],
                "summary": "Archived cards, latest first",
                "operationId": "get_app_admin_apiadminissue_archived",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/v3/admin/issues": {
            "post": {
                "tags": [
                    "Admin > Board"
                ],
                "summary": "Add a card at the bottom of a column",
                "operationId": "post_app_admin_apiadminissue_create",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "title": {
                                        "type": "string"
                                    },
                                    "status": {
                                        "description": "Column; new when omitted",
                                        "type": "string",
                                        "enum": [
                                            "new",
                                            "todo",
                                            "in_progress",
                                            "testing",
                                            "done"
                                        ]
                                    },
                                    "type": {
                                        "description": "improvement when omitted",
                                        "type": "string",
                                        "enum": [
                                            "bug",
                                            "improvement",
                                            "wish"
                                        ]
                                    },
                                    "description": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "urgent": {
                                        "type": "boolean"
                                    },
                                    "assignee_id": {
                                        "type": "integer",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The card"
                    },
                    "400": {
                        "description": "MISSING_TITLE | INVALID_ISSUE_* | INVALID_ASSIGNEE"
                    }
                }
            }
        },
        "/v3/admin/issues/{id}": {
            "get": {
                "tags": [
                    "Admin > Board"
                ],
                "summary": "A card with its description, user reports and comments",
                "operationId": "get_app_admin_apiadminissue_get",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "404": {
                        "description": "ISSUE_NOT_FOUND"
                    }
                }
            },
            "put": {
                "tags": [
                    "Admin > Board"
                ],
                "summary": "Change only the fields sent",
                "operationId": "put_app_admin_apiadminissue_update",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "title": {
                                        "type": "string"
                                    },
                                    "description": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "type": {
                                        "type": "string",
                                        "enum": [
                                            "bug",
                                            "improvement",
                                            "wish"
                                        ]
                                    },
                                    "urgent": {
                                        "type": "boolean"
                                    },
                                    "assignee_id": {
                                        "type": "integer",
                                        "nullable": true
                                    },
                                    "label_ids": {
                                        "description": "The gomets the card has (replaces them)",
                                        "type": "array",
                                        "items": {
                                            "type": "integer"
                                        }
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The card"
                    },
                    "400": {
                        "description": "LABEL_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/admin/issues/{id}/move": {
            "put": {
                "tags": [
                    "Admin > Board"
                ],
                "summary": "Drag a card: to a column, right above `before_id` (or at `index`, 0 = top; at the bottom without either)",
                "description": "Reaching `done` closes the card's user reports and emails whoever reported them (once).",
                "operationId": "put_app_admin_apiadminissue_move",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "status": {
                                        "type": "string",
                                        "enum": [
                                            "new",
                                            "todo",
                                            "in_progress",
                                            "testing",
                                            "done"
                                        ]
                                    },
                                    "before_id": {
                                        "description": "The card that ends up right below; null = bottom",
                                        "type": "integer",
                                        "nullable": true
                                    },
                                    "index": {
                                        "type": "integer",
                                        "minimum": 0
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The card"
                    },
                    "400": {
                        "description": "INVALID_ISSUE_STATUS | ISSUE_ARCHIVED"
                    }
                }
            }
        },
        "/v3/admin/issues/{id}/archive": {
            "post": {
                "tags": [
                    "Admin > Board"
                ],
                "summary": "Take a card off the board (not going to be done); its open reports close without email",
                "operationId": "post_app_admin_apiadminissue_archive",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The card"
                    }
                }
            }
        },
        "/v3/admin/issues/{id}/restore": {
            "post": {
                "tags": [
                    "Admin > Board"
                ],
                "summary": "Put an archived card back on the board, at the bottom of its column",
                "operationId": "post_app_admin_apiadminissue_restore",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The card"
                    }
                }
            }
        },
        "/v3/admin/issues/{id}/merge": {
            "post": {
                "tags": [
                    "Admin > Board"
                ],
                "summary": "Merge a card into another (same thing): its reports move over, it gets archived",
                "operationId": "post_app_admin_apiadminissue_merge",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "into_id": {
                                        "type": "integer"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The card it was merged into"
                    },
                    "400": {
                        "description": "CANNOT_MERGE_INTO_ITSELF"
                    }
                }
            }
        },
        "/v3/admin/issues/{id}/attachments": {
            "post": {
                "tags": [
                    "Admin > Board"
                ],
                "summary": "Attach a file to a card (up to 15 MB, any type; stored privately)",
                "description": "Multipart form with a `file`. Images show as thumbnails and the first one as the card cover; links are signed and expire in an hour.",
                "operationId": "post_app_admin_apiadminissue_attach",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The card"
                    },
                    "400": {
                        "description": "MISSING_FILE | INVALID_FILE | FILE_TOO_LARGE"
                    }
                }
            }
        },
        "/v3/admin/issues/{id}/attachments/{attachmentId}": {
            "delete": {
                "tags": [
                    "Admin > Board"
                ],
                "summary": "Remove an attachment from a card (and from storage)",
                "operationId": "delete_app_admin_apiadminissue_detach",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "name": "attachmentId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The card"
                    },
                    "404": {
                        "description": "ATTACHMENT_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/admin/issues/{id}/comments": {
            "post": {
                "tags": [
                    "Admin > Board"
                ],
                "summary": "Comment on a card (markdown)",
                "operationId": "post_app_admin_apiadminissue_comment",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "body": {
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The card"
                    },
                    "400": {
                        "description": "MISSING_COMMENT"
                    }
                }
            }
        },
        "/v3/analytics/scope": {
            "get": {
                "tags": [
                    "Analytics"
                ],
                "summary": "What the caller can analyse",
                "description": "The stores the caller may filter by and whether they are restricted to them (stores assigned in Settings \u203a Team). Owners and members without stores see the whole organization.",
                "operationId": "get_api_analytics_scope",
                "responses": {
                    "200": {
                        "description": "The scope",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "restricted": {
                                            "type": "boolean"
                                        },
                                        "stores": {
                                            "type": "array",
                                            "items": {
                                                "properties": {
                                                    "id": {
                                                        "type": "integer"
                                                    },
                                                    "name": {
                                                        "type": "string"
                                                    }
                                                },
                                                "type": "object"
                                            }
                                        },
                                        "currency": {
                                            "type": "string"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "INVALID_ROLE"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/analytics/store-performance": {
            "get": {
                "tags": [
                    "Analytics"
                ],
                "summary": "Store Performance",
                "description": "Designs saved for clients, quotes issued, confirmed sales, conversion, average values and their evolution, with the previous period of the same length to compare. Metrics that cannot be measured yet come in `unavailable`.",
                "operationId": "get_api_analytics_store_performance",
                "parameters": [
                    {
                        "name": "from",
                        "in": "query",
                        "description": "Y-m-d, included (default: 29 days before `to`)",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "description": "Y-m-d, included (default: today)",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "granularity",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "day",
                                "week",
                                "month"
                            ]
                        }
                    },
                    {
                        "name": "store_id",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The figures",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "INVALID_DATE | INVALID_PERIOD | PERIOD_TOO_LONG | INVALID_GRANULARITY | GRANULARITY_TOO_FINE"
                    },
                    "403": {
                        "description": "INVALID_ROLE | STORE_NOT_ALLOWED"
                    },
                    "404": {
                        "description": "STORE_NOT_FOUND"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/analytics/team-performance": {
            "get": {
                "tags": [
                    "Analytics"
                ],
                "summary": "Team Performance",
                "description": "One row per seller (the person recorded on each piece and order, taken from their session): designs saved, quotes, confirmed sales, conversion and average sale value. Meant to spot coaching needs, not to track clicks or time online.",
                "operationId": "get_api_analytics_team_performance",
                "parameters": [
                    {
                        "name": "from",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "store_id",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The team",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "INVALID_ROLE | STORE_NOT_ALLOWED"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/analytics/team-performance/{sellerId}": {
            "get": {
                "tags": [
                    "Analytics"
                ],
                "summary": "One seller",
                "description": "The Store Performance figures and evolution of one seller (user id), within the caller's stores.",
                "operationId": "get_api_analytics_seller_performance",
                "parameters": [
                    {
                        "name": "sellerId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "name": "from",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "granularity",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "day",
                                "week",
                                "month"
                            ]
                        }
                    },
                    {
                        "name": "store_id",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The seller",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "SELLER_NOT_FOUND | STORE_NOT_FOUND"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/analytics/design-insights": {
            "get": {
                "tags": [
                    "Analytics"
                ],
                "summary": "Design Insights",
                "description": "What clients choose: families (Solitaire, Halo, Three stone\u2026), piece types, metals, main gems and shapes of the pieces saved, quoted and sold; price ranges per piece; and the catalogue pieces that generate the most quotes and sales.",
                "operationId": "get_api_analytics_design_insights",
                "parameters": [
                    {
                        "name": "from",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "store_id",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The insights",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/assistant/conversations": {
            "get": {
                "tags": [
                    "Assistant"
                ],
                "summary": "The conversations of the current user with the assistant (the ephemeral Showroom ones are not listed)",
                "operationId": "get_app_assistant_apiassistant_list",
                "responses": {
                    "200": {
                        "description": "{conversations: [{id, title, created_at, updated_at, last_context, ephemeral: false}]}"
                    }
                }
            }
        },
        "/v3/assistant/conversations/{id}": {
            "get": {
                "tags": [
                    "Assistant"
                ],
                "summary": "A conversation with all its turns",
                "operationId": "get_app_assistant_apiassistant_get",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "{conversation, messages: [{id, role, content, tool_calls, tool_call_id, tool, arguments, tool_result, status, created_at}], pending: [{call_id, tool, arguments, summary}]}"
                    },
                    "404": {
                        "description": "CONVERSATION_NOT_FOUND"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Assistant"
                ],
                "summary": "Delete a conversation",
                "operationId": "delete_app_assistant_apiassistant_delete",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "{deleted: true}"
                    },
                    "404": {
                        "description": "CONVERSATION_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/assistant/conversations/{id}/messages": {
            "post": {
                "tags": [
                    "Assistant"
                ],
                "summary": "Send a message to the assistant (text/event-stream)",
                "description": "Body: {message, context: {module: showroom|backoffice|settings, screen?, route?, selection?: {type, id}, audience?: staff|client, client?: {id, name}, design?: {capsule_id, values, values_resolved, selected_part, design_id, draft_id, mode: studio|fit}}, title?, kickoff?}. With id \"new\" a conversation is created (titled with `title` or the message) and announced in the first event; opened from the Showroom it is ephemeral (`ephemeral: true`): not listed, and the app deletes it when the counter session ends. `context.design` makes it a Design Studio turn: the assistant gets the piece, the Studio toolset and the UI tools update_record / switch_capsule, streamed as `ui_tool` events for the browser to apply; `kickoff: true` sends the Ettore Fit starting prompt instead of `message`. The reply streams as server-sent events (see the controller doc).",
                "operationId": "post_app_assistant_apiassistant_send",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "new|\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "message": {
                                        "description": "Required unless kickoff is true",
                                        "type": "string"
                                    },
                                    "context": {
                                        "type": "object",
                                        "nullable": true
                                    },
                                    "title": {
                                        "description": "Title of a new conversation (Studio: the piece or capsule name)",
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "kickoff": {
                                        "description": "Ettore Fit: the first turn proposes a starting point without a user message",
                                        "type": "boolean",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "text/event-stream"
                    },
                    "400": {
                        "description": "INVALID_PAYLOAD, MISSING_MESSAGE, OPENROUTER_KEY_MISSING, ASSISTANT_DAILY_LIMIT"
                    },
                    "404": {
                        "description": "CONVERSATION_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/assistant/conversations/{id}/confirm/{callId}": {
            "post": {
                "tags": [
                    "Assistant"
                ],
                "summary": "Approve or cancel a pending tool call (text/event-stream)",
                "description": "Body: {approve: bool}. Approved, the tool runs and the assistant continues; cancelled, the assistant is told \"cancelled by user\" and continues.",
                "operationId": "post_app_assistant_apiassistant_confirm",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "name": "callId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "approve"
                                ],
                                "properties": {
                                    "approve": {
                                        "type": "boolean"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "text/event-stream"
                    },
                    "404": {
                        "description": "CONVERSATION_NOT_FOUND, CONFIRMATION_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/backoffice/account/member": {
            "get": {
                "tags": [
                    "Back Office > Account"
                ],
                "summary": "Get members",
                "description": "Returns all members of the organization",
                "operationId": "get_app_backoffice_apibackofficeaccounts_getmanagementmember",
                "responses": {
                    "200": {
                        "description": "Members retrieved successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/account/member/invite": {
            "post": {
                "tags": [
                    "Back Office > Account"
                ],
                "summary": "Invite member",
                "description": "Invites one or more workmates (form field `data` = JSON {emails: 'a@x,b@y', comment?}). Someone without an account gets Supabase's invitation email and joins on signing in; someone who already has one (a member of other organizations) gets our own email and accepts or declines in the app. Each email gets its own status: sent | resent (was already pending) | already_registered (already in this team) | rate_limited | invalid_email; `result` is true only when every email was sent.",
                "operationId": "post_app_backoffice_apibackofficeaccounts_postdashboardaccountmemberinvite",
                "responses": {
                    "200": {
                        "description": "Member invited successfully"
                    },
                    "400": {
                        "description": "Invalid data"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/account/app": {
            "post": {
                "tags": [
                    "Back Office > Account"
                ],
                "summary": "Select apps for member",
                "description": "Assigns application access to a member",
                "operationId": "post_app_backoffice_apibackofficeaccounts_postownermanagementmemberroles",
                "responses": {
                    "200": {
                        "description": "Apps assigned successfully"
                    },
                    "400": {
                        "description": "Invalid data"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/account/agent": {
            "post": {
                "tags": [
                    "Back Office > Account"
                ],
                "summary": "Select agents for member",
                "description": "Assigns agent access to a member",
                "operationId": "post_app_backoffice_apibackofficeaccounts_postownermanagementmemberagents",
                "responses": {
                    "200": {
                        "description": "Agents assigned successfully"
                    },
                    "400": {
                        "description": "Invalid data"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/account/member/delete": {
            "post": {
                "tags": [
                    "Back Office > Account"
                ],
                "summary": "Delete member",
                "description": "Deletes a user and migrates all files to owner",
                "operationId": "post_app_backoffice_apibackofficeaccounts_postadmindeleteuser",
                "responses": {
                    "200": {
                        "description": "Member deleted successfully"
                    },
                    "400": {
                        "description": "Invalid data"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/assistant/usage": {
            "get": {
                "tags": [
                    "AI Assistant"
                ],
                "summary": "What the assistant has cost the organization",
                "description": "Dollars (OpenRouter usage.cost), user messages and tokens of the last 24 hours and the last 30 days, the 30 days split by surface (showroom, backoffice, settings, backstage, <module>/studio) and by model, and the daily budget (the organization's own or the platform default) with what is spent today.",
                "operationId": "get_app_backoffice_apibackofficeassistant_usage",
                "responses": {
                    "200": {
                        "description": "{today: {cost, messages, prompt_tokens, completion_tokens}, month: {\u2026}, by_surface: [{surface, cost, messages}], by_model: [{model, cost, calls}], budget: {limit, spent_today, is_default}}"
                    }
                }
            }
        },
        "/v3/backoffice/assistant": {
            "get": {
                "tags": [
                    "AI Assistant"
                ],
                "summary": "The AI assistant settings of the organization",
                "description": "Resolved values: what is saved, or the defaults (Ettore, default icon, professional, balanced) when nothing was configured.",
                "operationId": "get_app_backoffice_apibackofficeassistant_get",
                "responses": {
                    "200": {
                        "description": "{display_name, avatar_type, avatar_url, personality, response_length, language, voice_enabled, voice_auto_send, voice_silence_ms}"
                    }
                }
            },
            "post": {
                "tags": [
                    "AI Assistant"
                ],
                "summary": "Save the AI assistant settings",
                "description": "Multipart: `data` (JSON with any of display_name, avatar_type [default|initials|image], personality, response_length, language [auto|en|es|ca|fr|it|de|pt|ru|ja|zhchs|zhcht], voice_enabled, voice_auto_send, voice_silence_ms [1000-6000], remove_avatar) and optionally `avatar` (PNG, JPEG or WebP up to 2 MB). With avatar_type=image an image must exist or come in the request.",
                "operationId": "post_app_backoffice_apibackofficeassistant_save",
                "responses": {
                    "200": {
                        "description": "Settings saved"
                    },
                    "400": {
                        "description": "INVALID_DATA, INVALID_ASSISTANT_NAME, INVALID_AVATAR_TYPE, INVALID_PERSONALITY, INVALID_RESPONSE_LENGTH, INVALID_LANGUAGE, INVALID_VOICE_ENABLED, INVALID_VOICE_AUTO_SEND, AVATAR_REQUIRED, INVALID_AVATAR, AVATAR_TOO_LARGE"
                    }
                }
            }
        },
        "/v3/backoffice/assistant/avatar": {
            "delete": {
                "tags": [
                    "AI Assistant"
                ],
                "summary": "Remove the uploaded avatar image",
                "description": "Deletes the image and goes back to the default icon.",
                "operationId": "delete_app_backoffice_apibackofficeassistant_removeavatar",
                "responses": {
                    "200": {
                        "description": "Settings after the removal"
                    }
                }
            }
        },
        "/v3/backoffice/assistant/speech": {
            "post": {
                "tags": [
                    "AI Assistant"
                ],
                "summary": "Read an assistant reply aloud",
                "description": "JSON {text}: the reply, cleaned for speech (no markdown, engine tokens in words) and capped at 1500 characters, converted with ElevenLabs (eleven_flash_v2_5) and the organization's voice and API key. Returns audio/mpeg.",
                "operationId": "post_app_backoffice_apibackofficeassistantspeech_speech",
                "responses": {
                    "200": {
                        "description": "audio/mpeg"
                    },
                    "400": {
                        "description": "EMPTY_TEXT, ELEVENLABS_API_KEY_MISSING, ELEVENLABS_API_KEY_INVALID, ELEVENLABS_QUOTA_EXCEEDED, ELEVENLABS_NO_VOICES, ELEVENLABS_ERROR"
                    }
                }
            }
        },
        "/v3/backoffice/assistant/voices": {
            "get": {
                "tags": [
                    "AI Assistant"
                ],
                "summary": "The ElevenLabs voices of the organization's account",
                "operationId": "get_app_backoffice_apibackofficeassistantspeech_voices",
                "responses": {
                    "200": {
                        "description": "[{voice_id, name, preview_url, category, labels}]"
                    },
                    "400": {
                        "description": "ELEVENLABS_API_KEY_MISSING, ELEVENLABS_API_KEY_INVALID, ELEVENLABS_ERROR"
                    }
                }
            }
        },
        "/v3/backoffice/bug-report": {
            "post": {
                "tags": [
                    "Back Office > Bug reports"
                ],
                "summary": "Report a bug",
                "description": "Multipart form: `data` is a JSON object with `message` (required), optional `design_id` (the design or draft on screen: a frozen, hidden copy of it is stored with the report) and `context` (whatever the app knew: screen, URL, capsule, record, conversation, selected part\u2026); optional `screenshot` image file (up to 8 MB). Each report becomes a card on the admin's Board.",
                "operationId": "post_app_backoffice_apibackofficebugreport_report",
                "responses": {
                    "200": {
                        "description": "{id}"
                    },
                    "400": {
                        "description": "INVALID_DATA | MISSING_MESSAGE"
                    }
                }
            }
        },
        "/v3/backoffice/camera-view": {
            "get": {
                "tags": [
                    "Camera view"
                ],
                "summary": "List the camera views",
                "operationId": "get_app_backoffice_apibackofficecameraview_list",
                "responses": {
                    "200": {
                        "description": "Camera views in order"
                    }
                }
            },
            "post": {
                "tags": [
                    "Camera view"
                ],
                "summary": "Create a camera view",
                "description": "JSON: `name`, `azimuth` and `polar` (radians, as the viewer orbit gives them), optionally `framing` (distance relative to fitting the piece, 1 = exact) and `role` (main, top, side or null).",
                "operationId": "post_app_backoffice_apibackofficecameraview_create",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "name": {
                                        "type": "string"
                                    },
                                    "azimuth": {
                                        "type": "number"
                                    },
                                    "polar": {
                                        "type": "number"
                                    },
                                    "framing": {
                                        "type": "number"
                                    },
                                    "role": {
                                        "type": "string",
                                        "nullable": true,
                                        "enum": [
                                            "main",
                                            "top",
                                            "side"
                                        ]
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Camera view created"
                    },
                    "400": {
                        "description": "INVALID_CAMERA_VIEW, INVALID_CAMERA_VIEW_NAME, INVALID_CAMERA_VIEW_ROLE, TOO_MANY_CAMERA_VIEWS"
                    }
                }
            }
        },
        "/v3/backoffice/camera-view/{id}": {
            "put": {
                "tags": [
                    "Camera view"
                ],
                "summary": "Update a camera view",
                "description": "JSON with any of `name`, `azimuth`, `polar`, `framing`, `role`. Giving a role takes it from the view that had it.",
                "operationId": "put_app_backoffice_apibackofficecameraview_update",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Camera view updated"
                    },
                    "404": {
                        "description": "INVALID_CAMERA_VIEW_ID"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Camera view"
                ],
                "summary": "Delete a camera view",
                "operationId": "delete_app_backoffice_apibackofficecameraview_delete",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "{ok: true}"
                    },
                    "404": {
                        "description": "INVALID_CAMERA_VIEW_ID"
                    }
                }
            }
        },
        "/v3/backoffice/camera-view/order": {
            "put": {
                "tags": [
                    "Camera view"
                ],
                "summary": "Reorder the camera views",
                "operationId": "put_app_backoffice_apibackofficecameraview_order",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "orderedIds": {
                                        "description": "Every camera view id of the organization, in the new order",
                                        "type": "array",
                                        "items": {
                                            "type": "integer"
                                        }
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Camera views in the new order"
                    },
                    "400": {
                        "description": "INVALID_DATA"
                    }
                }
            }
        },
        "/v3/backoffice/capsule": {
            "get": {
                "tags": [
                    "Knowledge Capsule"
                ],
                "summary": "Get all capsules",
                "description": "Returns every capsule of the organization, newest first. The schema and the configuration schema are omitted from the list; use the detail endpoint for those.",
                "operationId": "get_app_backoffice_apibackofficecapsule_getcapsules",
                "responses": {
                    "200": {
                        "description": "Knowledge Capsules retrieved successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            },
            "post": {
                "tags": [
                    "Knowledge Capsule"
                ],
                "summary": "Create a capsule",
                "description": "Creates a capsule in the organization. The .gh file is uploaded separately once the capsule exists.",
                "operationId": "post_app_backoffice_apibackofficecapsule_postcapsule",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "name"
                                ],
                                "properties": {
                                    "name": {
                                        "type": "string"
                                    },
                                    "description": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "schema": {
                                        "type": "object",
                                        "nullable": true
                                    },
                                    "configuration_schema": {
                                        "type": "object",
                                        "nullable": true
                                    },
                                    "manufacturing_standards": {
                                        "description": "Production rules of this capsule, on top of the manufacturer's (6,000 characters at most)",
                                        "type": "string",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Knowledge Capsule created successfully"
                    },
                    "400": {
                        "description": "INVALID_PAYLOAD, MISSING_NAME, CAPSULE_NAME_ALREADY_EXISTS, INVALID_SCHEMA or INVALID_CONFIGURATION_SCHEMA"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/capsule/{id}": {
            "get": {
                "tags": [
                    "Knowledge Capsule"
                ],
                "summary": "Get one capsule",
                "description": "Returns a capsule of the organization with its schema and configuration schema.",
                "operationId": "get_app_backoffice_apibackofficecapsule_getcapsule",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Knowledge Capsule retrieved successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "CAPSULE_NOT_FOUND"
                    }
                }
            },
            "post": {
                "tags": [
                    "Knowledge Capsule"
                ],
                "summary": "Update a capsule",
                "description": "Partial update: only the fields present in the body change. Send schema or configuration_schema as null to clear them.",
                "operationId": "post_app_backoffice_apibackofficecapsule_postcapsuleupdate",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "name": {
                                        "type": "string"
                                    },
                                    "uuid": {
                                        "description": "Stable id kept when importing a capsule exported from another account; unique per organization",
                                        "type": "string",
                                        "format": "uuid"
                                    },
                                    "description": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "status": {
                                        "description": "0 draft, 1 ready, 2 published",
                                        "type": "integer"
                                    },
                                    "tags": {
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        },
                                        "nullable": true
                                    },
                                    "schema": {
                                        "type": "object",
                                        "nullable": true
                                    },
                                    "configuration_schema": {
                                        "type": "object",
                                        "nullable": true
                                    },
                                    "manufacturing_standards": {
                                        "description": "Production rules of this capsule, on top of the manufacturer's (6,000 characters at most)",
                                        "type": "string",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Knowledge Capsule updated successfully"
                    },
                    "400": {
                        "description": "INVALID_PAYLOAD, MISSING_NAME, CAPSULE_NAME_ALREADY_EXISTS, INVALID_UUID, CAPSULE_UUID_ALREADY_EXISTS, INVALID_STATUS, INVALID_TAGS, INVALID_SCHEMA or INVALID_CONFIGURATION_SCHEMA"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "CAPSULE_NOT_FOUND"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Knowledge Capsule"
                ],
                "summary": "Delete a capsule",
                "description": "Deletes the capsule and its .gh file.",
                "operationId": "delete_app_backoffice_apibackofficecapsule_deletecapsule",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Knowledge Capsule deleted successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "CAPSULE_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/backoffice/capsule/{id}/gh": {
            "get": {
                "tags": [
                    "Knowledge Capsule"
                ],
                "summary": "Get a download link for the .gh file",
                "description": "Returns a signed URL valid for 15 minutes. The file is never public, so this is the only way to fetch it.",
                "operationId": "get_app_backoffice_apibackofficecapsule_getcapsulegh",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Signed URL generated"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "CAPSULE_NOT_FOUND or GH_FILE_NOT_FOUND"
                    }
                }
            },
            "post": {
                "tags": [
                    "Knowledge Capsule"
                ],
                "summary": "Upload the .gh file of a capsule",
                "description": "Multipart upload of the Grasshopper definition (field \"file\", .gh or .ghx, up to 25 MB). Replaces the previous one. The object is stored privately and is never served by public URL.",
                "operationId": "post_app_backoffice_apibackofficecapsule_postcapsulegh",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "required": [
                                    "file"
                                ],
                                "properties": {
                                    "file": {
                                        "type": "string",
                                        "format": "binary"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "File uploaded successfully"
                    },
                    "400": {
                        "description": "FILE_REQUIRED, INVALID_GH_FORMAT, EMPTY_FILE, FILE_TOO_LARGE or UNREADABLE_FILE"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "CAPSULE_NOT_FOUND"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Knowledge Capsule"
                ],
                "summary": "Remove the .gh file of a capsule",
                "description": "Deletes the Grasshopper definition and clears its metadata. The capsule itself is kept.",
                "operationId": "delete_app_backoffice_apibackofficecapsule_deletecapsulegh",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "File removed successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "CAPSULE_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/backoffice/capsule/{id}/gh-defaults": {
            "post": {
                "tags": [
                    "Knowledge Capsule"
                ],
                "summary": "Compute what the capsule's .gh gives with no input",
                "description": "Runs the .gh with an empty record: no start values and no fixed values of the capsule. Returns the resolved values (schema keys only) and the gh_hash they belong to. Nothing is stored here: the controls editor keeps them in the capsule UI (`defaults`). Served from the compute cache while the .gh does not change.",
                "operationId": "post_app_backoffice_apibackofficecapsule_postcapsuleghdefaults",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "{gh_hash, values}"
                    },
                    "400": {
                        "description": "CAPSULE_HAS_NO_DEFINITION"
                    },
                    "404": {
                        "description": "CAPSULE_NOT_FOUND"
                    },
                    "502": {
                        "description": "{error}: the engine failed"
                    }
                }
            }
        },
        "/v3/backoffice/catalogue": {
            "get": {
                "tags": [
                    "Catalogue"
                ],
                "summary": "Collections offered by the catalogue organization and by the vendors that give access to this one",
                "operationId": "get_app_backoffice_apibackofficecatalogue_list",
                "responses": {
                    "200": {
                        "description": "{sources: [{organization, source: standard|vendor, collections: [{id, name, description, square_image, design_count, installed}]}], organization, own, collections} (the last three: the catalogue, as before)"
                    }
                }
            }
        },
        "/v3/backoffice/catalogue/collections": {
            "get": {
                "tags": [
                    "Catalogue"
                ],
                "summary": "Collections brought from the catalogue or a vendor, and what changed in their original",
                "operationId": "get_app_backoffice_apibackofficecatalogue_collectionupdates",
                "responses": {
                    "200": {
                        "description": "{collections: {id: {state: update|current, source: standard|vendor, organization, source_collection_id, new, changed, removed}}}"
                    }
                }
            }
        },
        "/v3/backoffice/catalogue/collections/{id}/update": {
            "post": {
                "tags": [
                    "Catalogue"
                ],
                "summary": "Bring a collection up to date with its original: changed designs updated, removed ones taken out (new ones: then /install with source_collection_id and source_id)",
                "operationId": "post_app_backoffice_apibackofficecatalogue_updatecollection",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "{updated, removed, new, source_id, source, source_collection_id}"
                    },
                    "404": {
                        "description": "COLLECTION_NOT_FOUND | COLLECTION_HAS_NO_SOURCE"
                    }
                }
            }
        },
        "/v3/backoffice/catalogue/capsules": {
            "get": {
                "tags": [
                    "Catalogue"
                ],
                "summary": "The organization's capsules against the catalogue: which are up to date, and which catalogue capsules it does not have yet",
                "operationId": "get_app_backoffice_apibackofficecatalogue_capsules",
                "responses": {
                    "200": {
                        "description": "{capsules: {capsule id: {state: current|update, catalogue_gh_uploaded_at}}, new: [{uuid, name, description, tags, status, has_gh, gh_filename, gh_size, gh_uploaded_at, has_schema, has_configuration_schema, updated_at}]}"
                    }
                }
            }
        },
        "/v3/backoffice/catalogue/capsules/update": {
            "post": {
                "tags": [
                    "Catalogue"
                ],
                "summary": "Bring capsules up to date with the catalogue (.gh and schemas)",
                "operationId": "post_app_backoffice_apibackofficecatalogue_updatecapsules",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "capsule_ids": {
                                        "description": "Default: every capsule with an update",
                                        "type": "array",
                                        "items": {
                                            "type": "integer"
                                        }
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "{updated, capsules: {id: state}, new: [...]}"
                    }
                }
            }
        },
        "/v3/backoffice/catalogue/capsules/add": {
            "post": {
                "tags": [
                    "Catalogue"
                ],
                "summary": "Bring catalogue capsules the organization does not have yet (.gh and schemas)",
                "operationId": "post_app_backoffice_apibackofficecatalogue_addcapsules",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "uuids": {
                                        "description": "Default: every capsule the organization does not have",
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        }
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "{added, capsules: {id: state}, new: [...]}"
                    }
                }
            }
        },
        "/v3/backoffice/catalogue/photo-styles": {
            "get": {
                "tags": [
                    "Catalogue"
                ],
                "summary": "Photo styles of the catalogue, to add them",
                "operationId": "get_app_backoffice_apibackofficecatalogue_photostyles",
                "responses": {
                    "200": {
                        "description": "{organization, has_falai_api_key, styles: [{name, image, model, installed}]}"
                    }
                }
            }
        },
        "/v3/backoffice/catalogue/photo-styles/install": {
            "post": {
                "tags": [
                    "Catalogue"
                ],
                "summary": "Add photo styles of the catalogue to the organization",
                "operationId": "post_app_backoffice_apibackofficecatalogue_installphotostyles",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "names": {
                                        "description": "Default: every style the organization does not have",
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        }
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "{added}"
                    }
                }
            }
        },
        "/v3/backoffice/catalogue/viewer-settings": {
            "get": {
                "tags": [
                    "Catalogue"
                ],
                "summary": "Viewer scenes and camera views of the catalogue, to add them",
                "operationId": "get_app_backoffice_apibackofficecatalogue_viewersettings",
                "responses": {
                    "200": {
                        "description": "{organization, scenes: [{name, thumbnail, settings, studio, installed}], camera_views: [{name, azimuth, polar, framing, role, installed}]}"
                    }
                }
            }
        },
        "/v3/backoffice/catalogue/viewer-settings/install": {
            "post": {
                "tags": [
                    "Catalogue"
                ],
                "summary": "Add viewer scenes and camera views of the catalogue to the organization",
                "description": "What the organization already has with the same name is left alone. A camera view keeps its role only if no view of the organization has it.",
                "operationId": "post_app_backoffice_apibackofficecatalogue_installviewersettings",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "scenes": {
                                        "description": "Scene names; default: every scene the organization does not have",
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        }
                                    },
                                    "camera_views": {
                                        "description": "Camera view names; default: every view the organization does not have",
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        }
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "{scenes, camera_views}: how many were added"
                    }
                }
            }
        },
        "/v3/backoffice/catalogue/install": {
            "post": {
                "tags": [
                    "Catalogue"
                ],
                "summary": "Bring one batch of catalogue collections into the organization",
                "operationId": "post_app_backoffice_apibackofficecatalogue_install",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "collection_ids": {
                                        "type": "array",
                                        "items": {
                                            "type": "integer"
                                        }
                                    },
                                    "source_id": {
                                        "description": "Organization the collections come from: the catalogue (default) or a vendor that gives access to this one",
                                        "type": "integer"
                                    },
                                    "offset": {
                                        "type": "integer"
                                    },
                                    "limit": {
                                        "type": "integer"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "{total, offset, next_offset, created, existing, failed, warnings}"
                    }
                }
            }
        },
        "/v3/backoffice/collection": {
            "get": {
                "tags": [
                    "Collection"
                ],
                "summary": "Get all collections",
                "description": "Returns all collections for the organization",
                "operationId": "get_app_backoffice_apibackofficecollection_getcollections",
                "responses": {
                    "200": {
                        "description": "Collections retrieved successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            },
            "post": {
                "tags": [
                    "Collection"
                ],
                "summary": "Create new collection",
                "description": "Creates a new collection with square and video files",
                "operationId": "post_app_backoffice_apibackofficecollection_postnewcollection",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "properties": {
                                    "data": {
                                        "description": "JSON data",
                                        "type": "string"
                                    },
                                    "square": {
                                        "type": "string",
                                        "format": "binary"
                                    },
                                    "video": {
                                        "type": "string",
                                        "format": "binary"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Collection created successfully"
                    },
                    "400": {
                        "description": "Invalid data"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/collection/order": {
            "put": {
                "tags": [
                    "Collection"
                ],
                "summary": "Reorder collections",
                "description": "Bulk-assigns sortOrder to collections based on the provided array of IDs (0-based index).",
                "operationId": "put_app_backoffice_apibackofficecollection_putcollectionsorder",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "orderedIds"
                                ],
                                "properties": {
                                    "orderedIds": {
                                        "description": "Full ordered list of collection IDs",
                                        "type": "array",
                                        "items": {
                                            "type": "integer"
                                        }
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Collections reordered successfully"
                    },
                    "400": {
                        "description": "Invalid data"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied - some IDs do not belong to the organization"
                    }
                }
            }
        },
        "/v3/backoffice/collection/design-options": {
            "get": {
                "operationId": "get_app_backoffice_apibackofficecollection_getcollectiondesignoptions",
                "responses": {
                    "default": {
                        "description": ""
                    }
                }
            }
        },
        "/v3/backoffice/collection/{id}": {
            "get": {
                "tags": [
                    "Collection"
                ],
                "summary": "Get collection by ID",
                "description": "Returns a collection by its ID",
                "operationId": "get_app_backoffice_apibackofficecollection_getcollectionbyid",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Collection retrieved successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Collection not found"
                    }
                }
            },
            "post": {
                "tags": [
                    "Collection"
                ],
                "summary": "Edit collection",
                "description": "Updates an existing collection",
                "operationId": "post_app_backoffice_apibackofficecollection_posteditcollection",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "properties": {
                                    "data": {
                                        "description": "JSON data",
                                        "type": "string"
                                    },
                                    "square": {
                                        "type": "string",
                                        "format": "binary"
                                    },
                                    "video": {
                                        "type": "string",
                                        "format": "binary"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Collection updated successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Collection not found"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Collection"
                ],
                "summary": "Delete collection",
                "description": "Deletes a collection by its ID",
                "operationId": "delete_app_backoffice_apibackofficecollection_deletecollection",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Collection deleted successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Collection not found"
                    }
                }
            }
        },
        "/v3/backoffice/collection/{id}/designs": {
            "put": {
                "operationId": "put_app_backoffice_apibackofficecollection_putcollectiondesigns",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "default": {
                        "description": ""
                    }
                }
            }
        },
        "/v3/backoffice/collection/duplicate": {
            "post": {
                "tags": [
                    "Collection"
                ],
                "summary": "Duplicate collection",
                "description": "Creates a duplicate of an existing collection",
                "operationId": "post_app_backoffice_apibackofficecollection_postduplicatecollection",
                "responses": {
                    "201": {
                        "description": "Collection duplicated successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Collection not found"
                    }
                }
            }
        },
        "/v3/backoffice/design": {
            "get": {
                "tags": [
                    "Design"
                ],
                "summary": "List designs",
                "description": "Returns every saved design in the caller's organization, newest first. Drafts (solves not yet saved) are not included.",
                "operationId": "get_app_backoffice_apibackofficedesign_getdesigns",
                "responses": {
                    "200": {
                        "description": "Designs retrieved successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            },
            "post": {
                "tags": [
                    "Design"
                ],
                "summary": "Save a design",
                "description": "Two ways in: `draft_id` promotes a draft made by /v3/compute/solve (fast), or `capsule_id` + `values` computes and saves in one go (slow). Optionally assigns collections.",
                "operationId": "post_app_backoffice_apibackofficedesign_postdesign",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "name"
                                ],
                                "properties": {
                                    "name": {
                                        "type": "string"
                                    },
                                    "draft_id": {
                                        "description": "Id returned by /v3/compute/solve.",
                                        "type": "integer"
                                    },
                                    "capsule_id": {
                                        "description": "Knowledge Capsule of the organization whose .gh builds the piece.",
                                        "type": "integer"
                                    },
                                    "values": {
                                        "description": "The record: a flat object keyed by the Knowledge Capsule's schema (dotted names).",
                                        "type": "object"
                                    },
                                    "mode": {
                                        "type": "string",
                                        "default": "rendering",
                                        "enum": [
                                            "rendering",
                                            "manufacturing"
                                        ]
                                    },
                                    "description": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "collection_ids": {
                                        "type": "array",
                                        "items": {
                                            "type": "integer"
                                        }
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Design saved"
                    },
                    "400": {
                        "description": "MISSING_NAME | MISSING_DRAFT_OR_CAPSULE | INVALID_VALUES | CAPSULE_HAS_NO_DEFINITION"
                    },
                    "404": {
                        "description": "DRAFT_NOT_FOUND | CAPSULE_NOT_FOUND"
                    },
                    "502": {
                        "description": "Compute failed"
                    }
                }
            }
        },
        "/v3/backoffice/design/{id}": {
            "get": {
                "tags": [
                    "Design"
                ],
                "summary": "Get a design",
                "description": "Returns the design with its values, compute result (GLB/STL URLs, tech) and collections. Drafts are readable too, so a studio can reopen a solve it just made.",
                "operationId": "get_app_backoffice_apibackofficedesign_getdesign",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Design retrieved successfully"
                    },
                    "404": {
                        "description": "DESIGN_NOT_FOUND"
                    }
                }
            },
            "put": {
                "tags": [
                    "Design"
                ],
                "summary": "Update a design",
                "description": "Updates name, description, the semantic sentence and/or the full list of collections. `draft_id` replaces the geometry with a newer solve (the draft is consumed). Only the provided fields change.",
                "operationId": "put_app_backoffice_apibackofficedesign_putdesign",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "name": {
                                        "type": "string"
                                    },
                                    "description": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "semantic": {
                                        "description": "The piece in one sentence; the engine writes it on compute, Merchandising can polish it.",
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "draft_id": {
                                        "description": "A draft from /v3/compute/solve whose compute result replaces this design's.",
                                        "type": "integer"
                                    },
                                    "collection_ids": {
                                        "type": "array",
                                        "items": {
                                            "type": "integer"
                                        }
                                    },
                                    "notes": {
                                        "description": "Internal retailer notes (max 5000), stored with the author and date. Empty or null removes them. Never sent to the Showroom.",
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "badge": {
                                        "description": "Merchandising label over the photo: new, bestseller, essential, limited or free text (max 30). Empty or null removes it.",
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "display_name": {
                                        "description": "The name the store's customer sees (max 80). Empty or null: the store shows `name`.",
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "reference": {
                                        "description": "The store reference (SKU, max 40), unique in the organization: 409 REFERENCE_TAKEN when another design has it. Empty or null removes it.",
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "tags": {
                                        "description": "The retailer's own words for the piece (vintage, gift, everyday\u2026), found by the showroom search. Up to 20, 30 characters each, trimmed and deduplicated; the full list replaces the previous one.",
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        }
                                    },
                                    "design_type": {
                                        "description": "Piece type, a RhinoArtisan Outliner code (RING, EARRING, PENDANT, NECKLACE, BRACELET, COMPONENT). null clears it (and the subtype).",
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "design_subtype": {
                                        "description": "Subtype, one of the type's (RING_SOLITAIRE_BASKET, ETERNITY_BAND, WEDDING_BAND_DIAMOND...). Without design_type it keeps the current type, or takes the subtype's.",
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "pricing": {
                                        "description": "Edit the stored setting price by hand: `cost` (manufacturer) and `markup_percentage`, optionally `currency`. null clears it.",
                                        "properties": {
                                            "cost": {
                                                "type": "number"
                                            },
                                            "markup_percentage": {
                                                "type": "number"
                                            },
                                            "currency": {
                                                "type": "string"
                                            }
                                        },
                                        "type": "object",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Design updated"
                    },
                    "404": {
                        "description": "DESIGN_NOT_FOUND | DRAFT_NOT_FOUND"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Design"
                ],
                "summary": "Delete a design",
                "description": "Deletes the design and its files in storage.",
                "operationId": "delete_app_backoffice_apibackofficedesign_deletedesign",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Design deleted successfully"
                    },
                    "404": {
                        "description": "DESIGN_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/backoffice/design/{id}/compute": {
            "post": {
                "tags": [
                    "Design"
                ],
                "summary": "Recompute a design",
                "description": "Runs the engine again with the design's Knowledge Capsule, mode and values (or a new `values` from the body), replacing GLB/STL and tech in place. Previews are kept.",
                "operationId": "post_app_backoffice_apibackofficedesign_computedesign",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "values": {
                                        "type": "object"
                                    },
                                    "mode": {
                                        "type": "string",
                                        "enum": [
                                            "rendering",
                                            "manufacturing"
                                        ]
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Design recomputed"
                    },
                    "404": {
                        "description": "DESIGN_NOT_FOUND"
                    },
                    "502": {
                        "description": "Compute failed; the design is left as failed"
                    }
                }
            }
        },
        "/v3/backoffice/design/{id}/preview": {
            "post": {
                "tags": [
                    "Design"
                ],
                "summary": "Upload the design preview",
                "description": "Stores the image captured from the viewer as the design's preview and returns the updated design. Replacing a preview deletes the previous file. Works on drafts too.",
                "operationId": "post_app_backoffice_apibackofficedesign_postdesignpreview",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "properties": {
                                    "preview": {
                                        "type": "string",
                                        "format": "binary"
                                    },
                                    "kind": {
                                        "type": "string",
                                        "default": "main",
                                        "enum": [
                                            "main",
                                            "top",
                                            "side"
                                        ]
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Preview stored"
                    },
                    "400": {
                        "description": "MISSING_PREVIEW | INVALID_KIND"
                    },
                    "404": {
                        "description": "DESIGN_NOT_FOUND"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Design"
                ],
                "summary": "Delete the design previews",
                "description": "Removes one render (kind main, top or side) or all of them (kind all, the default) and deletes their files. Returns the updated design.",
                "operationId": "delete_app_backoffice_apibackofficedesign_deletedesignpreview",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "name": "kind",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "default": "all",
                            "enum": [
                                "all",
                                "main",
                                "top",
                                "side"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Previews deleted"
                    },
                    "400": {
                        "description": "INVALID_KIND"
                    },
                    "404": {
                        "description": "DESIGN_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/backoffice/design/{id}/description/generate": {
            "post": {
                "tags": [
                    "Design"
                ],
                "summary": "Write the store name and the customer description with AI",
                "description": "The organization's LLM (OpenRouter key; the internal agent's model) writes the design's store name and catalogue description for the store's customer, in English, from its record, its TECH and its capsule, with no prices, sizes or internal codes; the name is not one the capsule's other designs already use. It replaces `display_name` and `description` and returns the design.",
                "operationId": "post_app_backoffice_apibackofficedesign_generatedescription",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The design with its new `description`"
                    },
                    "400": {
                        "description": "OPENROUTER_KEY_MISSING"
                    },
                    "404": {
                        "description": "DESIGN_NOT_FOUND"
                    },
                    "502": {
                        "description": "DESCRIPTION_FAILED (the model gave no text)"
                    }
                }
            }
        },
        "/v3/backoffice/design/{id}/pricing/refresh": {
            "post": {
                "tags": [
                    "Design"
                ],
                "summary": "Refresh the stored setting price",
                "description": "Recomputes the setting price (metal, melee, setting and processes; no certified centre stone) with the organization's manufacturer and the active markup's onlySettingMarkup, and stores it on the design with today's date. Nothing is computed on read.",
                "operationId": "post_app_backoffice_apibackofficedesign_refreshpricing",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The design with its new `pricing`"
                    },
                    "400": {
                        "description": "PRICING_UNAVAILABLE (no manufacturer or no computed geometry)"
                    },
                    "404": {
                        "description": "DESIGN_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/backoffice/design/{id}/duplicate": {
            "post": {
                "tags": [
                    "Design"
                ],
                "summary": "Duplicate a design",
                "description": "Creates a copy in the same organization without recomputing: the row and its files (GLB, STL, previews) are copied. Optional `name` in the JSON body; defaults to 'Copy of \u2026'.",
                "operationId": "post_app_backoffice_apibackofficedesign_duplicatedesign",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The new design"
                    },
                    "404": {
                        "description": "DESIGN_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/backoffice/design-standards": {
            "get": {
                "tags": [
                    "Design standards"
                ],
                "summary": "The design standards of the organization",
                "operationId": "get_app_backoffice_apibackofficedesignstandards_get",
                "responses": {
                    "200": {
                        "description": "{design_standards: string|null, max_length: int}"
                    }
                }
            },
            "post": {
                "tags": [
                    "Design standards"
                ],
                "summary": "Save the design standards",
                "description": "JSON body {design_standards}: plain text (Markdown), at most 6,000 characters; empty or null removes them.",
                "operationId": "post_app_backoffice_apibackofficedesignstandards_save",
                "responses": {
                    "200": {
                        "description": "Standards saved"
                    },
                    "400": {
                        "description": "INVALID_DATA, INVALID_DESIGN_STANDARDS, DESIGN_STANDARDS_TOO_LONG"
                    }
                }
            }
        },
        "/v3/backoffice/diamond/certified/{groupId}": {
            "get": {
                "tags": [
                    "Diamond > Certified"
                ],
                "summary": "Get certified diamonds by group",
                "description": "Returns all certified diamonds belonging to a diamond center",
                "operationId": "get_app_backoffice_apibackofficediamondcertified_getdiamondcertified",
                "parameters": [
                    {
                        "name": "groupId",
                        "in": "path",
                        "description": "Diamond center ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "List of certified diamonds"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            },
            "post": {
                "tags": [
                    "Diamond > Certified"
                ],
                "summary": "Create a certified diamond",
                "description": "Creates a new certified diamond in the specified diamond center. Accepts images and certificate files.",
                "operationId": "post_app_backoffice_apibackofficediamondcertified_postdiamond",
                "parameters": [
                    {
                        "name": "groupId",
                        "in": "path",
                        "description": "Diamond center ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Diamond created successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Diamond > Certified"
                ],
                "summary": "Delete all certified diamonds",
                "description": "Deletes all certified diamonds belonging to a diamond center",
                "operationId": "delete_app_backoffice_apibackofficediamondcertified_deletealldiamond",
                "parameters": [
                    {
                        "name": "groupId",
                        "in": "path",
                        "description": "Diamond center ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "All diamonds deleted successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/diamond/certified/{groupId}/{id}": {
            "get": {
                "tags": [
                    "Diamond > Certified"
                ],
                "summary": "Get a certified diamond by ID",
                "description": "Returns a single certified diamond by group and diamond ID",
                "operationId": "get_app_backoffice_apibackofficediamondcertified_getdiamondbyid",
                "parameters": [
                    {
                        "name": "groupId",
                        "in": "path",
                        "description": "Diamond center ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Diamond ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Diamond found"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Diamond not found"
                    }
                }
            },
            "post": {
                "tags": [
                    "Diamond > Certified"
                ],
                "summary": "Edit a certified diamond",
                "description": "Updates an existing certified diamond. Accepts images, certificate, daylight, plotting and dimension files.",
                "operationId": "post_app_backoffice_apibackofficediamondcertified_posteditdiamond",
                "parameters": [
                    {
                        "name": "groupId",
                        "in": "path",
                        "description": "Diamond center ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Diamond ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Diamond updated successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Diamond not found"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Diamond > Certified"
                ],
                "summary": "Delete a certified diamond",
                "description": "Deletes a single certified diamond by ID",
                "operationId": "delete_app_backoffice_apibackofficediamondcertified_deletediamond",
                "parameters": [
                    {
                        "name": "groupId",
                        "in": "path",
                        "description": "Diamond center ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Diamond ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Diamond deleted successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Diamond not found"
                    }
                }
            }
        },
        "/v3/backoffice/diamond/certified/{groupId}/{id}/{imageId}": {
            "delete": {
                "tags": [
                    "Diamond > Certified"
                ],
                "summary": "Delete a diamond image or certificate",
                "description": "Deletes a specific image or certificate file attached to a certified diamond",
                "operationId": "delete_app_backoffice_apibackofficediamondcertified_deletediamondimage",
                "parameters": [
                    {
                        "name": "groupId",
                        "in": "path",
                        "description": "Diamond center ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Diamond ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "imageId",
                        "in": "path",
                        "description": "Image or certificate ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Image deleted successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Image not found"
                    }
                }
            }
        },
        "/v3/backoffice/diamond/gemstone/{groupId}": {
            "get": {
                "tags": [
                    "Diamond > Gemstones"
                ],
                "summary": "Get gemstones by group",
                "description": "Returns all gemstones belonging to a diamond center",
                "operationId": "get_app_backoffice_apibackofficediamondgemstone_getgemstock",
                "parameters": [
                    {
                        "name": "groupId",
                        "in": "path",
                        "description": "Diamond center ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "List of gemstones"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            },
            "post": {
                "tags": [
                    "Diamond > Gemstones"
                ],
                "summary": "Create a gemstone",
                "description": "Creates a new gemstone in the specified diamond center. Accepts images and certificate files.",
                "operationId": "post_app_backoffice_apibackofficediamondgemstone_postgem",
                "parameters": [
                    {
                        "name": "groupId",
                        "in": "path",
                        "description": "Diamond center ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Gemstone created successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Diamond > Gemstones"
                ],
                "summary": "Delete all gemstones",
                "description": "Deletes all gemstones belonging to a diamond center",
                "operationId": "delete_app_backoffice_apibackofficediamondgemstone_deleteallgem",
                "parameters": [
                    {
                        "name": "groupId",
                        "in": "path",
                        "description": "Diamond center ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "All gemstones deleted successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/diamond/gemstone/{groupId}/{id}": {
            "get": {
                "tags": [
                    "Diamond > Gemstones"
                ],
                "summary": "Get a gemstone by ID",
                "description": "Returns a single gemstone by group and gemstone ID",
                "operationId": "get_app_backoffice_apibackofficediamondgemstone_getgembyid",
                "parameters": [
                    {
                        "name": "groupId",
                        "in": "path",
                        "description": "Diamond center ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Gemstone ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Gemstone found"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Gemstone not found"
                    }
                }
            },
            "post": {
                "tags": [
                    "Diamond > Gemstones"
                ],
                "summary": "Edit a gemstone",
                "description": "Updates an existing gemstone. Accepts images and certificate files.",
                "operationId": "post_app_backoffice_apibackofficediamondgemstone_posteditgem",
                "parameters": [
                    {
                        "name": "groupId",
                        "in": "path",
                        "description": "Diamond center ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Gemstone ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Gemstone updated successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Gemstone not found"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Diamond > Gemstones"
                ],
                "summary": "Delete a gemstone",
                "description": "Deletes a single gemstone by ID",
                "operationId": "delete_app_backoffice_apibackofficediamondgemstone_deletegem",
                "parameters": [
                    {
                        "name": "groupId",
                        "in": "path",
                        "description": "Diamond center ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Gemstone ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Gemstone deleted successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Gemstone not found"
                    }
                }
            }
        },
        "/v3/backoffice/diamond/gemstone/{groupId}/{id}/{imageId}": {
            "delete": {
                "tags": [
                    "Diamond > Gemstones"
                ],
                "summary": "Delete a gemstone image or certificate",
                "description": "Deletes a specific image or certificate file attached to a gemstone",
                "operationId": "delete_app_backoffice_apibackofficediamondgemstone_deletediamondimage",
                "parameters": [
                    {
                        "name": "groupId",
                        "in": "path",
                        "description": "Diamond center ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Gemstone ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "imageId",
                        "in": "path",
                        "description": "Image or certificate ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Image deleted successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Image not found"
                    }
                }
            }
        },
        "/v3/backoffice/diamond/group": {
            "get": {
                "operationId": "get_app_backoffice_apibackofficediamondgroup_getdiamondgroups",
                "responses": {
                    "default": {
                        "description": ""
                    }
                }
            },
            "post": {
                "tags": [
                    "Diamond > Group"
                ],
                "summary": "Create a diamond group",
                "description": "Creates a new diamond group for the organization",
                "operationId": "post_app_backoffice_apibackofficediamondgroup_postdiamondgroupcreate",
                "responses": {
                    "201": {
                        "description": "Diamond group created successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/diamond/group/duplicate": {
            "post": {
                "tags": [
                    "Diamond > Group"
                ],
                "summary": "Duplicate a diamond group",
                "description": "Creates a duplicate of an existing diamond group",
                "operationId": "post_app_backoffice_apibackofficediamondgroup_postdiamondgroupduplicate",
                "responses": {
                    "201": {
                        "description": "Diamond group duplicated successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/diamond/group/deactivate": {
            "post": {
                "tags": [
                    "Diamond > Group"
                ],
                "summary": "Deactivate a diamond group",
                "description": "Deactivates an existing diamond group",
                "operationId": "post_app_backoffice_apibackofficediamondgroup_postdiamondgroupdeactivate",
                "responses": {
                    "201": {
                        "description": "Diamond group deactivated successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/diamond/group/activate": {
            "post": {
                "tags": [
                    "Diamond > Group"
                ],
                "summary": "Activate a diamond group",
                "description": "Activates an existing diamond group",
                "operationId": "post_app_backoffice_apibackofficediamondgroup_postdiamondgroupactivate",
                "responses": {
                    "200": {
                        "description": "Diamond group activated successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/diamond/group/{id}": {
            "get": {
                "tags": [
                    "Diamond > Group"
                ],
                "summary": "Get a diamond group by ID",
                "description": "Returns a specific diamond group by its ID",
                "operationId": "get_app_backoffice_apibackofficediamondgroup_getdiamondgroupbyid",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Diamond group ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Diamond group found"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Diamond group not found"
                    }
                }
            },
            "post": {
                "tags": [
                    "Diamond > Group"
                ],
                "summary": "Edit a diamond group",
                "description": "Updates an existing diamond group by ID",
                "operationId": "post_app_backoffice_apibackofficediamondgroup_posteditpost",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Diamond group ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Diamond group updated successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Diamond group not found"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Diamond > Group"
                ],
                "summary": "Delete a diamond group",
                "description": "Deletes a diamond group by ID",
                "operationId": "delete_app_backoffice_apibackofficediamondgroup_deletediamondgroup",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Diamond group ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Diamond group deleted successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Diamond group not found"
                    }
                }
            }
        },
        "/v3/backoffice/diamond/group/order": {
            "put": {
                "tags": [
                    "Diamond group"
                ],
                "summary": "Reorder diamond groups",
                "description": "Saves the order of the Pricing list. Send every id of the organization in the new order.",
                "operationId": "put_app_backoffice_apibackofficediamondgroup_putorder",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "orderedIds": {
                                        "description": "Full ordered list of IDs",
                                        "type": "array",
                                        "items": {
                                            "type": "integer"
                                        }
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Rows in the new order"
                    },
                    "400": {
                        "description": "Invalid data"
                    },
                    "403": {
                        "description": "Access denied - some IDs do not belong to the organization"
                    }
                }
            }
        },
        "/v3/backoffice/diamond/group/{groupId}/download": {
            "get": {
                "tags": [
                    "Diamond > Group"
                ],
                "summary": "Download diamond group Excel",
                "description": "Downloads an Excel file with all diamonds for the specified diamond group",
                "operationId": "get_app_backoffice_apibackofficediamondgroup_getdiamondgroupdownload",
                "parameters": [
                    {
                        "name": "groupId",
                        "in": "path",
                        "description": "Diamond group ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Download URL returned successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/diamond/group/{groupId}/upload": {
            "post": {
                "tags": [
                    "Diamond > Group"
                ],
                "summary": "Upload diamond group Excel",
                "description": "Imports diamonds into the diamond group from an Excel file",
                "operationId": "post_app_backoffice_apibackofficediamondgroup_postdiamondgroupupload",
                "parameters": [
                    {
                        "name": "groupId",
                        "in": "path",
                        "description": "Diamond group ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Excel file uploaded and processed successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/ettore/instructions": {
            "get": {
                "tags": [
                    "Back Office > Ettore"
                ],
                "summary": "Get Ettore instructions",
                "description": "Returns the organization's editable Ettore persona instructions plus the built-in default",
                "operationId": "get_app_backoffice_apibackofficeettore_getinstructions",
                "responses": {
                    "200": {
                        "description": "Instructions retrieved successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            },
            "post": {
                "tags": [
                    "Back Office > Ettore"
                ],
                "summary": "Save Ettore instructions",
                "description": "Updates the organization's editable Ettore persona instructions",
                "operationId": "post_app_backoffice_apibackofficeettore_postinstructions",
                "responses": {
                    "200": {
                        "description": "Instructions saved successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/manufacturer": {
            "get": {
                "operationId": "get_app_backoffice_apibackofficemanufacturer_getcosts",
                "responses": {
                    "default": {
                        "description": ""
                    }
                }
            },
            "post": {
                "tags": [
                    "Manufacturer"
                ],
                "summary": "Create a cost",
                "description": "Creates a new cost for the organization",
                "operationId": "post_app_backoffice_apibackofficemanufacturer_postcostcreate",
                "responses": {
                    "201": {
                        "description": "Manufacturer created successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/manufacturer/duplicate": {
            "post": {
                "tags": [
                    "Manufacturer"
                ],
                "summary": "Duplicate a cost",
                "description": "Duplicates an existing cost in the organization",
                "operationId": "post_app_backoffice_apibackofficemanufacturer_postcostduplicate",
                "responses": {
                    "201": {
                        "description": "Manufacturer duplicated successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/manufacturer/validate": {
            "post": {
                "tags": [
                    "Manufacturer"
                ],
                "summary": "Validate a cost",
                "description": "Validates cost data without persisting it",
                "operationId": "post_app_backoffice_apibackofficemanufacturer_postcostvalidate",
                "responses": {
                    "200": {
                        "description": "Validation result"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/manufacturer/deactivate": {
            "post": {
                "tags": [
                    "Manufacturer"
                ],
                "summary": "Deactivate a cost",
                "description": "Deactivates a cost in the organization",
                "operationId": "post_app_backoffice_apibackofficemanufacturer_postcostdeactivate",
                "responses": {
                    "201": {
                        "description": "Manufacturer deactivated successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/manufacturer/activate": {
            "post": {
                "tags": [
                    "Manufacturer"
                ],
                "summary": "Activate a cost",
                "description": "Activates a cost in the organization",
                "operationId": "post_app_backoffice_apibackofficemanufacturer_postcostactivate",
                "responses": {
                    "200": {
                        "description": "Manufacturer activated successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/manufacturer/{id}": {
            "get": {
                "operationId": "get_app_backoffice_apibackofficemanufacturer_getcostbyid",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "default": {
                        "description": ""
                    }
                }
            },
            "post": {
                "tags": [
                    "Manufacturer"
                ],
                "summary": "Edit a cost",
                "description": "Updates an existing cost by ID",
                "operationId": "post_app_backoffice_apibackofficemanufacturer_posteditpost",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Manufacturer ID",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Manufacturer updated successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Manufacturer not found"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Manufacturer"
                ],
                "summary": "Delete a cost",
                "description": "Deletes a cost by its ID",
                "operationId": "delete_app_backoffice_apibackofficemanufacturer_deletecost",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Manufacturer ID",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Manufacturer deleted successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Manufacturer not found"
                    }
                }
            }
        },
        "/v3/backoffice/manufacturer/{id}/export": {
            "get": {
                "tags": [
                    "Manufacturer"
                ],
                "summary": "Download a manufacturer as a JSON file",
                "description": "Backup / transfer file with the whole configuration (info, metals, printing, casting, stone setting, quality, packaging, shipping, timing, markup, diamonds). No ids or organization data. Upload it with POST /v3/backoffice/manufacturer/import.",
                "operationId": "get_app_backoffice_apibackofficemanufacturer_export",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "application/json attachment"
                    },
                    "404": {
                        "description": "INVALID_MANUFACTURER_CENTER_ID"
                    }
                }
            }
        },
        "/v3/backoffice/manufacturer/import": {
            "post": {
                "tags": [
                    "Manufacturer"
                ],
                "summary": "Create a manufacturer from an exported JSON file",
                "description": "Multipart: `file` (the JSON downloaded from /export) and optional `name` to rename the copy. The new manufacturer is created inactive and not validated.",
                "operationId": "post_app_backoffice_apibackofficemanufacturer_import",
                "responses": {
                    "201": {
                        "description": "Manufacturer created"
                    },
                    "400": {
                        "description": "MISSING_FILE, INVALID_MANUFACTURER_FILE, UNSUPPORTED_MANUFACTURER_FILE_VERSION, MISSING_NAME"
                    }
                }
            }
        },
        "/v3/backoffice/manufacturer/order": {
            "put": {
                "tags": [
                    "Manufacturer"
                ],
                "summary": "Reorder manufacturers",
                "description": "Saves the order of the Pricing list. Send every manufacturer id of the organization in the new order.",
                "operationId": "put_app_backoffice_apibackofficemanufacturer_putmanufacturersorder",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "orderedIds": {
                                        "description": "Full ordered list of manufacturer IDs",
                                        "type": "array",
                                        "items": {
                                            "type": "integer"
                                        }
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Manufacturers in the new order"
                    },
                    "400": {
                        "description": "Invalid data"
                    },
                    "403": {
                        "description": "Access denied - some IDs do not belong to the organization"
                    }
                }
            }
        },
        "/v3/backoffice/markup": {
            "get": {
                "tags": [
                    "Markup"
                ],
                "summary": "Get all markups",
                "description": "Returns all markups for the organization, in the order of the Pricing list. `active` marks the one pricing the stones.",
                "operationId": "get_app_backoffice_apibackofficemarkup_getmarkups",
                "responses": {
                    "200": {
                        "description": "Markups retrieved successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            },
            "post": {
                "tags": [
                    "Markup"
                ],
                "summary": "Create a markup",
                "description": "Creates a new markup for the organization",
                "operationId": "post_app_backoffice_apibackofficemarkup_postmarkupcreate",
                "responses": {
                    "201": {
                        "description": "Markup created successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/markup/duplicate": {
            "post": {
                "tags": [
                    "Markup"
                ],
                "summary": "Duplicate a markup",
                "description": "Duplicates an existing markup in the organization",
                "operationId": "post_app_backoffice_apibackofficemarkup_postmarkupduplicate",
                "responses": {
                    "201": {
                        "description": "Markup duplicated successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/markup/activate": {
            "post": {
                "tags": [
                    "Markup"
                ],
                "summary": "Activate a markup",
                "description": "Makes this markup the one that prices the stones (form field `data` = JSON {id}); the others are switched off. The markup must have a name and every tier filled in.",
                "operationId": "post_app_backoffice_apibackofficemarkup_postmarkupactivate",
                "responses": {
                    "200": {
                        "description": "All markups, with the new active one"
                    },
                    "400": {
                        "description": "MARKUP_INCOMPLETE | INVALID_MARKUP_ID"
                    }
                }
            }
        },
        "/v3/backoffice/markup/deactivate": {
            "post": {
                "tags": [
                    "Markup"
                ],
                "summary": "Deactivate a markup",
                "description": "Form field `data` = JSON {id}. The organization is left without a markup pricing the stones until another one is activated.",
                "operationId": "post_app_backoffice_apibackofficemarkup_postmarkupdeactivate",
                "responses": {
                    "200": {
                        "description": "The markup"
                    },
                    "400": {
                        "description": "INVALID_MARKUP_ID"
                    }
                }
            }
        },
        "/v3/backoffice/markup/{id}": {
            "get": {
                "tags": [
                    "Markup"
                ],
                "summary": "Get a markup by ID",
                "description": "Returns a single markup by its ID",
                "operationId": "get_app_backoffice_apibackofficemarkup_getmarkupbyid",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Markup ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Markup retrieved successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Markup not found"
                    }
                }
            },
            "post": {
                "tags": [
                    "Markup"
                ],
                "summary": "Edit a markup",
                "description": "Updates an existing markup by ID",
                "operationId": "post_app_backoffice_apibackofficemarkup_posteditpost",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Markup ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Markup updated successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Markup not found"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Markup"
                ],
                "summary": "Delete a markup",
                "description": "Deletes a markup by its ID",
                "operationId": "delete_app_backoffice_apibackofficemarkup_deletemarkup",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Markup ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Markup deleted successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Markup not found"
                    }
                }
            }
        },
        "/v3/backoffice/markup/order": {
            "put": {
                "tags": [
                    "Markup"
                ],
                "summary": "Reorder markups",
                "description": "Saves the order of the Pricing list. Send every id of the organization in the new order.",
                "operationId": "put_app_backoffice_apibackofficemarkup_putorder",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "orderedIds": {
                                        "description": "Full ordered list of IDs",
                                        "type": "array",
                                        "items": {
                                            "type": "integer"
                                        }
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Rows in the new order"
                    },
                    "400": {
                        "description": "Invalid data"
                    },
                    "403": {
                        "description": "Access denied - some IDs do not belong to the organization"
                    }
                }
            }
        },
        "/v3/backoffice/organization": {
            "get": {
                "tags": [
                    "Back Office > Organization"
                ],
                "summary": "Get organization",
                "description": "Returns the current organization details",
                "operationId": "get_app_backoffice_apibackofficeorganization_getorganization",
                "responses": {
                    "200": {
                        "description": "Organization retrieved successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            },
            "post": {
                "tags": [
                    "Back Office > Organization"
                ],
                "summary": "Edit organization",
                "description": "Updates the current user's organization with optional logo upload",
                "operationId": "post_app_backoffice_apibackofficeorganization_posteditorganization",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "properties": {
                                    "data": {
                                        "description": "JSON data",
                                        "type": "string"
                                    },
                                    "logo": {
                                        "description": "Organization logo (optional)",
                                        "type": "string",
                                        "format": "binary"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Organization updated successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Organization not found"
                    }
                }
            }
        },
        "/v3/backoffice/organization/team": {
            "get": {
                "tags": [
                    "Back Office > Organization"
                ],
                "summary": "Get organization team",
                "description": "Retrieves all team members of the organization",
                "operationId": "get_app_backoffice_apibackofficeorganization_getorganizationteam",
                "responses": {
                    "200": {
                        "description": "Team retrieved successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/organization/members": {
            "get": {
                "tags": [
                    "Back Office > Organization"
                ],
                "summary": "Get organization members",
                "description": "Retrieves all members of the organization. Only for owners.",
                "operationId": "get_app_backoffice_apibackofficeorganization_getorganizationmembers",
                "responses": {
                    "200": {
                        "description": "Members retrieved successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/organization/logo": {
            "delete": {
                "tags": [
                    "Back Office > Organization"
                ],
                "summary": "Delete organization logo",
                "description": "Deletes the logo of the current user's organization",
                "operationId": "delete_app_backoffice_apibackofficeorganization_deleteorganizationlogo",
                "responses": {
                    "200": {
                        "description": "Logo deleted successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/photo-style": {
            "get": {
                "tags": [
                    "Photo style"
                ],
                "summary": "List the photo styles of the organization",
                "operationId": "get_app_backoffice_apibackofficephotostyle_list",
                "responses": {
                    "200": {
                        "description": "Photo styles in order"
                    }
                }
            },
            "post": {
                "tags": [
                    "Photo style"
                ],
                "summary": "Create a photo style",
                "description": "Multipart: `data` (JSON with name, prompt, model, showroom) and `image` (the reference photo, required). `showroom: true` makes it the style of the Showroom photo button (only one per organization).",
                "operationId": "post_app_backoffice_apibackofficephotostyle_create",
                "responses": {
                    "201": {
                        "description": "Photo style created"
                    },
                    "400": {
                        "description": "IMAGE_REQUIRED, INVALID_NAME, INVALID_MODEL, INVALID_PROMPT, INVALID_IMAGE"
                    }
                }
            }
        },
        "/v3/backoffice/photo-style/models": {
            "get": {
                "tags": [
                    "Photo style"
                ],
                "summary": "Image-to-image models a photo style can use",
                "operationId": "get_app_backoffice_apibackofficephotostyle_models",
                "responses": {
                    "200": {
                        "description": "[{id, label}]"
                    }
                }
            }
        },
        "/v3/backoffice/photo-style/{id}": {
            "post": {
                "tags": [
                    "Photo style"
                ],
                "summary": "Edit a photo style",
                "description": "Multipart: `data` (JSON with any of name, prompt, model) and optionally `image` to replace the reference photo.",
                "operationId": "post_app_backoffice_apibackofficephotostyle_update",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Photo style updated"
                    },
                    "404": {
                        "description": "INVALID_PHOTO_STYLE_ID"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Photo style"
                ],
                "summary": "Delete a photo style",
                "operationId": "delete_app_backoffice_apibackofficephotostyle_delete",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "PHOTO_STYLE_DELETED"
                    },
                    "404": {
                        "description": "INVALID_PHOTO_STYLE_ID"
                    }
                }
            }
        },
        "/v3/backoffice/photo-style/showroom": {
            "get": {
                "tags": [
                    "Photo style"
                ],
                "summary": "Daily limit of styled photos in the Showroom",
                "operationId": "get_app_backoffice_apibackofficephotostyle_showroom",
                "responses": {
                    "200": {
                        "description": "{daily_limit, used_today}"
                    }
                }
            },
            "post": {
                "tags": [
                    "Photo style"
                ],
                "summary": "Set the daily limit of styled photos in the Showroom",
                "description": "JSON body {daily_limit}: 0 (off) to 500. Each photo is a paid fal.ai call with the organization key.",
                "operationId": "post_app_backoffice_apibackofficephotostyle_saveshowroom",
                "responses": {
                    "200": {
                        "description": "{daily_limit, used_today}"
                    },
                    "400": {
                        "description": "INVALID_DATA, INVALID_DAILY_LIMIT"
                    }
                }
            }
        },
        "/v3/backoffice/photo-style/{id}/try": {
            "post": {
                "tags": [
                    "Photo style"
                ],
                "summary": "Apply a photo style to a test photo",
                "description": "Multipart: `photo` (the photo to edit). Synchronous: waits for fal.ai and returns the result URL. Needs the organization fal.ai key.",
                "operationId": "post_app_backoffice_apibackofficephotostyle_try",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "{image_url, model}"
                    },
                    "400": {
                        "description": "FALAI_API_KEY_REQUIRED, PHOTO_REQUIRED, INVALID_IMAGE, FALAI_ERROR, FALAI_NO_IMAGE"
                    }
                }
            }
        },
        "/v3/backoffice/simulator": {
            "post": {
                "tags": [
                    "Simulator"
                ],
                "summary": "Simulate a design's price breakdown against a manufacturer",
                "description": "Computes the price breakdown of a design (from the tech data the engine produced) using any manufacturer of the organization and, optionally, a diamond group and a target currency.",
                "operationId": "post_app_backoffice_apibackofficesimulator_postsimulate",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "design_id",
                                    "manufacturer_id"
                                ],
                                "properties": {
                                    "design_id": {
                                        "type": "integer"
                                    },
                                    "manufacturer_id": {
                                        "type": "integer"
                                    },
                                    "group_id": {
                                        "description": "Diamond group, optional",
                                        "type": "integer",
                                        "nullable": true
                                    },
                                    "currency": {
                                        "type": "string",
                                        "example": "EUR",
                                        "nullable": true
                                    },
                                    "main_stone_cost": {
                                        "description": "Cost of the main stone, in the breakdown currency, to try the dynamic setting markup (its share of the raw cost picks the tier). Omitted: the stone put in the design, if any",
                                        "type": "number",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Breakdown (metals, gems, processes, markup, delivery), `retail` {setting_cost, markup_mode, markup_percentage, markup_tier, main_stone_cost, main_stone_share, markup_amount, total, currency} with the active markup (null without one), plus `design` {id, name, preview}"
                    },
                    "400": {
                        "description": "INVALID_DATA | MISSING_DESIGN_ID | MISSING_MANUFACTURER_ID | DESIGN_NOT_COMPUTED"
                    },
                    "404": {
                        "description": "DESIGN_NOT_FOUND | MANUFACTURER_NOT_FOUND | DIAMOND_GROUP_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/backoffice/stats": {
            "get": {
                "tags": [
                    "Back Office"
                ],
                "summary": "Back Office stats for the current organization",
                "operationId": "get_api_backoffice_stats",
                "responses": {
                    "200": {
                        "description": "Back Office stats",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Forbidden"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/backoffice/store": {
            "get": {
                "tags": [
                    "v3 / Store"
                ],
                "summary": "Get all stores",
                "operationId": "get_app_backoffice_apibackofficestores_getstorelist",
                "responses": {
                    "200": {
                        "description": "Stores found"
                    },
                    "403": {
                        "description": "Authentication failed"
                    }
                }
            },
            "post": {
                "tags": [
                    "v3 / Store"
                ],
                "summary": "Create a store",
                "operationId": "post_app_backoffice_apibackofficestores_postcreatestore",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "properties": {
                                    "data": {
                                        "description": "JSON payload with store data",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Store created"
                    },
                    "400": {
                        "description": "Invalid data"
                    },
                    "403": {
                        "description": "Authentication failed"
                    }
                }
            }
        },
        "/v3/backoffice/store/{id}": {
            "get": {
                "tags": [
                    "v3 / Store"
                ],
                "summary": "Get a store",
                "operationId": "get_app_backoffice_apibackofficestores_getstorebyid",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Store found"
                    },
                    "403": {
                        "description": "Authentication failed"
                    },
                    "404": {
                        "description": "Store not found"
                    }
                }
            },
            "post": {
                "tags": [
                    "v3 / Store"
                ],
                "summary": "Edit a store",
                "operationId": "post_app_backoffice_apibackofficestores_posteditstore",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "properties": {
                                    "data": {
                                        "description": "JSON payload with store data",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Store updated"
                    },
                    "400": {
                        "description": "Invalid data"
                    },
                    "403": {
                        "description": "Authentication failed"
                    }
                }
            },
            "delete": {
                "tags": [
                    "v3 / Store"
                ],
                "summary": "Delete a store",
                "operationId": "delete_app_backoffice_apibackofficestores_deletestore",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Store deleted"
                    },
                    "403": {
                        "description": "Authentication failed"
                    },
                    "404": {
                        "description": "Store not found"
                    }
                }
            }
        },
        "/v3/backoffice/tax": {
            "get": {
                "operationId": "get_app_backoffice_apibackofficetax_gettaxs",
                "responses": {
                    "default": {
                        "description": ""
                    }
                }
            },
            "post": {
                "tags": [
                    "Tax"
                ],
                "summary": "Create a tax",
                "description": "Creates a new tax for the organization",
                "operationId": "post_app_backoffice_apibackofficetax_posttaxcreate",
                "responses": {
                    "201": {
                        "description": "Tax created successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/tax/duplicate": {
            "post": {
                "tags": [
                    "Tax"
                ],
                "summary": "Duplicate a tax",
                "description": "Duplicates an existing tax in the organization",
                "operationId": "post_app_backoffice_apibackofficetax_posttaxduplicate",
                "responses": {
                    "201": {
                        "description": "Tax duplicated successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/tax/deactivate": {
            "post": {
                "tags": [
                    "Tax"
                ],
                "summary": "Deactivate a tax",
                "description": "Deactivates a tax in the organization",
                "operationId": "post_app_backoffice_apibackofficetax_posttaxdeactivate",
                "responses": {
                    "201": {
                        "description": "Tax deactivated successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/tax/activate": {
            "post": {
                "tags": [
                    "Tax"
                ],
                "summary": "Activate a tax",
                "description": "Activates a tax in the organization",
                "operationId": "post_app_backoffice_apibackofficetax_posttaxactivate",
                "responses": {
                    "200": {
                        "description": "Tax activated successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/backoffice/tax/{id}": {
            "get": {
                "tags": [
                    "Tax"
                ],
                "summary": "Get a tax by ID",
                "description": "Returns a single tax by its ID",
                "operationId": "get_app_backoffice_apibackofficetax_gettaxbyid",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Tax ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Tax retrieved successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Tax not found"
                    }
                }
            },
            "post": {
                "tags": [
                    "Tax"
                ],
                "summary": "Edit a tax",
                "description": "Updates an existing tax by ID",
                "operationId": "post_app_backoffice_apibackofficetax_posteditpost",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Tax ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Tax updated successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Tax not found"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Tax"
                ],
                "summary": "Delete a tax",
                "description": "Deletes a tax by its ID",
                "operationId": "delete_app_backoffice_apibackofficetax_deletetax",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Tax ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Tax deleted successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Tax not found"
                    }
                }
            }
        },
        "/v3/backoffice/tax/order": {
            "put": {
                "tags": [
                    "Tax"
                ],
                "summary": "Reorder taxs",
                "description": "Saves the order of the Pricing list. Send every id of the organization in the new order.",
                "operationId": "put_app_backoffice_apibackofficetax_putorder",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "orderedIds": {
                                        "description": "Full ordered list of IDs",
                                        "type": "array",
                                        "items": {
                                            "type": "integer"
                                        }
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Rows in the new order"
                    },
                    "400": {
                        "description": "Invalid data"
                    },
                    "403": {
                        "description": "Access denied - some IDs do not belong to the organization"
                    }
                }
            }
        },
        "/v3/backoffice/viewer-environment": {
            "get": {
                "tags": [
                    "Viewer environment"
                ],
                "summary": "List the custom HDR environments of the organization",
                "operationId": "get_app_backoffice_apibackofficeviewerenvironment_list",
                "responses": {
                    "200": {
                        "description": "[{id, name, file, file_url, thumbnail_url, created_at}]"
                    }
                }
            },
            "post": {
                "tags": [
                    "Viewer environment"
                ],
                "summary": "Upload a custom HDR",
                "description": "Multipart: `file` (.hdr or .exr, up to 32 MB) and optionally `data` (JSON with name; defaults to the file name). At most 20 per organization.",
                "operationId": "post_app_backoffice_apibackofficeviewerenvironment_create",
                "responses": {
                    "201": {
                        "description": "Environment created"
                    },
                    "400": {
                        "description": "ENVIRONMENT_LIMIT, FILE_REQUIRED, INVALID_HDR, INVALID_ENVIRONMENT_NAME"
                    }
                }
            }
        },
        "/v3/backoffice/viewer-environment/{id}": {
            "post": {
                "tags": [
                    "Viewer environment"
                ],
                "summary": "Rename a custom HDR or set its thumbnail",
                "description": "Multipart: `data` (JSON with name) and/or `thumbnail` (JPG/PNG/WebP capture of the sample piece with the HDR).",
                "operationId": "post_app_backoffice_apibackofficeviewerenvironment_update",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Environment updated"
                    },
                    "404": {
                        "description": "INVALID_ENVIRONMENT_ID"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Viewer environment"
                ],
                "summary": "Delete a custom HDR",
                "description": "Scenes that used it fall back to the viewer default HDR.",
                "operationId": "delete_app_backoffice_apibackofficeviewerenvironment_delete",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "ENVIRONMENT_DELETED"
                    },
                    "404": {
                        "description": "INVALID_ENVIRONMENT_ID"
                    }
                }
            }
        },
        "/v3/backoffice/viewer-scene": {
            "get": {
                "tags": [
                    "Viewer scene"
                ],
                "summary": "List the viewer scenes of the organization",
                "operationId": "get_app_backoffice_apibackofficeviewerscene_list",
                "responses": {
                    "200": {
                        "description": "Scenes in gallery order"
                    }
                }
            },
            "post": {
                "tags": [
                    "Viewer scene"
                ],
                "summary": "Create a viewer scene",
                "description": "Multipart: `data` (JSON with name and settings {options, default_view}) and optionally `thumbnail` (JPG/PNG/WebP).",
                "operationId": "post_app_backoffice_apibackofficeviewerscene_create",
                "responses": {
                    "201": {
                        "description": "Scene created"
                    },
                    "400": {
                        "description": "INVALID_SCENE_NAME, INVALID_VIEWER_SETTINGS, INVALID_IMAGE"
                    }
                }
            }
        },
        "/v3/backoffice/viewer-scene/{id}": {
            "post": {
                "tags": [
                    "Viewer scene"
                ],
                "summary": "Edit a viewer scene",
                "description": "Multipart: `data` (JSON with any of name, settings) and optionally `thumbnail` to replace the capture.",
                "operationId": "post_app_backoffice_apibackofficeviewerscene_update",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Scene updated"
                    },
                    "404": {
                        "description": "INVALID_SCENE_ID"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Viewer scene"
                ],
                "summary": "Delete a viewer scene",
                "description": "Contexts that used it fall back to the Studio defaults.",
                "operationId": "delete_app_backoffice_apibackofficeviewerscene_delete",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "SCENE_DELETED"
                    },
                    "404": {
                        "description": "INVALID_SCENE_ID"
                    }
                }
            }
        },
        "/v3/backoffice/viewer-scene/{id}/duplicate": {
            "post": {
                "tags": [
                    "Viewer scene"
                ],
                "summary": "Duplicate a viewer scene",
                "description": "Optional JSON body {name}; by default the copy is named after the original.",
                "operationId": "post_app_backoffice_apibackofficeviewerscene_duplicate",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "201": {
                        "description": "The copy"
                    },
                    "404": {
                        "description": "INVALID_SCENE_ID"
                    }
                }
            }
        },
        "/v3/backoffice/viewer-scene/order": {
            "put": {
                "tags": [
                    "Viewer scene"
                ],
                "summary": "Reorder the scenes",
                "operationId": "put_app_backoffice_apibackofficeviewerscene_order",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "orderedIds": {
                                        "description": "Every scene id of the organization, in the new order",
                                        "type": "array",
                                        "items": {
                                            "type": "integer"
                                        }
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Scenes in the new order"
                    },
                    "400": {
                        "description": "INVALID_DATA"
                    }
                }
            }
        },
        "/v3/backoffice/viewer-scene/assign": {
            "post": {
                "tags": [
                    "Viewer scene"
                ],
                "summary": "Choose the scene a context uses",
                "description": "JSON body {context: \"studio\", scene_id: number|null}. Null clears the assignment: the context falls back to the Studio defaults.",
                "operationId": "post_app_backoffice_apibackofficeviewerscene_assign",
                "responses": {
                    "200": {
                        "description": "{scene_assignments, viewer_settings}"
                    },
                    "400": {
                        "description": "INVALID_SCENE_CONTEXT, INVALID_SCENE_ID"
                    },
                    "404": {
                        "description": "INVALID_SCENE_ID"
                    }
                }
            }
        },
        "/v3/client-book/client": {
            "get": {
                "tags": [
                    "Client Book"
                ],
                "summary": "List clients",
                "description": "Paginated clients of the caller's organization. `search` matches name, email or phone (digits only also work). `scope` is `active` (default), `archived` or `all`.",
                "operationId": "get_app_clientbook_apiclientbook_list",
                "parameters": [
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "scope",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "default": "active",
                            "enum": [
                                "active",
                                "archived",
                                "all"
                            ]
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 25,
                            "maximum": 100
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "{ items, total, page, limit }"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            },
            "post": {
                "tags": [
                    "Client Book"
                ],
                "summary": "Create a client",
                "description": "A commercial record, not a user account: no invitation is sent. Email and phone are optional but validated when present; duplicates are allowed (see /match).",
                "operationId": "post_app_clientbook_apiclientbook_create",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "name"
                                ],
                                "properties": {
                                    "name": {
                                        "type": "string"
                                    },
                                    "email": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "phone": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "preferences": {
                                        "description": "Free text: sizes, metals, gems, styles\u2026",
                                        "type": "string",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Client created"
                    },
                    "400": {
                        "description": "MISSING_NAME | NAME_TOO_LONG | INVALID_EMAIL | INVALID_PHONE | PREFERENCES_TOO_LONG"
                    }
                }
            }
        },
        "/v3/client-book/client/match": {
            "get": {
                "tags": [
                    "Client Book"
                ],
                "summary": "Find possible duplicates",
                "description": "Clients of the organization with the same email (case-insensitive) or phone (digits only), archived included. A warning aid: nothing is merged and creating is still allowed.",
                "operationId": "get_app_clientbook_apiclientbook_match",
                "parameters": [
                    {
                        "name": "email",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "phone",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "except",
                        "in": "query",
                        "description": "Client id to leave out (when editing).",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Matching clients (may be empty)"
                    }
                }
            }
        },
        "/v3/client-book/client/{id}": {
            "get": {
                "tags": [
                    "Client Book"
                ],
                "summary": "Get a client",
                "description": "Contact data, preferences, internal notes (newest first) and the number of linked designs. Archived clients are readable too.",
                "operationId": "get_app_clientbook_apiclientbook_get",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Client"
                    },
                    "404": {
                        "description": "CLIENT_NOT_FOUND"
                    }
                }
            },
            "put": {
                "tags": [
                    "Client Book"
                ],
                "summary": "Update a client",
                "description": "Only the provided fields change. Send `null` (or an empty string) to clear email, phone or preferences.",
                "operationId": "put_app_clientbook_apiclientbook_update",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "name": {
                                        "type": "string"
                                    },
                                    "email": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "phone": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "preferences": {
                                        "type": "string",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Client updated"
                    },
                    "400": {
                        "description": "MISSING_NAME | INVALID_EMAIL | INVALID_PHONE"
                    },
                    "404": {
                        "description": "CLIENT_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/client-book/client/{id}/archive": {
            "post": {
                "tags": [
                    "Client Book"
                ],
                "summary": "Archive a client",
                "description": "Hides the client from the default list and from the Showroom selector. Designs, notes and history are kept.",
                "operationId": "post_app_clientbook_apiclientbook_archive",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Client archived"
                    },
                    "404": {
                        "description": "CLIENT_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/client-book/client/{id}/restore": {
            "post": {
                "tags": [
                    "Client Book"
                ],
                "summary": "Restore an archived client",
                "operationId": "post_app_clientbook_apiclientbook_restore",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Client restored"
                    },
                    "404": {
                        "description": "CLIENT_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/client-book/client/{id}/note": {
            "post": {
                "tags": [
                    "Client Book"
                ],
                "summary": "Add an internal note",
                "description": "Seller note with author and date. Internal: never shown to the buyer.",
                "operationId": "post_app_clientbook_apiclientbook_addnote",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "content"
                                ],
                                "properties": {
                                    "content": {
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "The note"
                    },
                    "400": {
                        "description": "MISSING_NOTE_CONTENT | NOTE_TOO_LONG"
                    },
                    "404": {
                        "description": "CLIENT_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/client-book/client/{id}/note/{noteId}": {
            "delete": {
                "tags": [
                    "Client Book"
                ],
                "summary": "Delete a note",
                "operationId": "delete_app_clientbook_apiclientbook_deletenote",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "name": "noteId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "{ ok: true }"
                    },
                    "404": {
                        "description": "CLIENT_NOT_FOUND | NOTE_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/client-book/client/{id}/design": {
            "get": {
                "tags": [
                    "Client Book"
                ],
                "summary": "List the client's designs",
                "description": "Saved designs linked to the client, most recently updated first. Open one in the Showroom with /showroom/design/{designId}.",
                "operationId": "get_app_clientbook_apiclientbook_listdesigns",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Designs"
                    },
                    "404": {
                        "description": "CLIENT_NOT_FOUND"
                    }
                }
            },
            "post": {
                "tags": [
                    "Client Book"
                ],
                "summary": "Save a design for the client",
                "description": "Two ways in: `draft_id` promotes a draft made by /v3/compute/solve into the client's design (fast); `source_design_id` alone copies an existing design of the organization without recomputing. With both, the draft is saved and `source_design_id` is recorded as the piece it personalizes. The source design is never modified.",
                "operationId": "post_app_clientbook_apiclientbook_createdesign",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "draft_id": {
                                        "type": "integer",
                                        "nullable": true
                                    },
                                    "source_design_id": {
                                        "type": "integer",
                                        "nullable": true
                                    },
                                    "store_id": {
                                        "description": "The store where it was made (Analytics). Defaults to the only store assigned to the caller in Settings \u203a Team; none if they work in several or none.",
                                        "type": "integer",
                                        "nullable": true
                                    },
                                    "name": {
                                        "description": "Defaults to the source (or draft) name.",
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "display_name": {
                                        "description": "The name shown to the client (Showroom, piece details, share page), up to 80 characters; without the key a copy keeps its source's, empty removes it.",
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "description": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "engraving": {
                                        "description": "Inside engraving of a ring: `{text, font, size}` (font: script, italic, roman, serif, sans or typewriter; size: cap height in mm, 0.6\u20133). Null or an empty text removes it; without the key a copy keeps its source's.",
                                        "type": "object",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "The client's design"
                    },
                    "400": {
                        "description": "MISSING_DRAFT_OR_SOURCE | CLIENT_ARCHIVED"
                    },
                    "404": {
                        "description": "CLIENT_NOT_FOUND | DRAFT_NOT_FOUND | DESIGN_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/client-book/client/{id}/design/{designId}/preview": {
            "post": {
                "tags": [
                    "Client Book"
                ],
                "summary": "Upload the preview of one of the client's designs",
                "description": "Stores the image captured from the viewer as the design's preview (`kind`: main, top or side) and returns the design. Same as the Drive endpoint, for showroom members.",
                "operationId": "post_app_clientbook_apiclientbook_uploaddesignpreview",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "name": "designId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "properties": {
                                    "preview": {
                                        "type": "string",
                                        "format": "binary"
                                    },
                                    "kind": {
                                        "type": "string",
                                        "default": "main",
                                        "enum": [
                                            "main",
                                            "top",
                                            "side"
                                        ]
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Preview stored"
                    },
                    "400": {
                        "description": "MISSING_PREVIEW | INVALID_KIND"
                    },
                    "404": {
                        "description": "CLIENT_NOT_FOUND | DESIGN_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/client-book/client/{id}/shares": {
            "get": {
                "tags": [
                    "Client Book"
                ],
                "summary": "Public links to the client's pieces",
                "description": "Every link of every piece of the client, newest first: url, message, expiry, whether it is still active and how many times it was opened.",
                "operationId": "get_app_clientbook_apiclientbook_listshares",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "[{id, design_id, url, message, show_price, price: {total, currency, priced_at}|null, expires_at, revoked_at, active, views_count, last_viewed_at, created_at}]"
                    }
                }
            }
        },
        "/v3/client-book/client/{id}/design/{designId}/share": {
            "post": {
                "tags": [
                    "Client Book"
                ],
                "summary": "Share a client piece with a public link",
                "description": "Returns the active link of the piece, or a new one. JSON body, all optional: message (up to 500 characters), expires_in_days (1-30, 2 = 48 hours; a new link lasts 30 days) and show_price (boolean, off by default; true freezes today's retail price, sent again it updates it). The page shows the piece live (photos, 3D, metal and stones) and, with show_price, its frozen retail price: the piece, the inventory stone and the total. 400 SHARE_PRICE_UNAVAILABLE if the piece cannot be priced today.",
                "operationId": "post_app_clientbook_apiclientbook_sharedesign",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "name": "designId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The link"
                    },
                    "400": {
                        "description": "CLIENT_ARCHIVED, INVALID_SHARE_MESSAGE, SHARE_MESSAGE_TOO_LONG, INVALID_SHARE_EXPIRY"
                    },
                    "404": {
                        "description": "DESIGN_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/client-book/client/{id}/design/{designId}/share/{shareId}": {
            "post": {
                "tags": [
                    "Client Book"
                ],
                "summary": "Change the message, the expiry or the price switch of a link",
                "description": "JSON body with message, expires_in_days (from now, 1-30) and/or show_price (true freezes today's price, also to update it; false removes it). Also reopens an expired link; a revoked one stays revoked.",
                "operationId": "post_app_clientbook_apiclientbook_updateshare",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "name": "designId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "name": "shareId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The link"
                    },
                    "400": {
                        "description": "SHARE_REVOKED, INVALID_SHARE_MESSAGE, SHARE_MESSAGE_TOO_LONG, INVALID_SHARE_EXPIRY"
                    },
                    "404": {
                        "description": "SHARE_NOT_FOUND"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Client Book"
                ],
                "summary": "Stop sharing: the link no longer opens",
                "operationId": "delete_app_clientbook_apiclientbook_revokeshare",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "name": "designId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "name": "shareId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The revoked link"
                    },
                    "404": {
                        "description": "SHARE_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/client-book/client/{id}/photos": {
            "get": {
                "tags": [
                    "Client Book"
                ],
                "summary": "Photos saved on the client's pieces",
                "description": "Every photo of every piece of the client, newest first; each with its design_id and whether it is the piece cover.",
                "operationId": "get_app_clientbook_apiclientbook_listphotos",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "[{id, design_id, url, style, cover, created_at}]"
                    }
                }
            }
        },
        "/v3/client-book/client/{id}/design/{designId}/photos": {
            "post": {
                "tags": [
                    "Client Book"
                ],
                "summary": "Save a photo on one of the client's pieces",
                "description": "Multipart: `photo` (PNG, JPEG or WebP) and optionally `photo_style_id`. Up to 12 per piece; the first one becomes the cover (the piece preview).",
                "operationId": "post_app_clientbook_apiclientbook_addphoto",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "name": "designId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "{preview, photos}"
                    },
                    "400": {
                        "description": "MISSING_PHOTO, INVALID_IMAGE, DESIGN_PHOTOS_LIMIT"
                    },
                    "404": {
                        "description": "CLIENT_NOT_FOUND, DESIGN_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/client-book/client/{id}/design/{designId}/photos/{photoId}/cover": {
            "post": {
                "tags": [
                    "Client Book"
                ],
                "summary": "Make a photo the cover of the piece",
                "operationId": "post_app_clientbook_apiclientbook_coverphoto",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "name": "designId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "name": "photoId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "{preview, photos}"
                    },
                    "404": {
                        "description": "PHOTO_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/client-book/client/{id}/design/{designId}/photos/{photoId}": {
            "delete": {
                "tags": [
                    "Client Book"
                ],
                "summary": "Remove a photo from the piece",
                "description": "If it was the cover, the newest remaining photo takes its place.",
                "operationId": "delete_app_clientbook_apiclientbook_deletephoto",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "name": "designId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "name": "photoId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "{preview, photos}"
                    },
                    "404": {
                        "description": "PHOTO_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/client-book/client/{id}/design/{designId}": {
            "put": {
                "tags": [
                    "Client Book"
                ],
                "summary": "Update one of the client's designs",
                "description": "Edits a design that already belongs to the client without creating copies: name, description, the inside engraving and, with `draft_id`, the geometry of a newer solve (the draft is consumed).",
                "operationId": "put_app_clientbook_apiclientbook_updatedesign",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    },
                    {
                        "name": "designId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "name": {
                                        "type": "string"
                                    },
                                    "display_name": {
                                        "description": "The name shown to the client (Showroom, piece details, share page), up to 80 characters; empty removes it.",
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "description": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "draft_id": {
                                        "type": "integer"
                                    },
                                    "engraving": {
                                        "description": "Inside engraving `{text, font, size}`; null removes it.",
                                        "type": "object",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Design updated"
                    },
                    "400": {
                        "description": "INVALID_ENGRAVING"
                    },
                    "404": {
                        "description": "CLIENT_NOT_FOUND | DESIGN_NOT_FOUND | DRAFT_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/compute/health": {
            "get": {
                "tags": [
                    "Compute"
                ],
                "summary": "Compute health check",
                "description": "Proxies to the configured RhinoArtisan Compute server to validate connectivity and API key. Returns the RhinoArtisan Compute version payload on success.",
                "operationId": "get_app_compute_apicompute_health",
                "responses": {
                    "200": {
                        "description": "RhinoArtisan Compute reachable"
                    },
                    "502": {
                        "description": "RhinoArtisan Compute unreachable or misconfigured"
                    }
                }
            }
        },
        "/v3/compute/solve": {
            "post": {
                "tags": [
                    "Compute"
                ],
                "summary": "Solve a values record into a draft design",
                "description": "Runs the Knowledge Capsule's .gh on RhinoArtisan Compute with `values` as its single `RH_IN:100:GLOBAL` input, uploads the GLB/STL and stores the result as a draft Design (not yet in the catalogue). Returns the design with public URLs, a `materials` map for the viewer, the resolved values and a price breakdown. Save it with POST /v3/backoffice/design {draft_id}.",
                "operationId": "post_app_compute_apicompute_solve",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "capsule_id",
                                    "values"
                                ],
                                "properties": {
                                    "capsule_id": {
                                        "description": "Knowledge Capsule of the caller's organization. Its .gh must be uploaded.",
                                        "type": "integer"
                                    },
                                    "values": {
                                        "description": "The record: a flat object keyed by the Knowledge Capsule's schema (dotted names). A nested object is flattened. Validated against `KnowledgeCapsule.schema`.",
                                        "type": "object",
                                        "example": {
                                            "center_stone.main.material": "DIAMOND",
                                            "center_stone.main.shape": "ROUND",
                                            "center_stone.main.size_ct": 1
                                        }
                                    },
                                    "mode": {
                                        "type": "string",
                                        "default": "rendering",
                                        "enum": [
                                            "rendering",
                                            "manufacturing"
                                        ]
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Draft design with glb_url/stl_url, tech, parts (the part paths of the piece, as in the GLB extras.part), values_resolved, materials and breakdown"
                    },
                    "400": {
                        "description": "INVALID_PAYLOAD, MISSING_CAPSULE, CAPSULE_REQUIRES_ORGANIZATION, INVALID_VALUES, INVALID_MODE or CAPSULE_HAS_NO_DEFINITION"
                    },
                    "404": {
                        "description": "CAPSULE_NOT_FOUND"
                    },
                    "502": {
                        "description": "Compute or upload failed; the draft is kept as failed"
                    }
                }
            }
        },
        "/v3/compute/standards": {
            "post": {
                "tags": [
                    "Compute"
                ],
                "summary": "Check a piece against the written standards",
                "description": "Asks a model whether the record about to be computed (over the last resolved piece, if any) breaks the organization's design standards, the production manufacturer's manufacturing standards or the capsule's own rules. Returns findings with the key to change, the proposed value (already within the capsule's schema and Studio UI rules; null when the UI fixes that key) and the rule quoted verbatim. Nothing is applied here: the Studio applies the proposals before computing and reports them in the chat. Call it only when a key of the gate (GET /v3/compute/standards/gate) changed. `checked` is false, without calling the model, when there are no standards (NO_STANDARDS) or no OpenRouter key (OPENROUTER_KEY_MISSING).",
                "operationId": "post_app_compute_apicompute_standards",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "capsule_id",
                                    "values"
                                ],
                                "properties": {
                                    "capsule_id": {
                                        "description": "Knowledge Capsule of the caller's organization.",
                                        "type": "integer"
                                    },
                                    "values": {
                                        "description": "The record, as sent to /v3/compute/solve.",
                                        "type": "object"
                                    },
                                    "resolved": {
                                        "description": "`values_resolved` of the last solve, if any (the record overrides it).",
                                        "type": "object"
                                    },
                                    "tech": {
                                        "description": "`tech` of the last solve, if any.",
                                        "type": "object"
                                    },
                                    "changed_keys": {
                                        "description": "Schema keys the user changed since the last check (empty on the first check).",
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        }
                                    },
                                    "lang": {
                                        "description": "Language code for the findings' `reason` (\"es\", \"en\"\u2026); English when missing.",
                                        "type": "string",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "{checked, reason?, findings: [{key, current, proposed, rule, source: design|manufacturing|capsule, severity: must|should, reason}]}"
                    },
                    "400": {
                        "description": "INVALID_PAYLOAD, MISSING_CAPSULE, INVALID_VALUES or CAPSULE_REQUIRES_ORGANIZATION"
                    },
                    "404": {
                        "description": "CAPSULE_NOT_FOUND"
                    },
                    "502": {
                        "description": "The model failed"
                    }
                }
            }
        },
        "/v3/compute/standards/gate": {
            "get": {
                "tags": [
                    "Compute"
                ],
                "summary": "Which schema keys the standards involve",
                "description": "The gate of the standards check for a capsule: the schema keys that the applicable standards (design, manufacturing, capsule) constrain, set or use as a condition, and whether any standard depends on the piece as built by the engine (`needs_result`). The Studio checks the standards (POST /v3/compute/standards) only when one of these keys changes, before computing. A model extracts the keys once; they are cached on the capsule until the standards or the schema change. `has_standards` is false when there are none (reason NO_STANDARDS); with no OpenRouter key the keys are empty (reason OPENROUTER_KEY_MISSING).",
                "operationId": "get_app_compute_apicompute_standardsgate",
                "parameters": [
                    {
                        "name": "capsule_id",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "{has_standards, reason?, keys: [schema keys], needs_result}"
                    },
                    "400": {
                        "description": "MISSING_CAPSULE or CAPSULE_REQUIRES_ORGANIZATION"
                    },
                    "404": {
                        "description": "CAPSULE_NOT_FOUND"
                    },
                    "502": {
                        "description": "The model failed"
                    }
                }
            }
        },
        "/v3/developer/usage": {
            "get": {
                "tags": [
                    "Developer"
                ],
                "summary": "Compute usage of the organization",
                "description": "Totals, per-day series, breakdown by capsule and the latest failures, over the requested window. Built from the compute log itself (every solve leaves a row), scoped to the users of the organization. Cache hits are counted apart: they never reached the engine.",
                "operationId": "get_app_developer_apideveloperusage_getusage",
                "parameters": [
                    {
                        "name": "days",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 30,
                            "enum": [
                                7,
                                30,
                                90
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Usage summary"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "INVALID_ROLE"
                    }
                }
            }
        },
        "/v3/fulfillment/jobs": {
            "get": {
                "tags": [
                    "Fulfillment"
                ],
                "summary": "The workshop queue",
                "description": "Production jobs, oldest first. Filters: status (comma-separated: pending, sent, in_progress, done, cancelled), manufacturer_id, order_id.",
                "operationId": "get_api_fulfillment_jobs",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "example": "pending,sent,in_progress"
                        }
                    },
                    {
                        "name": "manufacturer_id",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "order_id",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 50,
                            "maximum": 200
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of jobs",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/ProductionJob"
                                            }
                                        },
                                        "total": {
                                            "type": "integer"
                                        },
                                        "page": {
                                            "type": "integer"
                                        },
                                        "limit": {
                                            "type": "integer"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/fulfillment/jobs/{id}": {
            "get": {
                "tags": [
                    "Fulfillment"
                ],
                "summary": "A production job with its tech sheet",
                "operationId": "get_api_fulfillment_job",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The job",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ProductionJob"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "JOB_NOT_FOUND"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            },
            "patch": {
                "tags": [
                    "Fulfillment"
                ],
                "summary": "Change the job notes",
                "operationId": "patch_api_fulfillment_job_update",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "notes": {
                                        "type": "string",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The job",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ProductionJob"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/fulfillment/jobs/{id}/send": {
            "post": {
                "tags": [
                    "Fulfillment"
                ],
                "summary": "Send the job to the workshop",
                "description": "Prepares the manufacturing STL (the engine is asked if the piece was computed for rendering; a failure is recorded and can be retried) and marks the job as sent. On a job already sent it only retries the STL.",
                "operationId": "post_api_fulfillment_job_send",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "note": {
                                        "type": "string",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The job",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ProductionJob"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "JOB_NOT_FOUND"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/fulfillment/jobs/{id}/status": {
            "post": {
                "tags": [
                    "Fulfillment"
                ],
                "summary": "Move the job along (sent \u2192 in_progress \u2192 done, or cancelled)",
                "description": "When the last job of the order is done, the order becomes ready.",
                "operationId": "post_api_fulfillment_job_status",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "status"
                                ],
                                "properties": {
                                    "status": {
                                        "type": "string",
                                        "enum": [
                                            "sent",
                                            "in_progress",
                                            "done",
                                            "cancelled"
                                        ]
                                    },
                                    "note": {
                                        "type": "string",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The job",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ProductionJob"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "INVALID_JOB_STATUS | INVALID_JOB_TRANSITION"
                    },
                    "404": {
                        "description": "JOB_NOT_FOUND"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/fulfillment/jobs/{id}/tech-sheet": {
            "get": {
                "tags": [
                    "Fulfillment"
                ],
                "summary": "The tech sheet for the workshop, as a JSON file",
                "description": "What defines the piece (metal, size, engraving, stones, engine tech, STL link); no prices.",
                "operationId": "get_api_fulfillment_job_tech_sheet",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "application/json attachment"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/fulfillment/orders": {
            "get": {
                "tags": [
                    "Fulfillment"
                ],
                "summary": "List the orders",
                "description": "Most recent first. Filters: status (comma-separated), client_id, store_id and search (order number or client name).",
                "operationId": "get_api_fulfillment_orders",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "example": "ordered,in_production"
                        }
                    },
                    {
                        "name": "client_id",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "store_id",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "default": 25,
                            "maximum": 100
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of orders",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Order"
                                            }
                                        },
                                        "total": {
                                            "type": "integer"
                                        },
                                        "page": {
                                            "type": "integer"
                                        },
                                        "limit": {
                                            "type": "integer"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "INVALID_ORDER_STATUS"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/fulfillment/orders/{id}": {
            "get": {
                "tags": [
                    "Fulfillment"
                ],
                "summary": "An order with its lines and timeline",
                "operationId": "get_api_fulfillment_order",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The order",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Order"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "ORDER_NOT_FOUND"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            },
            "patch": {
                "tags": [
                    "Fulfillment"
                ],
                "summary": "Change notes, quote validity, expected delivery or store",
                "description": "Only the keys passed change; an empty string clears notes, valid_until or expected_delivery_at.",
                "operationId": "patch_api_fulfillment_order_update",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "notes": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "valid_until": {
                                        "type": "string",
                                        "format": "date",
                                        "nullable": true
                                    },
                                    "expected_delivery_at": {
                                        "type": "string",
                                        "format": "date",
                                        "nullable": true
                                    },
                                    "store_id": {
                                        "type": "integer",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The order",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Order"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "INVALID_DATE"
                    },
                    "404": {
                        "description": "ORDER_NOT_FOUND | STORE_NOT_FOUND"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/fulfillment/orders/from-bag": {
            "post": {
                "tags": [
                    "Fulfillment"
                ],
                "summary": "Create an order from a bag",
                "description": "Every line of the bag becomes an order line, frozen as it is today (piece, price, cost, markup and the active manufacturer). A client bag already says whose it is; the counter bag needs client_id. The bag is kept as history (status ordered) and stops being the open bag.",
                "operationId": "post_api_fulfillment_order_from_bag",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "bag_id"
                                ],
                                "properties": {
                                    "bag_id": {
                                        "type": "integer"
                                    },
                                    "client_id": {
                                        "type": "integer",
                                        "nullable": true
                                    },
                                    "store_id": {
                                        "type": "integer",
                                        "nullable": true
                                    },
                                    "status": {
                                        "type": "string",
                                        "default": "ordered",
                                        "enum": [
                                            "draft",
                                            "quote",
                                            "ordered"
                                        ]
                                    },
                                    "notes": {
                                        "type": "string",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "The new order",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Order"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "BAG_EMPTY | BAG_ALREADY_ORDERED | CLIENT_REQUIRED | MIXED_CURRENCIES | INVALID_ORDER_STATUS"
                    },
                    "404": {
                        "description": "BAG_NOT_FOUND | CLIENT_NOT_FOUND | STORE_NOT_FOUND"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/fulfillment/orders/from-design": {
            "post": {
                "tags": [
                    "Fulfillment"
                ],
                "summary": "Create a one-line order from a piece saved for a client",
                "description": "The piece must belong to the client (Client Book). Priced today with the active manufacturer and markup.",
                "operationId": "post_api_fulfillment_order_from_design",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "client_id",
                                    "design_id"
                                ],
                                "properties": {
                                    "client_id": {
                                        "type": "integer"
                                    },
                                    "design_id": {
                                        "type": "integer"
                                    },
                                    "quantity": {
                                        "type": "integer",
                                        "default": 1
                                    },
                                    "store_id": {
                                        "type": "integer",
                                        "nullable": true
                                    },
                                    "status": {
                                        "type": "string",
                                        "default": "ordered",
                                        "enum": [
                                            "draft",
                                            "quote",
                                            "ordered"
                                        ]
                                    },
                                    "notes": {
                                        "type": "string",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "The new order",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Order"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "DESIGN_NOT_OF_CLIENT | INVALID_ORDER_STATUS"
                    },
                    "404": {
                        "description": "CLIENT_NOT_FOUND | DESIGN_NOT_FOUND | STORE_NOT_FOUND"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/fulfillment/orders/{id}/convert": {
            "post": {
                "tags": [
                    "Fulfillment"
                ],
                "summary": "Turn a quote (or draft) into a confirmed order",
                "description": "A quote still valid keeps the prices it was given. An expired one needs reprice: true, which freezes every line again at today's price, cost, markup and active manufacturer (the timeline keeps the previous total).",
                "operationId": "post_api_fulfillment_order_convert",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "reprice": {
                                        "type": "boolean",
                                        "default": false
                                    },
                                    "note": {
                                        "type": "string",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The order, now confirmed",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Order"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "ORDER_NOT_A_QUOTE | QUOTE_EXPIRED | MIXED_CURRENCIES"
                    },
                    "404": {
                        "description": "ORDER_NOT_FOUND"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/fulfillment/orders/{id}/send": {
            "post": {
                "tags": [
                    "Fulfillment"
                ],
                "summary": "Email the quote or the order confirmation to the client",
                "description": "The PDF goes attached, with a link to it. To the client's email unless `to` is passed. Recorded in the timeline.",
                "operationId": "post_api_fulfillment_order_send",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "to": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "message": {
                                        "type": "string",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The order",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Order"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "CLIENT_EMAIL_REQUIRED | INVALID_EMAIL | EMAIL_NOT_SENT"
                    },
                    "404": {
                        "description": "ORDER_NOT_FOUND"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/fulfillment/orders/{id}/ship": {
            "post": {
                "tags": [
                    "Fulfillment"
                ],
                "summary": "The order leaves for the client",
                "description": "From ready: records carrier, tracking and address and moves the order to shipped.",
                "operationId": "post_api_fulfillment_order_ship",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "carrier": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "tracking": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "address": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "note": {
                                        "type": "string",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The order",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Order"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "INVALID_ORDER_TRANSITION"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/fulfillment/orders/{id}/incidents": {
            "post": {
                "tags": [
                    "Fulfillment"
                ],
                "summary": "Report an incident",
                "description": "rework, resize, damage, lost or other. With reopen_production the order goes back to the workshop with a rework job for the line (or every piece).",
                "operationId": "post_api_fulfillment_order_incident",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "type",
                                    "description"
                                ],
                                "properties": {
                                    "type": {
                                        "type": "string",
                                        "enum": [
                                            "rework",
                                            "resize",
                                            "damage",
                                            "lost",
                                            "other"
                                        ]
                                    },
                                    "description": {
                                        "type": "string"
                                    },
                                    "line_id": {
                                        "type": "integer",
                                        "nullable": true
                                    },
                                    "reopen_production": {
                                        "type": "boolean",
                                        "default": false
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The order",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Order"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "INVALID_INCIDENT_TYPE | INVALID_NOTE | INVALID_ORDER_TRANSITION | NO_PIECE_TO_REWORK | ORDER_NEEDS_MANUFACTURER"
                    },
                    "404": {
                        "description": "ORDER_NOT_FOUND | ORDER_LINE_NOT_FOUND"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/fulfillment/orders/{id}/costs": {
            "post": {
                "tags": [
                    "Fulfillment"
                ],
                "summary": "Record an extra cost",
                "description": "Shipping, rework, courier\u2026 in the order currency; it lowers the real margin.",
                "operationId": "post_api_fulfillment_order_cost",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "amount",
                                    "concept"
                                ],
                                "properties": {
                                    "amount": {
                                        "type": "number"
                                    },
                                    "concept": {
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The order (margin included for those who see costs)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Order"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "INVALID_COST_AMOUNT | INVALID_NOTE"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/fulfillment/orders/{id}/status": {
            "post": {
                "tags": [
                    "Fulfillment"
                ],
                "summary": "Move the order to another status",
                "description": "Only the transitions the order allows (allowed_transitions). Going into production needs a manufacturer frozen on every design line. expected_delivery_at (YYYY-MM-DD) sets the date promised to the client.",
                "operationId": "post_api_fulfillment_order_status",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "status"
                                ],
                                "properties": {
                                    "status": {
                                        "type": "string",
                                        "enum": [
                                            "draft",
                                            "quote",
                                            "ordered",
                                            "in_production",
                                            "ready",
                                            "shipped",
                                            "delivered",
                                            "cancelled"
                                        ]
                                    },
                                    "note": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "expected_delivery_at": {
                                        "type": "string",
                                        "format": "date",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The order",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Order"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "INVALID_ORDER_STATUS | INVALID_ORDER_TRANSITION | ORDER_NEEDS_MANUFACTURER | INVALID_DATE"
                    },
                    "404": {
                        "description": "ORDER_NOT_FOUND"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/fulfillment/orders/{id}/notes": {
            "post": {
                "tags": [
                    "Fulfillment"
                ],
                "summary": "Add a note to the timeline",
                "operationId": "post_api_fulfillment_order_note",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "note"
                                ],
                                "properties": {
                                    "note": {
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The order",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Order"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "INVALID_NOTE"
                    },
                    "404": {
                        "description": "ORDER_NOT_FOUND"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/fulfillment/orders/{id}/payments": {
            "post": {
                "tags": [
                    "Fulfillment"
                ],
                "summary": "Record a payment made outside the platform",
                "description": "A deposit or the balance, taken by hand (no gateway): amount in the order currency, method and an optional reference. It cannot exceed the balance due.",
                "operationId": "post_api_fulfillment_order_payment",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "amount",
                                    "method"
                                ],
                                "properties": {
                                    "amount": {
                                        "type": "number"
                                    },
                                    "method": {
                                        "type": "string",
                                        "enum": [
                                            "cash",
                                            "card",
                                            "transfer",
                                            "other"
                                        ]
                                    },
                                    "reference": {
                                        "type": "string",
                                        "nullable": true
                                    },
                                    "note": {
                                        "type": "string",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The order",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Order"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "INVALID_PAYMENT_AMOUNT | INVALID_PAYMENT_METHOD | PAYMENT_EXCEEDS_BALANCE | ORDER_CLOSED"
                    },
                    "404": {
                        "description": "ORDER_NOT_FOUND"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/fulfillment/orders/{id}/pdf": {
            "get": {
                "tags": [
                    "Fulfillment"
                ],
                "summary": "The order confirmation for the client, as PDF",
                "description": "No costs or markups: a document for the buyer.",
                "operationId": "get_api_fulfillment_order_pdf",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "application/pdf"
                    },
                    "404": {
                        "description": "ORDER_NOT_FOUND"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/media": {
            "get": {
                "tags": [
                    "Media"
                ],
                "summary": "Get all media files",
                "description": "Returns all media files for the organization",
                "operationId": "get_app_media_apimedia_getmedialist",
                "responses": {
                    "200": {
                        "description": "Media files retrieved successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            },
            "post": {
                "tags": [
                    "Media"
                ],
                "summary": "Upload media file",
                "description": "Uploads a new media file (jpg, png, hdr, exr)",
                "operationId": "post_app_media_apimedia_postuploadmedia",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "required": [
                                    "file"
                                ],
                                "properties": {
                                    "description": {
                                        "description": "Optional description",
                                        "type": "string"
                                    },
                                    "file": {
                                        "description": "Media file (jpg, png, hdr, exr)",
                                        "type": "string",
                                        "format": "binary"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Media file uploaded successfully"
                    },
                    "400": {
                        "description": "Invalid file or data"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/media/{id}": {
            "get": {
                "tags": [
                    "Media"
                ],
                "summary": "Get media file by ID",
                "description": "Returns a media file by its ID",
                "operationId": "get_app_media_apimedia_getmediabyid",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Media file retrieved successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Media file not found"
                    }
                }
            },
            "put": {
                "tags": [
                    "Media"
                ],
                "summary": "Update media file",
                "description": "Updates an existing media file",
                "operationId": "put_app_media_apimedia_updatemedia",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "name": {
                                        "description": "File name",
                                        "type": "string"
                                    },
                                    "description": {
                                        "description": "Description",
                                        "type": "string"
                                    },
                                    "metadata": {
                                        "description": "Additional metadata",
                                        "type": "object"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Media file updated successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Media file not found"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Media"
                ],
                "summary": "Delete media file",
                "description": "Deletes a media file by its ID",
                "operationId": "delete_app_media_apimedia_deletemedia",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Media file deleted successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Media file not found"
                    }
                }
            },
            "patch": {
                "operationId": "patch_app_media_apimedia_updatemedia",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "default": {
                        "description": ""
                    }
                }
            }
        },
        "/v3/media/{id}/preview": {
            "post": {
                "tags": [
                    "Media"
                ],
                "summary": "Generate preview",
                "description": "Generates or regenerates a preview for the media file",
                "operationId": "post_app_media_apimedia_generatepreview",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Preview generated successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Media file not found"
                    }
                }
            }
        },
        "/v3/media/check-duplicate": {
            "post": {
                "tags": [
                    "Media"
                ],
                "summary": "Check for duplicate",
                "description": "Checks if a file with the same hash already exists",
                "operationId": "post_app_media_apimedia_checkduplicate",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "hash"
                                ],
                                "properties": {
                                    "hash": {
                                        "description": "File hash (MD5)",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Duplicate check completed"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/public/auth/link": {
            "post": {
                "tags": [
                    "Public API"
                ],
                "summary": "Request a new access link",
                "description": "Sends a new invitation email to an address with a pending invitation, or a password-recovery email to an address with an account. The response is the same in every case (it never says whether the address is known). Rate limited per email (3 / 15 min) and per IP (30 / hour).",
                "operationId": "post_app_publico_apipublicauth_postaccesslink",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "email"
                                ],
                                "properties": {
                                    "email": {
                                        "type": "string",
                                        "format": "email"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Request accepted"
                    },
                    "400": {
                        "description": "Invalid email"
                    },
                    "429": {
                        "description": "Too many requests"
                    }
                }
            }
        },
        "/v3/public/auth/signup": {
            "post": {
                "tags": [
                    "Public API"
                ],
                "summary": "Sign up a new company",
                "description": "Creates the account of a new company and emails it a link (and a code) to confirm the address and sign in; its organization is created on the first sign-in and waits for approval. Requires a Cloudflare Turnstile token solved for the `signup` action. An address that already has an invitation or an account gets its usual access link instead; the response is the same in every case. Personal email domains (gmail, hotmail, yahoo\u2026) are refused where the deployment requires a company address. Rate limited per email (3 / 15 min) and per IP (10 / hour).",
                "operationId": "post_app_publico_apipublicauth_postsignup",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "email",
                                    "full_name",
                                    "organization",
                                    "turnstile_token"
                                ],
                                "properties": {
                                    "email": {
                                        "type": "string",
                                        "format": "email"
                                    },
                                    "full_name": {
                                        "type": "string",
                                        "maxLength": 120
                                    },
                                    "organization": {
                                        "type": "string",
                                        "maxLength": 120
                                    },
                                    "lang": {
                                        "description": "LCID of the language the person signs up in (1033, 1034\u2026)",
                                        "type": "string"
                                    },
                                    "turnstile_token": {
                                        "description": "The cf-turnstile-response of the widget",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Request accepted"
                    },
                    "400": {
                        "description": "INVALID_EMAIL, NAME_REQUIRED, ORGANIZATION_REQUIRED or COMPANY_EMAIL_REQUIRED"
                    },
                    "403": {
                        "description": "CAPTCHA_FAILED"
                    },
                    "429": {
                        "description": "Too many requests"
                    }
                }
            }
        },
        "/v3/public/check/vat/{country}/{vat}": {
            "get": {
                "tags": [
                    "Public API"
                ],
                "summary": "Validate VAT number",
                "description": "Checks if a VAT number is valid",
                "operationId": "get_app_publico_apipublic_getvatnumberpublic",
                "parameters": [
                    {
                        "name": "country",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "vat",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "VAT validation result"
                    },
                    "400": {
                        "description": "Invalid VAT format"
                    }
                }
            }
        },
        "/v3/public/health": {
            "get": {
                "tags": [
                    "Public API"
                ],
                "summary": "Health check endpoint",
                "description": "Verifies the API is operational and returns health status information",
                "operationId": "get_app_publico_apipublic_gethealth",
                "responses": {
                    "200": {
                        "description": "API is healthy",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "example": "ok"
                                        },
                                        "timestamp": {
                                            "type": "integer"
                                        },
                                        "version": {
                                            "type": "string",
                                            "example": "1.0.0"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/v3/public/search": {
            "post": {
                "tags": [
                    "Public API"
                ],
                "summary": "Public search endpoint",
                "description": "Search functionality accessible without authentication",
                "operationId": "post_app_publico_apipublic_postsearch",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "query"
                                ],
                                "properties": {
                                    "query": {
                                        "description": "Search query string",
                                        "type": "string"
                                    },
                                    "limit": {
                                        "description": "Maximum number of results to return",
                                        "type": "integer",
                                        "default": 10
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Search results",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "array",
                                    "items": {
                                        "properties": {
                                            "id": {
                                                "type": "string"
                                            },
                                            "title": {
                                                "type": "string"
                                            },
                                            "score": {
                                                "type": "number"
                                            }
                                        },
                                        "type": "object"
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Query parameter is required"
                    }
                }
            }
        },
        "/v3/public/webcomponent/diamond/search": {
            "post": {
                "tags": [
                    "Public Webcomponent"
                ],
                "summary": "Search the store diamonds of an organization",
                "description": "Filtered, paginated search over every diamond of the organization identified by the apikey header (all its groups). Prices are retail (markup applied). Public endpoint intended for embeddable webcomponents.",
                "operationId": "post_app_publico_apipublicdiamond_postsearchdiamonds",
                "parameters": [
                    {
                        "name": "apikey",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "shapes": {
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        },
                                        "nullable": true
                                    },
                                    "types": {
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "enum": [
                                                "EARTH",
                                                "LAB"
                                            ]
                                        },
                                        "nullable": true
                                    },
                                    "labs": {
                                        "description": "GIA, IGI, GCAL\u2026",
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        },
                                        "nullable": true
                                    },
                                    "cut": {
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        },
                                        "nullable": true
                                    },
                                    "color": {
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        },
                                        "nullable": true
                                    },
                                    "clarity": {
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        },
                                        "nullable": true
                                    },
                                    "carat_min": {
                                        "type": "number",
                                        "nullable": true
                                    },
                                    "carat_max": {
                                        "type": "number",
                                        "nullable": true
                                    },
                                    "price_min": {
                                        "description": "Over the retail price",
                                        "type": "number",
                                        "nullable": true
                                    },
                                    "price_max": {
                                        "description": "Over the retail price",
                                        "type": "number",
                                        "nullable": true
                                    },
                                    "sort_mode": {
                                        "type": "string",
                                        "nullable": true,
                                        "default": "price-asc",
                                        "enum": [
                                            "price-asc",
                                            "price-desc",
                                            "date-asc",
                                            "date-desc",
                                            "carat-asc",
                                            "carat-desc",
                                            "color-asc",
                                            "color-desc"
                                        ]
                                    },
                                    "page": {
                                        "type": "integer",
                                        "nullable": true,
                                        "default": 0
                                    },
                                    "page_size": {
                                        "type": "integer",
                                        "nullable": true,
                                        "default": 24,
                                        "maximum": 100
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Paginated diamonds with retail prices",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "total": {
                                            "type": "integer"
                                        },
                                        "page": {
                                            "type": "integer"
                                        },
                                        "page_size": {
                                            "type": "integer"
                                        },
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "object"
                                            }
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "NO_ACTIVE_MARKUP"
                    },
                    "403": {
                        "description": "INVALID_APIKEY"
                    }
                }
            }
        },
        "/v3/public/webcomponent/diamond/{id}": {
            "get": {
                "tags": [
                    "Public Webcomponent"
                ],
                "summary": "Get a store diamond by id",
                "description": "Returns one diamond of the organization identified by the apikey header, with its retail price. Public endpoint intended for embeddable webcomponents.",
                "operationId": "get_app_publico_apipublicdiamond_getdiamondbyid",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "apikey",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Diamond data with retail price",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "NO_ACTIVE_MARKUP | INVALID_DIAMOND"
                    },
                    "403": {
                        "description": "INVALID_APIKEY"
                    }
                }
            }
        },
        "/v3/public/webcomponent/diamond/{id}/similar": {
            "get": {
                "tags": [
                    "Public Webcomponent"
                ],
                "summary": "Get store diamonds similar to the given one",
                "description": "Returns similar diamonds (same shape and type, closest carat and price) of the organization identified by the apikey header, with retail prices. Public endpoint intended for embeddable webcomponents.",
                "operationId": "get_app_publico_apipublicdiamond_getsimilardiamonds",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "apikey",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Similar diamonds with retail prices",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "array",
                                    "items": {
                                        "type": "object"
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "NO_ACTIVE_MARKUP | INVALID_DIAMOND"
                    },
                    "403": {
                        "description": "INVALID_APIKEY"
                    }
                }
            }
        },
        "/v3/public/orders/{token}.pdf": {
            "get": {
                "tags": [
                    "Fulfillment"
                ],
                "summary": "The order confirmation PDF, by its private token",
                "description": "The link that get_order_pdf_url returns. No session: whoever has the token sees the client document (no costs or markups).",
                "operationId": "get_public_order_pdf",
                "parameters": [
                    {
                        "name": "token",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "[A-Za-z0-9_-]{16,32}"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "application/pdf"
                    },
                    "404": {
                        "description": "ORDER_NOT_FOUND"
                    }
                },
                "security": []
            }
        },
        "/v3/developer/user": {
            "get": {
                "tags": [
                    "Developer"
                ],
                "summary": "Get developer API keys",
                "description": "Returns all user developer API keys",
                "operationId": "get_app_shared_apideveloperuser_getuserdeveloper",
                "responses": {
                    "200": {
                        "description": "API keys retrieved successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            },
            "post": {
                "tags": [
                    "Developer"
                ],
                "summary": "Create developer API key",
                "description": "Creates a new developer user API key",
                "operationId": "post_app_shared_apideveloperuser_postnewdeveloperuser",
                "responses": {
                    "201": {
                        "description": "API key created successfully"
                    },
                    "400": {
                        "description": "Invalid data"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/developer/user/{id}": {
            "post": {
                "tags": [
                    "Developer"
                ],
                "summary": "Edit developer API key",
                "description": "Updates an existing developer user API key",
                "operationId": "post_app_shared_apideveloperuser_posteditapikey",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "API key updated successfully"
                    },
                    "400": {
                        "description": "Invalid data"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "API key not found"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Developer"
                ],
                "summary": "Delete developer API key",
                "description": "Deletes a developer user API key",
                "operationId": "delete_app_shared_apideveloperuser_deleteapikey",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "API key deleted successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "API key not found"
                    }
                }
            }
        },
        "/v3/exchange": {
            "get": {
                "tags": [
                    "Exchange"
                ],
                "summary": "Get available currencies",
                "description": "Returns the list of available currency codes in the latest market snapshot",
                "operationId": "get_app_shared_apiexchange_getavailablecurrencies",
                "responses": {
                    "200": {
                        "description": "Currencies retrieved successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/exchange/{code}": {
            "get": {
                "tags": [
                    "Exchange"
                ],
                "summary": "Get exchange rate based on USD",
                "description": "Returns the exchange rate from USD to the given 3-letter currency code",
                "operationId": "get_app_shared_apiexchange_getexchangebycode",
                "parameters": [
                    {
                        "name": "code",
                        "in": "path",
                        "description": "ISO 4217 currency code (3 letters)",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Exchange rate retrieved successfully"
                    },
                    "400": {
                        "description": "Invalid currency code"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Currency not found"
                    }
                }
            }
        },
        "/v3/exchange/{from}/{to}": {
            "get": {
                "tags": [
                    "Exchange"
                ],
                "summary": "Get exchange rate between two currencies",
                "description": "Returns the exchange rate from the source currency to the target currency",
                "operationId": "get_app_shared_apiexchange_getexchangerate",
                "parameters": [
                    {
                        "name": "from",
                        "in": "path",
                        "description": "Source ISO 4217 currency code (3 letters)",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "to",
                        "in": "path",
                        "description": "Target ISO 4217 currency code (3 letters)",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Exchange rate retrieved successfully"
                    },
                    "400": {
                        "description": "Invalid currency code"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Currency not found"
                    }
                }
            }
        },
        "/v3/market": {
            "get": {
                "tags": [
                    "Market"
                ],
                "summary": "Get latest LBMA metal prices in USD",
                "description": "Returns the latest stored LBMA metal prices (gold AM/PM, silver, platinum AM/PM, palladium AM/PM) in USD.",
                "operationId": "get_app_shared_apimarket_getmarketusd",
                "responses": {
                    "200": {
                        "description": "Market prices retrieved successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "No market data available"
                    }
                }
            }
        },
        "/v3/market/{currency}": {
            "get": {
                "tags": [
                    "Market"
                ],
                "summary": "Get latest LBMA metal prices in a target currency",
                "description": "Latest LBMA fixings (USD/toz, from rhinoartisan.com metal-prices.json) converted to the requested ISO 4217 currency with the FX rates of rhinoartisan.com currency.json. Cached 15 minutes.",
                "operationId": "get_app_shared_apimarket_getmarketbycurrency",
                "parameters": [
                    {
                        "name": "currency",
                        "in": "path",
                        "description": "ISO 4217 currency code (3 letters)",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Market prices retrieved successfully"
                    },
                    "400": {
                        "description": "Invalid currency code"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "Currency or market data not found"
                    }
                }
            }
        },
        "/v3/me/avatar": {
            "post": {
                "tags": [
                    "User Profile"
                ],
                "summary": "Upload user avatar",
                "description": "Uploads the user's profile photo/avatar",
                "operationId": "post_app_shared_apimeavatarbackground_postavatar",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "properties": {
                                    "avatar": {
                                        "description": "Avatar image file",
                                        "type": "string",
                                        "format": "binary"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Avatar uploaded successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            },
            "delete": {
                "tags": [
                    "User Profile"
                ],
                "summary": "Delete user avatar",
                "description": "Deletes the user's profile photo/avatar",
                "operationId": "delete_app_shared_apimeavatarbackground_deleteavatar",
                "responses": {
                    "200": {
                        "description": "Avatar deleted successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/me/edit": {
            "post": {
                "tags": [
                    "User Profile"
                ],
                "summary": "Update user profile",
                "description": "Updates user information including profile data, avatar, and background",
                "operationId": "post_app_shared_apime_posteditme",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "properties": {
                                    "data": {
                                        "description": "JSON string with user profile data",
                                        "type": "string"
                                    },
                                    "avatar": {
                                        "description": "Avatar image file",
                                        "type": "string",
                                        "format": "binary"
                                    },
                                    "background": {
                                        "description": "Background image file",
                                        "type": "string",
                                        "format": "binary"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "User profile updated successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/me": {
            "get": {
                "tags": [
                    "User Profile"
                ],
                "summary": "Get current user information",
                "description": "Returns the authenticated user with the organization they are working in (`organization`, `member`), every organization they belong to (`organizations`, the current one flagged `active`), the invitations waiting for them (`invitations`) and `organization_choice_pending` when they belong to several and have not picked one yet.",
                "operationId": "get_app_shared_apime_getme",
                "responses": {
                    "200": {
                        "description": "User information retrieved successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            },
            "delete": {
                "tags": [
                    "User Profile"
                ],
                "summary": "Delete user account",
                "description": "Deletes the current user's account",
                "operationId": "delete_app_shared_apime_deleteuser",
                "responses": {
                    "200": {
                        "description": "User deleted successfully"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    },
                    "404": {
                        "description": "User not deleted"
                    }
                }
            }
        },
        "/v3/me/check/vat/{country}/{vat}": {
            "get": {
                "tags": [
                    "User Profile"
                ],
                "summary": "Validate VAT number",
                "description": "Checks if a VAT number is valid for the given country",
                "operationId": "get_app_shared_apime_getvatnumber",
                "parameters": [
                    {
                        "name": "country",
                        "in": "path",
                        "description": "Country code",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "vat",
                        "in": "path",
                        "description": "VAT number",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "VAT validation result returned"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/me/check/email/{email}": {
            "get": {
                "tags": [
                    "User Profile"
                ],
                "summary": "Check email availability",
                "description": "Checks if an email address is available for use",
                "operationId": "get_app_shared_apime_getchecknoninuseemail",
                "parameters": [
                    {
                        "name": "email",
                        "in": "path",
                        "description": "Email address to check",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Email availability status returned"
                    },
                    "400": {
                        "description": "Invalid email format"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/me/check/username/{username}": {
            "get": {
                "tags": [
                    "User Profile"
                ],
                "summary": "Check username availability",
                "description": "Checks if a username is available for use",
                "operationId": "get_app_shared_apime_getchecknoninuseusername",
                "parameters": [
                    {
                        "name": "username",
                        "in": "path",
                        "description": "Username to check",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Username availability status returned"
                    },
                    "400": {
                        "description": "Invalid username format"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/me/feedback": {
            "post": {
                "tags": [
                    "User Profile"
                ],
                "summary": "Send user feedback",
                "description": "Sends feedback from the user about the application",
                "operationId": "post_app_shared_apime_postmefeedback",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "data": {
                                        "description": "JSON string with comment and url",
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Feedback sent successfully"
                    },
                    "400": {
                        "description": "Invalid request data"
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Access denied"
                    }
                }
            }
        },
        "/v3/me/organization": {
            "post": {
                "tags": [
                    "User Profile"
                ],
                "summary": "Switch organization",
                "description": "For people who belong to several organizations: from now on they work in this one, and it is remembered for their next sessions and devices. Not available with an API key, which always works in the organization it was created in.",
                "operationId": "post_app_shared_apimeorganizations_switchorganization",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "organization_id"
                                ],
                                "properties": {
                                    "organization_id": {
                                        "type": "integer"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The user, as GET /v3/me, already in that organization"
                    },
                    "400": {
                        "description": "ORGANIZATION_ID_REQUIRED | API_KEY_IS_BOUND_TO_ITS_ORGANIZATION"
                    },
                    "404": {
                        "description": "ORGANIZATION_NOT_FOUND (not a member of it)"
                    }
                }
            }
        },
        "/v3/me/organizations": {
            "post": {
                "tags": [
                    "User Profile"
                ],
                "summary": "Create another organization",
                "description": "Registers one more organization owned by the user. Like a signup, it starts pending approval: the team activates it from the admin and the owner gets an email; until then it cannot be used. The user stays in the organization they were working in. Only one pending organization of their own at a time. Not available with an API key.",
                "operationId": "post_app_shared_apimeorganizations_createorganization",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "name"
                                ],
                                "properties": {
                                    "name": {
                                        "type": "string"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "The user, as GET /v3/me, with the new organization among `organizations` (pending_approval)"
                    },
                    "400": {
                        "description": "NAME_REQUIRED | ORGANIZATION_ALREADY_PENDING | API_KEY_IS_BOUND_TO_ITS_ORGANIZATION | NOT_AVAILABLE_IN_SUPPORT_ACCESS"
                    }
                }
            }
        },
        "/v3/me/organizations/{id}/leave": {
            "post": {
                "tags": [
                    "User Profile"
                ],
                "summary": "Leave an organization",
                "description": "Removes the user from one of their organizations. What they owned in it goes to one of its owners, and their API keys for it stop working. The only owner cannot leave.",
                "operationId": "post_app_shared_apimeorganizations_leaveorganization",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The user, as GET /v3/me"
                    },
                    "400": {
                        "description": "ORGANIZATION_NEEDS_AN_OWNER"
                    },
                    "404": {
                        "description": "ORGANIZATION_NOT_FOUND (not a member of it)"
                    }
                }
            }
        },
        "/v3/me/invitations/{id}/accept": {
            "post": {
                "tags": [
                    "User Profile"
                ],
                "summary": "Accept an invitation",
                "description": "Joins the organization that invited the user's email (`invitations` of GET /v3/me). The user stays in the organization they were working in; switching is a separate call.",
                "operationId": "post_app_shared_apimeorganizations_acceptinvitation",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The user, as GET /v3/me"
                    },
                    "404": {
                        "description": "INVITATION_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/me/invitations/{id}/decline": {
            "post": {
                "tags": [
                    "User Profile"
                ],
                "summary": "Decline an invitation",
                "operationId": "post_app_shared_apimeorganizations_declineinvitation",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The user, as GET /v3/me"
                    },
                    "404": {
                        "description": "INVITATION_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/template": {
            "get": {
                "tags": [
                    "Template"
                ],
                "summary": "Browse the template library",
                "description": "Designs published as templates by the Bespoke team, newest first. Same for every organization.",
                "operationId": "get_app_shared_apitemplate_list",
                "responses": {
                    "200": {
                        "description": "Templates"
                    },
                    "401": {
                        "description": "Unauthorized"
                    }
                }
            }
        },
        "/v3/template/{id}/copy": {
            "post": {
                "tags": [
                    "Template"
                ],
                "summary": "Copy a template into my organization",
                "description": "Creates an independent design owned by the caller (is_template = false, source_design_id = the template), files included, without recomputing. Optionally drops it into a collection of the caller's organization.",
                "operationId": "post_app_shared_apitemplate_copy",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "collection_id": {
                                        "type": "integer",
                                        "nullable": true
                                    },
                                    "name": {
                                        "description": "Defaults to the template's name",
                                        "type": "string",
                                        "nullable": true
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The new design"
                    },
                    "400": {
                        "description": "COLLECTION_NOT_FOUND"
                    },
                    "404": {
                        "description": "TEMPLATE_NOT_FOUND"
                    }
                }
            }
        },
        "/v3/showroom/bag": {
            "get": {
                "tags": [
                    "Showroom"
                ],
                "summary": "The open bag of the client (or the counter bag)",
                "description": "With client_id, the open bag of that client; without it, the counter bag of the current member. An empty bag (id null) when none exists yet.",
                "operationId": "get_api_showroom_bag",
                "parameters": [
                    {
                        "name": "client_id",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The bag",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Bag"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "CLIENT_NOT_FOUND"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/showroom/bag/items": {
            "post": {
                "tags": [
                    "Showroom"
                ],
                "summary": "Add a diamond or a design to the bag",
                "description": "One of diamond_id (a stone of the active group, at today's retail price; adding it twice keeps one line) or design_id (a saved design of the organization; adding it again adds units). Creates the bag when needed.",
                "operationId": "post_api_showroom_bag_add",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "client_id": {
                                        "type": "integer",
                                        "nullable": true
                                    },
                                    "diamond_id": {
                                        "type": "integer",
                                        "nullable": true
                                    },
                                    "design_id": {
                                        "type": "integer",
                                        "nullable": true
                                    },
                                    "quantity": {
                                        "type": "integer",
                                        "nullable": true,
                                        "default": 1
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The bag",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Bag"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "DIAMOND_OR_DESIGN_REQUIRED | NO_ACTIVE_MARKUP | INVALID_DIAMOND"
                    },
                    "404": {
                        "description": "CLIENT_NOT_FOUND | DESIGN_NOT_FOUND"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/showroom/bag/items/{id}": {
            "delete": {
                "tags": [
                    "Showroom"
                ],
                "summary": "Remove a line from the bag",
                "operationId": "delete_api_showroom_bag_item_remove",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The bag",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Bag"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "BAG_ITEM_NOT_FOUND"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            },
            "patch": {
                "tags": [
                    "Showroom"
                ],
                "summary": "Change the units of a line",
                "description": "Only designs take more than one unit; a stone stays at one.",
                "operationId": "patch_api_showroom_bag_item_update",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "quantity": {
                                        "type": "integer",
                                        "minimum": 1
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The bag",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Bag"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "INVALID_QUANTITY"
                    },
                    "404": {
                        "description": "BAG_ITEM_NOT_FOUND"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/showroom/bag/{id}/assign": {
            "post": {
                "tags": [
                    "Showroom"
                ],
                "summary": "Hand the counter bag to a client",
                "description": "The counter bag becomes the client's open bag, or its lines are merged into the one the client already has (a repeated stone is kept once, a repeated design adds units).",
                "operationId": "post_api_showroom_bag_assign",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "client_id": {
                                        "type": "integer"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The client's bag",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Bag"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "BAG_ALREADY_ASSIGNED"
                    },
                    "404": {
                        "description": "BAG_NOT_FOUND | CLIENT_NOT_FOUND"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/showroom/bag/{id}/items": {
            "delete": {
                "tags": [
                    "Showroom"
                ],
                "summary": "Empty the bag",
                "operationId": "delete_api_showroom_bag_clear",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The (now empty) bag",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Bag"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "BAG_NOT_FOUND"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/showroom/collection": {
            "get": {
                "tags": [
                    "Showroom"
                ],
                "summary": "Get showroom collections",
                "operationId": "get_api_showroom_collections",
                "responses": {
                    "200": {
                        "description": "List of showroom collections",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "array",
                                    "items": {
                                        "$ref": "#/components/schemas/BoutiqueCollection"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Forbidden"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/showroom/collection/{id}": {
            "get": {
                "tags": [
                    "Showroom"
                ],
                "summary": "Get showroom collection by ID",
                "operationId": "get_api_showroom_collection",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Collection ID",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Showroom collection details",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/BoutiqueCollection"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthorized"
                    },
                    "403": {
                        "description": "Forbidden"
                    },
                    "404": {
                        "description": "Collection not found"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/showroom/design": {
            "get": {
                "tags": [
                    "Showroom"
                ],
                "summary": "Search the showroom designs",
                "description": "Designs of the published collections of the organization matching `q` (at least 2 characters, up to 60 results, best first). Every word must match, in any order, in the name, collections, type, badge, values (stone shape, metal\u2026) or description; accents and case are ignored, Spanish words are understood (alianza, oro blanco, redondo\u2026), prefixes match while typing and small typos are forgiven. Each one carries the published collection it is shown in, so the showroom can open it from there.",
                "operationId": "get_api_showroom_design_search",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "description": "Text to look for",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Matching designs, each with `collection: {id, name}`",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "array",
                                    "items": {
                                        "type": "object"
                                    }
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Forbidden"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/showroom/design/{id}": {
            "get": {
                "tags": [
                    "Showroom"
                ],
                "summary": "Get a design of the organization for the showroom",
                "description": "Same payload as /v3/backoffice/design/{id}, but for showroom members (ROLE_BOUTIQUE) who cannot enter the Back Office: lets the showroom open a collection design in Ettore.",
                "operationId": "get_api_showroom_design",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Design ID",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Design with its values and compute result"
                    },
                    "404": {
                        "description": "DESIGN_NOT_FOUND"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/showroom/diamond/search": {
            "post": {
                "tags": [
                    "Showroom"
                ],
                "summary": "Search the store diamonds for the showroom",
                "description": "Filtered, paginated search over every diamond of the organization (all its groups), with retail prices (active markup applied). Same contract as the public webcomponent search, for showroom members.",
                "operationId": "post_api_showroom_diamond_search",
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "properties": {
                                    "shapes": {
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        },
                                        "nullable": true
                                    },
                                    "types": {
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "enum": [
                                                "EARTH",
                                                "LAB"
                                            ]
                                        },
                                        "nullable": true
                                    },
                                    "labs": {
                                        "description": "GIA, IGI, GCAL\u2026",
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        },
                                        "nullable": true
                                    },
                                    "cut": {
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        },
                                        "nullable": true
                                    },
                                    "color": {
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        },
                                        "nullable": true
                                    },
                                    "clarity": {
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        },
                                        "nullable": true
                                    },
                                    "carat_min": {
                                        "type": "number",
                                        "nullable": true
                                    },
                                    "carat_max": {
                                        "type": "number",
                                        "nullable": true
                                    },
                                    "price_min": {
                                        "description": "Over the retail price",
                                        "type": "number",
                                        "nullable": true
                                    },
                                    "price_max": {
                                        "description": "Over the retail price",
                                        "type": "number",
                                        "nullable": true
                                    },
                                    "sort_mode": {
                                        "type": "string",
                                        "nullable": true,
                                        "default": "price-asc",
                                        "enum": [
                                            "price-asc",
                                            "price-desc",
                                            "date-asc",
                                            "date-desc",
                                            "carat-asc",
                                            "carat-desc",
                                            "color-asc",
                                            "color-desc"
                                        ]
                                    },
                                    "page": {
                                        "type": "integer",
                                        "nullable": true,
                                        "default": 0
                                    },
                                    "page_size": {
                                        "type": "integer",
                                        "nullable": true,
                                        "default": 24,
                                        "maximum": 100
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Paginated diamonds with retail prices",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "total": {
                                            "type": "integer"
                                        },
                                        "page": {
                                            "type": "integer"
                                        },
                                        "page_size": {
                                            "type": "integer"
                                        },
                                        "items": {
                                            "type": "array",
                                            "items": {
                                                "type": "object"
                                            }
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "NO_ACTIVE_MARKUP"
                    },
                    "403": {
                        "description": "Forbidden"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/showroom/diamond/facets": {
            "get": {
                "tags": [
                    "Showroom"
                ],
                "summary": "What the boutique diamond filters can offer",
                "description": "Counts per type (EARTH|LAB), shape and lab over every diamond of the organization, plus the carat and retail price ranges and the currency shared by its groups (null when they differ).",
                "operationId": "get_api_showroom_diamond_facets",
                "responses": {
                    "200": {
                        "description": "Facets",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "properties": {
                                        "total": {
                                            "type": "integer"
                                        },
                                        "types": {
                                            "type": "object",
                                            "additionalProperties": {
                                                "type": "integer"
                                            }
                                        },
                                        "shapes": {
                                            "type": "object",
                                            "additionalProperties": {
                                                "type": "integer"
                                            }
                                        },
                                        "labs": {
                                            "type": "object",
                                            "additionalProperties": {
                                                "type": "integer"
                                            }
                                        },
                                        "carat": {
                                            "properties": {
                                                "min": {
                                                    "type": "number",
                                                    "nullable": true
                                                },
                                                "max": {
                                                    "type": "number",
                                                    "nullable": true
                                                }
                                            },
                                            "type": "object"
                                        },
                                        "price": {
                                            "properties": {
                                                "min": {
                                                    "type": "number",
                                                    "nullable": true
                                                },
                                                "max": {
                                                    "type": "number",
                                                    "nullable": true
                                                }
                                            },
                                            "type": "object"
                                        },
                                        "currency": {
                                            "type": "string"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "NO_ACTIVE_MARKUP"
                    },
                    "403": {
                        "description": "Forbidden"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/showroom/diamond/{id}/similar": {
            "get": {
                "tags": [
                    "Showroom"
                ],
                "summary": "Store diamonds similar to the given one",
                "description": "Up to 8 stones of the organization with the same shape and type, the closest in carat and then in price, with retail prices.",
                "operationId": "get_api_showroom_diamond_similar",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Diamond ID",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Similar diamonds with retail prices",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "array",
                                    "items": {
                                        "type": "object"
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "NO_ACTIVE_MARKUP | INVALID_DIAMOND"
                    },
                    "403": {
                        "description": "Forbidden"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/showroom/diamond/{id}": {
            "get": {
                "tags": [
                    "Showroom"
                ],
                "summary": "Get a store diamond for the showroom",
                "description": "One diamond of the organization, with its retail price.",
                "operationId": "get_api_showroom_diamond",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "Diamond ID",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Diamond with retail price"
                    },
                    "400": {
                        "description": "NO_ACTIVE_MARKUP | INVALID_DIAMOND"
                    },
                    "403": {
                        "description": "Forbidden"
                    }
                },
                "security": [
                    {
                        "ApiKeyAuth": []
                    }
                ]
            }
        },
        "/v3/showroom/photo-style": {
            "get": {
                "tags": [
                    "Showroom"
                ],
                "summary": "Photo styles the Showroom can use",
                "description": "The styles with a reference photo (the Showroom one first, `showroom: true`) and how many photos are left today.",
                "operationId": "get_app_showroom_apishowroomphotostyle_list",
                "responses": {
                    "200": {
                        "description": "{styles: [{id, name, image_url, showroom}], daily_limit, used_today}"
                    }
                }
            }
        },
        "/v3/showroom/photo-style/{id}/apply": {
            "post": {
                "tags": [
                    "Showroom"
                ],
                "summary": "Apply a photo style to a viewer capture",
                "description": "Multipart: `photo` (the capture). Synchronous: waits for fal.ai and returns the result URL. Counts for the daily limit.",
                "operationId": "post_app_showroom_apishowroomphotostyle_apply",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "\\d+"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "{image_url, daily_limit, used_today}"
                    },
                    "400": {
                        "description": "SHOWROOM_PHOTOS_DISABLED, PHOTO_DAILY_LIMIT_REACHED, FALAI_API_KEY_REQUIRED, PHOTO_REQUIRED, INVALID_IMAGE, FALAI_ERROR, FALAI_NO_IMAGE"
                    },
                    "404": {
                        "description": "INVALID_PHOTO_STYLE_ID"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "BoutiqueCollection": {
                "required": [
                    "name"
                ],
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "name": {
                        "type": "string"
                    },
                    "description": {
                        "type": "string"
                    },
                    "slug": {
                        "type": "string"
                    },
                    "squareImage": {
                        "type": "string"
                    },
                    "video": {
                        "type": "string"
                    },
                    "status": {
                        "type": "integer"
                    },
                    "createdAt": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "updatedAt": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "design_count": {
                        "title": "The list's count, set by CollectionRepository::getCollectionsByOrganization (not a column).",
                        "type": "integer"
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "updated_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "sort_order": {
                        "type": "integer",
                        "default": 0
                    },
                    "square_image": {
                        "type": "string"
                    },
                    "designs": {
                        "title": "Los dise\u00f1os de la colecci\u00f3n: es lo \u00fanico que una Collection agrupa. El\nlado propietario vive en Design (design_collections).",
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Design"
                        }
                    }
                },
                "type": "object"
            },
            "Design": {
                "properties": {
                    "source_design_id": {
                        "type": "integer"
                    },
                    "capsule_id": {
                        "type": "integer"
                    },
                    "client_id": {
                        "type": "integer"
                    },
                    "id": {
                        "type": "integer"
                    },
                    "name": {
                        "type": "string"
                    },
                    "display_name": {
                        "title": "El nombre que ve el cliente en la tienda (Boutique); `name` es el interno\ndel equipo (\"Wedding Bands 22\"). Null: la tienda ense\u00f1a `name`.",
                        "type": "string"
                    },
                    "description": {
                        "type": "string"
                    },
                    "reference": {
                        "title": "La referencia de la pieza en la tienda (SKU, \"AN-0412\"): la pone\nMerchandising y la ve el Showroom. \u00danica en la organizaci\u00f3n; null sin ella.",
                        "type": "string"
                    },
                    "draft": {
                        "title": "Borrador: creado por un solve y todav\u00eda sin guardar por el usuario.",
                        "type": "boolean",
                        "default": true
                    },
                    "is_template": {
                        "title": "Dise\u00f1o de partida de la biblioteca: pertenece a la cuenta de Bespoke\ny cualquier usuario puede explorarlo y copi\u00e1rselo. Solo lo marca nuestro\nequipo (admin).",
                        "type": "boolean",
                        "default": false
                    },
                    "preview": {
                        "title": "URL p\u00fablica de la imagen de preview.",
                        "type": "string"
                    },
                    "preview_top": {
                        "title": "Render cenital (top view), misma distancia y zoom que la preview.",
                        "type": "string"
                    },
                    "preview_side": {
                        "title": "Render lateral (side view), misma distancia y zoom que la preview.",
                        "type": "string"
                    },
                    "mode": {
                        "type": "string",
                        "default": "rendering"
                    },
                    "hash": {
                        "title": "sha256 del input can\u00f3nico (configurador/capsule + modo + values). No es\n\u00fanico: dos dise\u00f1os iguales conviven; sirve para encontrarlos.",
                        "type": "string"
                    },
                    "status": {
                        "type": "string",
                        "default": "pending"
                    },
                    "error_message": {
                        "type": "string"
                    },
                    "glb_url": {
                        "type": "string"
                    },
                    "stl_url": {
                        "type": "string"
                    },
                    "glb_bytes": {
                        "type": "integer"
                    },
                    "stl_bytes": {
                        "type": "integer"
                    },
                    "semantic": {
                        "title": "La pieza en una frase, tal y como la construy\u00f3 el motor (RH_OUT:*:SEMANTIC).",
                        "type": "string"
                    },
                    "compute_cache_hash": {
                        "title": "Fila de compute_cache de la que sali\u00f3 el resultado. Con esto puesto, el\nGLB/STL viven en la carpeta de la cach\u00e9, compartidos: no se copian al\nduplicar ni se borran con el dise\u00f1o.",
                        "type": "string"
                    },
                    "duration_ms": {
                        "type": "integer"
                    },
                    "computed_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "badge": {
                        "title": "Etiqueta de merchandising sobre la foto (Boutique, lista de dise\u00f1os): un\nc\u00f3digo de la lista (`new`, `bestseller`, `essential`, `limited`), que la\napp traduce, o un texto libre corto. Null sin etiqueta.",
                        "type": "string"
                    },
                    "design_type": {
                        "title": "Tipo de pieza (RING, EARRING...), con los c\u00f3digos del Outliner de\nRhinoArtisan (App\\Model\\DesignTypes). Null sin definir.",
                        "type": "string"
                    },
                    "design_subtype": {
                        "title": "Subtipo (RING_SOLITAIRE_BASKET, ETERNITY_BAND...), uno de los de su tipo. Null sin definir.",
                        "type": "string"
                    },
                    "notes": {
                        "title": "Notas internas del retailer sobre la pieza, compartidas por el equipo.",
                        "description": "Privadas: solo en el detalle (grupo design), nunca en Boutique.",
                        "type": "string"
                    },
                    "notes_updated_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "notes_updated_by": {
                        "title": "Qui\u00e9n las toc\u00f3 por \u00faltima vez (el nombre en ese momento).",
                        "type": "string"
                    },
                    "collections": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/BoutiqueCollection"
                        }
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "updated_at": {
                        "type": "string",
                        "format": "date-time"
                    }
                },
                "type": "object"
            },
            "Bag": {
                "properties": {
                    "id": {
                        "description": "null until it has lines",
                        "type": "integer",
                        "nullable": true
                    },
                    "client_id": {
                        "type": "integer",
                        "nullable": true
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "open",
                            "ordered"
                        ]
                    },
                    "items": {
                        "type": "array",
                        "items": {
                            "properties": {
                                "id": {
                                    "type": "integer"
                                },
                                "kind": {
                                    "type": "string",
                                    "enum": [
                                        "diamond",
                                        "design"
                                    ]
                                },
                                "quantity": {
                                    "type": "integer"
                                },
                                "unit_price": {
                                    "type": "number",
                                    "nullable": true
                                },
                                "currency": {
                                    "type": "string",
                                    "nullable": true
                                },
                                "line_total": {
                                    "type": "number",
                                    "nullable": true
                                },
                                "added_at": {
                                    "type": "string",
                                    "format": "date-time"
                                },
                                "diamond": {
                                    "type": "object",
                                    "nullable": true
                                },
                                "design": {
                                    "type": "object",
                                    "nullable": true
                                }
                            },
                            "type": "object"
                        }
                    },
                    "count": {
                        "type": "integer"
                    },
                    "total": {
                        "type": "number"
                    },
                    "currency": {
                        "type": "string",
                        "nullable": true
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "updated_at": {
                        "type": "string",
                        "format": "date-time"
                    }
                },
                "type": "object"
            },
            "Order": {
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "number": {
                        "type": "string",
                        "example": "ORD-2026-00001"
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "draft",
                            "quote",
                            "ordered",
                            "in_production",
                            "ready",
                            "shipped",
                            "delivered",
                            "cancelled"
                        ]
                    },
                    "client": {
                        "properties": {
                            "id": {
                                "type": "integer"
                            },
                            "name": {
                                "type": "string"
                            },
                            "email": {
                                "type": "string",
                                "nullable": true
                            },
                            "phone": {
                                "type": "string",
                                "nullable": true
                            }
                        },
                        "type": "object",
                        "nullable": true
                    },
                    "store": {
                        "properties": {
                            "id": {
                                "type": "integer"
                            },
                            "name": {
                                "type": "string"
                            }
                        },
                        "type": "object",
                        "nullable": true
                    },
                    "seller": {
                        "properties": {
                            "id": {
                                "type": "integer"
                            },
                            "name": {
                                "type": "string"
                            }
                        },
                        "type": "object",
                        "nullable": true
                    },
                    "currency": {
                        "type": "string"
                    },
                    "subtotal": {
                        "type": "number"
                    },
                    "tax_name": {
                        "type": "string",
                        "nullable": true
                    },
                    "tax_rate": {
                        "description": "Percentage",
                        "type": "number"
                    },
                    "tax_included": {
                        "description": "Line prices already include the tax",
                        "type": "boolean"
                    },
                    "tax_amount": {
                        "type": "number"
                    },
                    "total": {
                        "type": "number"
                    },
                    "paid_amount": {
                        "type": "number"
                    },
                    "balance": {
                        "type": "number"
                    },
                    "notes": {
                        "type": "string",
                        "nullable": true
                    },
                    "preview": {
                        "description": "First piece photo (list only)",
                        "type": "string",
                        "nullable": true
                    },
                    "lines_count": {
                        "type": "integer"
                    },
                    "lines": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/OrderLine"
                        }
                    },
                    "events": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/OrderEvent"
                        }
                    },
                    "allowed_transitions": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "can_produce": {
                        "description": "Every design line has a manufacturer frozen",
                        "type": "boolean"
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "confirmed_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "expected_delivery_at": {
                        "type": "string",
                        "format": "date",
                        "nullable": true
                    },
                    "valid_until": {
                        "description": "Quote validity",
                        "type": "string",
                        "format": "date",
                        "nullable": true
                    },
                    "expired": {
                        "description": "A quote past its validity",
                        "type": "boolean"
                    },
                    "sent_at": {
                        "description": "Last time it was emailed to the client",
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "shipping_carrier": {
                        "type": "string",
                        "nullable": true
                    },
                    "shipping_tracking": {
                        "type": "string",
                        "nullable": true
                    },
                    "shipping_address": {
                        "type": "string",
                        "nullable": true
                    },
                    "shipped_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "jobs": {
                        "description": "Workshop jobs (detail only)",
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/ProductionJob"
                        }
                    },
                    "margin": {
                        "description": "Only for those who see costs",
                        "properties": {
                            "revenue": {
                                "type": "number"
                            },
                            "lines_cost": {
                                "type": "number"
                            },
                            "extra_costs": {
                                "type": "number"
                            },
                            "margin": {
                                "type": "number"
                            },
                            "margin_pct": {
                                "type": "number",
                                "nullable": true
                            },
                            "lines_without_cost": {
                                "type": "integer"
                            }
                        },
                        "type": "object",
                        "nullable": true
                    },
                    "delivered_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "cancelled_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "updated_at": {
                        "type": "string",
                        "format": "date-time"
                    }
                },
                "type": "object"
            },
            "OrderLine": {
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "position": {
                        "type": "integer"
                    },
                    "kind": {
                        "type": "string",
                        "enum": [
                            "design",
                            "diamond"
                        ]
                    },
                    "design_id": {
                        "type": "integer",
                        "nullable": true
                    },
                    "diamond_id": {
                        "type": "integer",
                        "nullable": true
                    },
                    "name": {
                        "type": "string"
                    },
                    "preview": {
                        "type": "string",
                        "nullable": true
                    },
                    "quantity": {
                        "type": "integer"
                    },
                    "unit_price": {
                        "type": "number"
                    },
                    "line_total": {
                        "type": "number"
                    },
                    "currency": {
                        "type": "string"
                    },
                    "snapshot": {
                        "description": "The frozen piece: capsule, record, values_resolved, tech, breakdown, metal, size, engraving, stones, pricing, manufacturer",
                        "type": "object"
                    },
                    "cost": {
                        "description": "Only for Owner, Fulfillment, Merchandising and Settings",
                        "type": "number",
                        "nullable": true
                    },
                    "markup_percentage": {
                        "description": "Only for Owner, Fulfillment, Merchandising and Settings",
                        "type": "number",
                        "nullable": true
                    },
                    "manufacturer": {
                        "description": "Only for Owner, Fulfillment, Merchandising and Settings",
                        "properties": {
                            "id": {
                                "type": "integer",
                                "nullable": true
                            },
                            "name": {
                                "type": "string"
                            }
                        },
                        "type": "object",
                        "nullable": true
                    }
                },
                "type": "object"
            },
            "ProductionJob": {
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "order": {
                        "description": "List only",
                        "properties": {
                            "id": {
                                "type": "integer"
                            },
                            "number": {
                                "type": "string"
                            },
                            "status": {
                                "type": "string"
                            },
                            "client": {
                                "type": "string",
                                "nullable": true
                            },
                            "expected_delivery_at": {
                                "type": "string",
                                "format": "date",
                                "nullable": true
                            }
                        },
                        "type": "object"
                    },
                    "line": {
                        "properties": {
                            "id": {
                                "type": "integer"
                            },
                            "name": {
                                "type": "string"
                            },
                            "preview": {
                                "type": "string",
                                "nullable": true
                            },
                            "design_id": {
                                "type": "integer",
                                "nullable": true
                            }
                        },
                        "type": "object"
                    },
                    "manufacturer_id": {
                        "type": "integer",
                        "nullable": true
                    },
                    "manufacturer_name": {
                        "type": "string",
                        "nullable": true
                    },
                    "kind": {
                        "type": "string",
                        "enum": [
                            "production",
                            "rework"
                        ]
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "pending",
                            "sent",
                            "in_progress",
                            "done",
                            "cancelled"
                        ]
                    },
                    "allowed_transitions": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "quantity": {
                        "type": "integer"
                    },
                    "stl_url": {
                        "type": "string",
                        "nullable": true
                    },
                    "stl_status": {
                        "type": "string",
                        "enum": [
                            "ready",
                            "pending",
                            "failed"
                        ]
                    },
                    "stl_error": {
                        "type": "string",
                        "nullable": true
                    },
                    "tech_sheet": {
                        "description": "Piece, metal, size, engraving, stones, record, tech; no prices",
                        "type": "object"
                    },
                    "notes": {
                        "type": "string",
                        "nullable": true
                    },
                    "sent_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "started_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "done_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "updated_at": {
                        "type": "string",
                        "format": "date-time"
                    }
                },
                "type": "object"
            },
            "OrderEvent": {
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "kind": {
                        "type": "string",
                        "enum": [
                            "created",
                            "status",
                            "payment",
                            "note",
                            "email",
                            "job",
                            "shipment",
                            "incident",
                            "cost"
                        ]
                    },
                    "status_from": {
                        "type": "string",
                        "nullable": true
                    },
                    "status_to": {
                        "type": "string",
                        "nullable": true
                    },
                    "amount": {
                        "description": "Payment amount, in the order currency",
                        "type": "number",
                        "nullable": true
                    },
                    "method": {
                        "type": "string",
                        "nullable": true,
                        "enum": [
                            "cash",
                            "card",
                            "transfer",
                            "other"
                        ]
                    },
                    "reference": {
                        "type": "string",
                        "nullable": true
                    },
                    "note": {
                        "type": "string",
                        "nullable": true
                    },
                    "author": {
                        "properties": {
                            "id": {
                                "type": "integer",
                                "nullable": true
                            },
                            "name": {
                                "type": "string"
                            }
                        },
                        "type": "object",
                        "nullable": true
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    }
                },
                "type": "object"
            }
        },
        "securitySchemes": {
            "ApiKeyAuth": {
                "type": "apiKey",
                "name": "apikey",
                "in": "header"
            }
        }
    },
    "security": [
        {
            "ApiKeyAuth": []
        }
    ],
    "tags": [
        {
            "name": "Admin",
            "description": "Admin"
        },
        {
            "name": "Admin > Board",
            "description": "Admin > Board"
        },
        {
            "name": "Analytics",
            "description": "Analytics"
        },
        {
            "name": "Assistant",
            "description": "Assistant"
        },
        {
            "name": "Back Office > Account",
            "description": "Back Office > Account"
        },
        {
            "name": "AI Assistant",
            "description": "AI Assistant"
        },
        {
            "name": "Back Office > Bug reports",
            "description": "Back Office > Bug reports"
        },
        {
            "name": "Camera view",
            "description": "Camera view"
        },
        {
            "name": "Knowledge Capsule",
            "description": "Knowledge Capsule"
        },
        {
            "name": "Catalogue",
            "description": "Catalogue"
        },
        {
            "name": "Collection",
            "description": "Collection"
        },
        {
            "name": "Design",
            "description": "Design"
        },
        {
            "name": "Design standards",
            "description": "Design standards"
        },
        {
            "name": "Diamond > Certified",
            "description": "Diamond > Certified"
        },
        {
            "name": "Diamond > Gemstones",
            "description": "Diamond > Gemstones"
        },
        {
            "name": "Diamond > Group",
            "description": "Diamond > Group"
        },
        {
            "name": "Diamond group",
            "description": "Diamond group"
        },
        {
            "name": "Back Office > Ettore",
            "description": "Back Office > Ettore"
        },
        {
            "name": "Manufacturer",
            "description": "Manufacturer"
        },
        {
            "name": "Markup",
            "description": "Markup"
        },
        {
            "name": "Back Office > Organization",
            "description": "Back Office > Organization"
        },
        {
            "name": "Photo style",
            "description": "Photo style"
        },
        {
            "name": "Simulator",
            "description": "Simulator"
        },
        {
            "name": "Back Office",
            "description": "Back Office"
        },
        {
            "name": "v3 / Store",
            "description": "v3 / Store"
        },
        {
            "name": "Tax",
            "description": "Tax"
        },
        {
            "name": "Viewer environment",
            "description": "Viewer environment"
        },
        {
            "name": "Viewer scene",
            "description": "Viewer scene"
        },
        {
            "name": "Client Book",
            "description": "Client Book"
        },
        {
            "name": "Compute",
            "description": "Compute"
        },
        {
            "name": "Developer",
            "description": "Developer"
        },
        {
            "name": "Fulfillment",
            "description": "Fulfillment"
        },
        {
            "name": "Media",
            "description": "Media"
        },
        {
            "name": "Public API",
            "description": "Public API"
        },
        {
            "name": "Public Webcomponent",
            "description": "Public Webcomponent"
        },
        {
            "name": "Exchange",
            "description": "Exchange"
        },
        {
            "name": "Market",
            "description": "Market"
        },
        {
            "name": "User Profile",
            "description": "User Profile"
        },
        {
            "name": "Template",
            "description": "Template"
        },
        {
            "name": "Showroom",
            "description": "Showroom"
        }
    ]
}