{
    "openapi": "3.0.0",
    "info": {
        "title": "LSI Events Portal — Admin API",
        "description": "Management API for the events portal. Every endpoint requires an active admin, authenticated either with a Sanctum personal access token carrying the \"admin\" ability, or with the portal session cookie. Every write is recorded in the activity log against the admin who made it.",
        "version": "1.0.0"
    },
    "servers": [
        {
            "url": "/api/admin/v1",
            "description": "Admin API v1"
        }
    ],
    "paths": {
        "/activity": {
            "get": {
                "tags": [
                    "Activity"
                ],
                "summary": "The audit trail",
                "description": "Every create, update and delete across the portal and this API, newest first. Filter with ?filter[event]=created|updated|deleted, ?filter[subject_type]=company, ?filter[causer_id]=. Include ?include=causer to see who did it.",
                "operationId": "f7ac2c65246dfac7d15e6c25d4f6089f",
                "responses": {
                    "200": {
                        "description": "A page of activity."
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/companies": {
            "get": {
                "tags": [
                    "Companies"
                ],
                "summary": "List every company, for every user",
                "description": "Filter with ?filter[search]=, ?filter[user_id]=, ?filter[trashed]=with|only. Include the owner with ?include=user.",
                "operationId": "915ce98e72e97e445613896ca9e17def",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "Companies"
                ],
                "summary": "Create a company for any user",
                "operationId": "a64afa1ac00a0071332d0de85e8c3243",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "$ref": "#/components/schemas/StoreCompany"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/companies/{company}": {
            "get": {
                "tags": [
                    "Companies"
                ],
                "summary": "Show a company",
                "operationId": "53125bf4fab648427451fddba8a6707b",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            },
            "put": {
                "tags": [
                    "Companies"
                ],
                "summary": "Update a company",
                "operationId": "5e1781c19a1eb45c60205525bcefe5c9",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "$ref": "#/components/schemas/UpdateCompany"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "Companies"
                ],
                "summary": "Soft delete a company",
                "operationId": "03c5d733ddc7d672c5090bd55d1b01e6",
                "responses": {
                    "204": {
                        "description": "Deleted"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/companies/{company}/restore": {
            "post": {
                "tags": [
                    "Companies"
                ],
                "summary": "Restore a soft-deleted company",
                "operationId": "5ba08db606bcf12b32f50f819400f36a",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/companies/{company}/logo": {
            "delete": {
                "tags": [
                    "Companies"
                ],
                "summary": "Remove the company logo",
                "operationId": "a2eed68dda757d5f71f50600f9e7766e",
                "responses": {
                    "204": {
                        "description": "Deleted"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/event-assets": {
            "get": {
                "tags": [
                    "Event assets"
                ],
                "summary": "List event assets",
                "description": "Filter with ?filter[event_id]=, ?filter[category]=. Include ?include=event.",
                "operationId": "9a73723764d9f02659b3f0de631db811",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "Event assets"
                ],
                "summary": "Create an event asset",
                "description": "multipart/form-data. Send the PDF/image as \"file\"; a title can be set with \"title\".",
                "operationId": "dd242e5d8d55bfe51082a4f90633fcee",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "$ref": "#/components/schemas/StoreEventAsset"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/event-assets/{eventAsset}": {
            "get": {
                "tags": [
                    "Event assets"
                ],
                "summary": "Show an event asset",
                "operationId": "57d033eb395f3235998e6244089ab1df",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            },
            "put": {
                "tags": [
                    "Event assets"
                ],
                "summary": "Update an event asset",
                "operationId": "3e9c833417059080093534b40e54896f",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "$ref": "#/components/schemas/UpdateEventAsset"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "Event assets"
                ],
                "summary": "Delete an event asset",
                "operationId": "205aa6e8790d0165d2ec1aa15b900b4f",
                "responses": {
                    "204": {
                        "description": "Deleted"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/events": {
            "get": {
                "tags": [
                    "Events"
                ],
                "summary": "List every event",
                "description": "Unlike the portal, past events are included. Filter with ?filter[search]=, ?filter[upcoming]=1, ?filter[trashed]=with|only. Include ?include=assets,participants.",
                "operationId": "fdc6b5b5d569eb063781a403964eb293",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "Events"
                ],
                "summary": "Create an event",
                "operationId": "89462d4ddcdcafcd8eb9828286a41851",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "$ref": "#/components/schemas/StoreEvent"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/events/{event}": {
            "get": {
                "tags": [
                    "Events"
                ],
                "summary": "Show an event",
                "operationId": "fbb5996fd26c9408daca04199b919ae0",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            },
            "put": {
                "tags": [
                    "Events"
                ],
                "summary": "Update an event",
                "operationId": "1376517eeeb456ceb5eefd142c11e5e4",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "$ref": "#/components/schemas/UpdateEvent"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "Events"
                ],
                "summary": "Soft delete an event",
                "operationId": "f434f60b43cf657b2fd237116b24c6d0",
                "responses": {
                    "204": {
                        "description": "Deleted"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/events/{event}/restore": {
            "post": {
                "tags": [
                    "Events"
                ],
                "summary": "Restore a soft-deleted event",
                "operationId": "756d62a8dd6a7ad959f8a67182cd9407",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/events/{event}/image": {
            "delete": {
                "tags": [
                    "Events"
                ],
                "summary": "Remove the event image",
                "operationId": "3230a8a7286fe5f8b5915bc769066611",
                "responses": {
                    "204": {
                        "description": "Deleted"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/events/{event}/participants": {
            "post": {
                "tags": [
                    "Events"
                ],
                "summary": "Register users for an event",
                "description": "Additive — existing participants are kept.",
                "operationId": "de13c7389374adb263fec9881f7585d5",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "required": [
                                    "user_ids"
                                ],
                                "properties": {
                                    "user_ids": {
                                        "type": "array",
                                        "items": {
                                            "type": "integer"
                                        },
                                        "example": [
                                            1,
                                            2
                                        ]
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/events/{event}/participants/{user}": {
            "delete": {
                "tags": [
                    "Events"
                ],
                "summary": "Unregister a user from an event",
                "operationId": "59c0ee273d81272175496879b04a8ec3",
                "responses": {
                    "204": {
                        "description": "Deleted"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/invoices": {
            "get": {
                "tags": [
                    "Invoices"
                ],
                "summary": "List every invoice, for every user",
                "description": "Filter with ?filter[user_id]=, ?filter[number]=, ?filter[search]=, ?filter[trashed]=with|only. Include ?include=user.",
                "operationId": "9faa4de728f46c6a8e94faec959c6901",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "Invoices"
                ],
                "summary": "Create an invoice for a user",
                "description": "multipart/form-data. Send the PDF as \"file\" — it is written to the private invoices disk, never a public URL.",
                "operationId": "2bbe1a74b1be52d0ca107796ea231fff",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "$ref": "#/components/schemas/StoreInvoice"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/invoices/{invoice}": {
            "get": {
                "tags": [
                    "Invoices"
                ],
                "summary": "Show an invoice",
                "operationId": "d3b57512c686ff597fcb662417ea7aeb",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            },
            "put": {
                "tags": [
                    "Invoices"
                ],
                "summary": "Update an invoice",
                "operationId": "a49fc24996cdedaa4124a45fdbadf10c",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "$ref": "#/components/schemas/UpdateInvoice"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "Invoices"
                ],
                "summary": "Soft delete an invoice",
                "operationId": "278d9d9cf44957bb6cfa1670b6e7ecb4",
                "responses": {
                    "204": {
                        "description": "Deleted"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/invoices/{invoice}/restore": {
            "post": {
                "tags": [
                    "Invoices"
                ],
                "summary": "Restore a soft-deleted invoice",
                "operationId": "defdf7965c5729ae2cc72d3c95453f52",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/invoices/{invoice}/download": {
            "get": {
                "tags": [
                    "Invoices"
                ],
                "summary": "Download the invoice PDF",
                "description": "Streams the file off the private disk.",
                "operationId": "8659b703f5a11c59874bcccc53957653",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/media-links": {
            "get": {
                "tags": [
                    "Media links"
                ],
                "summary": "List the photo/video links shared with users",
                "description": "Filter with ?filter[user_id]=, ?filter[search]=. Include ?include=user.",
                "operationId": "15f985bc6a9ae6828e9a771771b7eddb",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "Media links"
                ],
                "summary": "Share a media link with a user",
                "operationId": "21a4a4173026a0cf3c3ad5bf3a2c51dd",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/StoreMediaLink"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/media-links/{mediaLink}": {
            "get": {
                "tags": [
                    "Media links"
                ],
                "summary": "Show a media link",
                "operationId": "63ce215352758269cb610e0732ec5e83",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            },
            "put": {
                "tags": [
                    "Media links"
                ],
                "summary": "Update a media link",
                "operationId": "b4ddd920eafbba4e6cb7f7e91c92b1ae",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/UpdateMediaLink"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "Media links"
                ],
                "summary": "Delete a media link",
                "operationId": "b2b2284670790418d0211b792a53a3e3",
                "responses": {
                    "204": {
                        "description": "Deleted"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/users": {
            "get": {
                "tags": [
                    "Users"
                ],
                "summary": "List every user",
                "description": "Filter with ?filter[search]=, ?filter[role]=, ?filter[active]=, ?filter[trashed]=with|only. Sort with ?sort=-created_at. Include with ?include=companies,events,invoices.",
                "operationId": "aa1387d41e4c18f382aa5f02ded8e952",
                "responses": {
                    "200": {
                        "description": "A page of users."
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "Users"
                ],
                "summary": "Create a portal user",
                "description": "The new user has the \"user\" role and no password: they sign in with an emailed one-time code and choose their own password. Neither the role nor a password can be set through this API.",
                "operationId": "d7337bc8bf26c4a3852d6d31ba29d1f0",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/StoreUser"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "The user."
                    },
                    "422": {
                        "description": "Validation failed."
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/users/{user}": {
            "get": {
                "tags": [
                    "Users"
                ],
                "summary": "Show a user",
                "operationId": "4aeb3626b3e1d2d7c87f2900e115fe99",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            },
            "put": {
                "tags": [
                    "Users"
                ],
                "summary": "Update a user",
                "operationId": "4c5fbf57ea3ec6a0b183027ecb5f44b3",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/UpdateUser"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "Users"
                ],
                "summary": "Soft delete a user",
                "description": "Reversible: POST /users/{user}/restore brings them back.",
                "operationId": "aa791e478d2279ecdc859f59e18ecc7f",
                "responses": {
                    "204": {
                        "description": "Deleted."
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/users/{user}/restore": {
            "post": {
                "tags": [
                    "Users"
                ],
                "summary": "Restore a soft-deleted user",
                "operationId": "099d70e1d0ea7805c2b1968d0180cc9b",
                "responses": {
                    "200": {
                        "description": "OK"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/users/{user}/headshots": {
            "post": {
                "tags": [
                    "Users"
                ],
                "summary": "Upload one of the user's headshots",
                "description": "Images only, max 5 MB.",
                "operationId": "7987b3217f0a5578586fd46e6339695c",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "required": [
                                    "headshot"
                                ],
                                "properties": {
                                    "headshot": {
                                        "type": "string",
                                        "format": "binary"
                                    }
                                },
                                "type": "object"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "The uploaded file."
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        },
        "/users/{user}/headshots/{media}": {
            "delete": {
                "tags": [
                    "Users"
                ],
                "summary": "Delete one of the user's headshots",
                "operationId": "096571073f59f8947d3f0c2b82c665a2",
                "responses": {
                    "204": {
                        "description": "Deleted"
                    },
                    "401": {
                        "description": "Not authenticated"
                    },
                    "403": {
                        "description": "Not an admin"
                    },
                    "404": {
                        "description": "Resource not found"
                    }
                },
                "security": [
                    {
                        "sanctum": []
                    }
                ]
            }
        }
    },
    "components": {
        "schemas": {
            "StoreCompany": {
                "title": "Create a company",
                "description": "Send as multipart/form-data when including a logo.",
                "required": [
                    "user_id",
                    "name"
                ],
                "properties": {
                    "user_id": {
                        "description": "The user the company belongs to",
                        "type": "integer"
                    },
                    "name": {
                        "type": "string",
                        "example": "Acme Medical",
                        "maxLength": 255
                    },
                    "title": {
                        "description": "The user's job title at this company",
                        "type": "string",
                        "example": "CEO",
                        "nullable": true
                    },
                    "description": {
                        "type": "string",
                        "nullable": true
                    },
                    "website": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true
                    },
                    "linkedin": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true
                    },
                    "x": {
                        "type": "string",
                        "example": "@acme",
                        "nullable": true
                    },
                    "instagram": {
                        "type": "string",
                        "nullable": true
                    },
                    "billing_email": {
                        "type": "string",
                        "format": "email",
                        "nullable": true
                    },
                    "assistant_email": {
                        "type": "string",
                        "format": "email",
                        "nullable": true
                    },
                    "logo": {
                        "description": "Image, max 5 MB. Replaces the existing logo.",
                        "type": "string",
                        "format": "binary",
                        "nullable": true
                    }
                },
                "type": "object"
            },
            "UpdateCompany": {
                "title": "Update a company",
                "description": "Every field is optional. Include a logo to replace the current one; leave it out and the logo is untouched. Multipart updates must be sent as POST with _method=PUT.",
                "properties": {
                    "user_id": {
                        "type": "integer"
                    },
                    "name": {
                        "type": "string",
                        "maxLength": 255
                    },
                    "title": {
                        "type": "string",
                        "nullable": true
                    },
                    "description": {
                        "type": "string",
                        "nullable": true
                    },
                    "website": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true
                    },
                    "linkedin": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true
                    },
                    "x": {
                        "type": "string",
                        "nullable": true
                    },
                    "instagram": {
                        "type": "string",
                        "nullable": true
                    },
                    "billing_email": {
                        "type": "string",
                        "format": "email",
                        "nullable": true
                    },
                    "assistant_email": {
                        "type": "string",
                        "format": "email",
                        "nullable": true
                    },
                    "logo": {
                        "type": "string",
                        "format": "binary",
                        "nullable": true
                    }
                },
                "type": "object"
            },
            "StoreEvent": {
                "title": "Create an event",
                "required": [
                    "name",
                    "start_date",
                    "end_date"
                ],
                "properties": {
                    "name": {
                        "type": "string",
                        "example": "LSI Europe '26"
                    },
                    "start_date": {
                        "type": "string",
                        "format": "date",
                        "example": "2026-09-28"
                    },
                    "end_date": {
                        "type": "string",
                        "format": "date",
                        "example": "2026-10-01"
                    },
                    "location": {
                        "type": "string",
                        "example": "Barcelona",
                        "nullable": true
                    },
                    "registration_link": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true
                    },
                    "image": {
                        "description": "Image, max 5 MB.",
                        "type": "string",
                        "format": "binary",
                        "nullable": true
                    }
                },
                "type": "object"
            },
            "UpdateEvent": {
                "title": "Update an event",
                "description": "Include an image to replace the current one. Multipart updates must be sent as POST with _method=PUT.",
                "properties": {
                    "name": {
                        "type": "string"
                    },
                    "start_date": {
                        "type": "string",
                        "format": "date"
                    },
                    "end_date": {
                        "type": "string",
                        "format": "date"
                    },
                    "location": {
                        "type": "string",
                        "nullable": true
                    },
                    "registration_link": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true
                    },
                    "image": {
                        "type": "string",
                        "format": "binary",
                        "nullable": true
                    }
                },
                "type": "object"
            },
            "StoreEventAsset": {
                "title": "Create an event asset",
                "description": "multipart/form-data. The format column is derived from the uploaded file when not given.",
                "required": [
                    "event_id",
                    "category",
                    "file"
                ],
                "properties": {
                    "event_id": {
                        "type": "integer"
                    },
                    "category": {
                        "type": "string",
                        "example": "know_before_you_go",
                        "enum": [
                            "know_before_you_go",
                            "presenter_resources"
                        ]
                    },
                    "title": {
                        "description": "Shown as the asset name in the portal",
                        "type": "string",
                        "nullable": true
                    },
                    "format": {
                        "type": "string",
                        "example": "PDF",
                        "nullable": true
                    },
                    "order": {
                        "type": "integer",
                        "nullable": true
                    },
                    "file": {
                        "description": "PDF, image or slides. Max 50 MB.",
                        "type": "string",
                        "format": "binary"
                    }
                },
                "type": "object"
            },
            "UpdateEventAsset": {
                "title": "Update an event asset",
                "description": "Include a file to replace the current one. Multipart updates must be sent as POST with _method=PUT.",
                "properties": {
                    "event_id": {
                        "type": "integer"
                    },
                    "category": {
                        "type": "string",
                        "enum": [
                            "know_before_you_go",
                            "presenter_resources"
                        ]
                    },
                    "title": {
                        "type": "string",
                        "nullable": true
                    },
                    "format": {
                        "type": "string",
                        "nullable": true
                    },
                    "order": {
                        "type": "integer",
                        "nullable": true
                    },
                    "file": {
                        "type": "string",
                        "format": "binary",
                        "nullable": true
                    }
                },
                "type": "object"
            },
            "StoreInvoice": {
                "title": "Create an invoice",
                "description": "multipart/form-data when sending the PDF. The file is written to the private invoices disk and is only ever served through the authenticated download endpoint.",
                "required": [
                    "user_id",
                    "name"
                ],
                "properties": {
                    "user_id": {
                        "type": "integer"
                    },
                    "number": {
                        "type": "string",
                        "example": "INV-4821",
                        "nullable": true
                    },
                    "name": {
                        "type": "string",
                        "example": "LSI Asia '26 Registration"
                    },
                    "amount": {
                        "type": "number",
                        "format": "float",
                        "example": 4850,
                        "nullable": true
                    },
                    "file": {
                        "description": "PDF only, max 50 MB.",
                        "type": "string",
                        "format": "binary",
                        "nullable": true
                    }
                },
                "type": "object"
            },
            "UpdateInvoice": {
                "title": "Update an invoice",
                "description": "Include a PDF to replace the current one; leave it out and the file is untouched. Multipart updates must be sent as POST with _method=PUT.",
                "properties": {
                    "user_id": {
                        "type": "integer"
                    },
                    "number": {
                        "type": "string",
                        "nullable": true
                    },
                    "name": {
                        "type": "string"
                    },
                    "amount": {
                        "type": "number",
                        "format": "float",
                        "nullable": true
                    },
                    "file": {
                        "type": "string",
                        "format": "binary",
                        "nullable": true
                    }
                },
                "type": "object"
            },
            "StoreMediaLink": {
                "title": "Create a media link",
                "required": [
                    "user_id",
                    "name",
                    "url"
                ],
                "properties": {
                    "user_id": {
                        "type": "integer"
                    },
                    "name": {
                        "type": "string",
                        "example": "LSI Asia '26 — Presenter Kit"
                    },
                    "url": {
                        "type": "string",
                        "format": "uri"
                    },
                    "files_count": {
                        "type": "integer",
                        "nullable": true
                    },
                    "order": {
                        "type": "integer",
                        "nullable": true
                    }
                },
                "type": "object"
            },
            "UpdateMediaLink": {
                "title": "Update a media link",
                "properties": {
                    "user_id": {
                        "type": "integer"
                    },
                    "name": {
                        "type": "string"
                    },
                    "url": {
                        "type": "string",
                        "format": "uri"
                    },
                    "files_count": {
                        "type": "integer",
                        "nullable": true
                    },
                    "order": {
                        "type": "integer",
                        "nullable": true
                    }
                },
                "type": "object"
            },
            "StoreUser": {
                "title": "Create a user",
                "description": "Role and password are deliberately absent: the API only creates portal users, and they set their own password.",
                "required": [
                    "name",
                    "email"
                ],
                "properties": {
                    "name": {
                        "type": "string",
                        "example": "Ada Lovelace",
                        "maxLength": 255
                    },
                    "email": {
                        "type": "string",
                        "format": "email",
                        "example": "ada@example.com"
                    },
                    "linkedin": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true
                    },
                    "bio": {
                        "type": "string",
                        "nullable": true
                    },
                    "active": {
                        "type": "boolean",
                        "default": true
                    }
                },
                "type": "object"
            },
            "UpdateUser": {
                "title": "Update a user",
                "properties": {
                    "name": {
                        "type": "string",
                        "maxLength": 255
                    },
                    "email": {
                        "type": "string",
                        "format": "email"
                    },
                    "linkedin": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true
                    },
                    "bio": {
                        "type": "string",
                        "nullable": true
                    },
                    "active": {
                        "type": "boolean"
                    }
                },
                "type": "object"
            },
            "AdminActivity": {
                "title": "Activity log entry"
            },
            "AdminCompany": {
                "title": "Company"
            },
            "AdminEventAsset": {
                "title": "Event asset"
            },
            "AdminEvent": {
                "title": "Event"
            },
            "AdminInvoice": {
                "title": "Invoice"
            },
            "AdminMediaLink": {
                "title": "Media link"
            },
            "AdminMedia": {
                "title": "Media file"
            },
            "AdminUser": {
                "title": "User"
            }
        },
        "securitySchemes": {
            "sanctum": {
                "type": "http",
                "description": "A Sanctum personal access token with the \"admin\" ability. Mint one with `php artisan admin:token {email}`.",
                "scheme": "bearer"
            }
        }
    },
    "tags": [
        {
            "name": "Users",
            "description": "Portal users"
        },
        {
            "name": "Companies",
            "description": "Companies, and their logos"
        },
        {
            "name": "Events",
            "description": "Events, and their images"
        },
        {
            "name": "Event assets",
            "description": "Files attached to an event"
        },
        {
            "name": "Invoices",
            "description": "Invoices, and their PDFs"
        },
        {
            "name": "Media links",
            "description": "Photo/video links shared with a user"
        },
        {
            "name": "Activity",
            "description": "The audit trail"
        }
    ]
}