{
    "openapi": "3.0.3",
    "info": {
        "title": "Nudge API",
        "version": "1.0.0",
        "description": "REST API for user accounts, profiles, Firebase tokens, and reminders.\n\nAuth: register/login return a JWT in `data.token`. Send it on subsequent requests as either:\n- `token: <jwt>` header (preferred), or\n- `Authorization: Bearer <jwt>`.\n\nAll response bodies use the envelope `{ code, success, error, data }`."
    },
    "servers": [
        {
            "url": "https://nudge.gt4it.com",
            "description": "Configured APP_URL"
        }
    ],
    "tags": [
        {
            "name": "Auth",
            "description": "Public registration, login, password reset."
        },
        {
            "name": "Profile",
            "description": "Authenticated current-user account operations."
        },
        {
            "name": "Reminders",
            "description": "Authenticated reminder CRUD with filters."
        },
        {
            "name": "Sounds",
            "description": "Alarm sounds available for reminders."
        },
        {
            "name": "Misc",
            "description": "Utility endpoints (uploads, FCM passthrough)."
        }
    ],
    "components": {
        "securitySchemes": {
            "AppKey": {
                "type": "apiKey",
                "in": "header",
                "name": "X-API-Key",
                "description": "Global app key. Required on **every** request, even register/login. Configured via `API_APP_KEY` in the server `.env`."
            },
            "UserToken": {
                "type": "apiKey",
                "in": "header",
                "name": "token",
                "description": "User JWT issued by /auth/register or /auth/login. Required on user-scoped endpoints."
            },
            "BearerAuth": {
                "type": "http",
                "scheme": "bearer",
                "bearerFormat": "JWT",
                "description": "Same JWT as UserToken but sent as `Authorization: Bearer <jwt>`."
            }
        },
        "schemas": {
            "Envelope": {
                "type": "object",
                "properties": {
                    "code": {
                        "type": "integer",
                        "example": 200
                    },
                    "success": {
                        "type": "boolean",
                        "example": true
                    },
                    "error": {
                        "oneOf": [
                            {
                                "type": "array",
                                "items": {
                                    "type": "string"
                                }
                            },
                            {
                                "type": "string"
                            }
                        ]
                    },
                    "data": {
                        "type": "object"
                    }
                }
            },
            "Error": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/Envelope"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "success": {
                                "example": false
                            },
                            "data": {
                                "example": []
                            }
                        }
                    }
                ]
            },
            "User": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer",
                        "example": 42
                    },
                    "name": {
                        "type": "string",
                        "example": "Ahmed Hamdi"
                    },
                    "email": {
                        "type": "string",
                        "format": "email",
                        "example": "ahmed@example.com"
                    },
                    "phone": {
                        "type": "string",
                        "example": "+201000000000"
                    },
                    "is_admin": {
                        "type": "boolean",
                        "example": false
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    }
                }
            },
            "AuthSuccess": {
                "type": "object",
                "properties": {
                    "token": {
                        "type": "string",
                        "description": "JWT to use on subsequent calls."
                    },
                    "user": {
                        "$ref": "#/components/schemas/User"
                    }
                }
            },
            "Sound": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer",
                        "example": 2
                    },
                    "name": {
                        "type": "string",
                        "example": "Classic bell"
                    },
                    "file_name": {
                        "type": "string",
                        "example": "sound_a1b2c3.mp3"
                    },
                    "url": {
                        "type": "string",
                        "format": "uri",
                        "description": "Direct, playable URL — use to preview in-app."
                    },
                    "is_default": {
                        "type": "boolean",
                        "description": "Marked default by admin (only meaningful for public sounds)."
                    },
                    "is_public": {
                        "type": "boolean",
                        "description": "true → admin-uploaded, available to everyone. false → private to a single user."
                    },
                    "is_mine": {
                        "type": "boolean",
                        "description": "true if the calling user uploaded this sound."
                    },
                    "owner_id": {
                        "type": "integer",
                        "nullable": true,
                        "description": "null for public sounds; user id for private ones."
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "updated_at": {
                        "type": "string",
                        "format": "date-time"
                    }
                }
            },
            "Reminder": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer",
                        "example": 7
                    },
                    "name": {
                        "type": "string",
                        "example": "Take medication"
                    },
                    "remind_date": {
                        "type": "string",
                        "format": "date",
                        "example": "2026-05-01"
                    },
                    "remind_time": {
                        "type": "string",
                        "example": "08:30:00"
                    },
                    "is_repeat": {
                        "type": "boolean",
                        "example": true
                    },
                    "repeat_unit": {
                        "type": "string",
                        "enum": [
                            "daily",
                            "weekly",
                            "monthly",
                            "yearly",
                            "weekdays"
                        ],
                        "nullable": true
                    },
                    "repeat_every": {
                        "type": "integer",
                        "nullable": true,
                        "example": 1,
                        "description": "Required when repeat_unit is daily/weekly/monthly/yearly."
                    },
                    "repeat_weekdays": {
                        "type": "array",
                        "nullable": true,
                        "items": {
                            "type": "string",
                            "enum": [
                                "mon",
                                "tue",
                                "wed",
                                "thu",
                                "fri",
                                "sat",
                                "sun"
                            ]
                        },
                        "description": "Required when repeat_unit = weekdays."
                    },
                    "repeat_until": {
                        "type": "string",
                        "format": "date",
                        "nullable": true
                    },
                    "sound_id": {
                        "type": "integer",
                        "nullable": true
                    },
                    "sound": {
                        "nullable": true,
                        "allOf": [
                            {
                                "$ref": "#/components/schemas/Sound"
                            }
                        ]
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "updated_at": {
                        "type": "string",
                        "format": "date-time"
                    }
                }
            },
            "ReminderInput": {
                "type": "object",
                "required": [
                    "name",
                    "remind_date",
                    "remind_time",
                    "is_repeat"
                ],
                "properties": {
                    "name": {
                        "type": "string",
                        "example": "Take medication"
                    },
                    "remind_date": {
                        "type": "string",
                        "format": "date",
                        "example": "2026-05-01"
                    },
                    "remind_time": {
                        "type": "string",
                        "example": "08:30",
                        "description": "HH:mm or HH:mm:ss"
                    },
                    "is_repeat": {
                        "type": "boolean",
                        "example": true
                    },
                    "repeat_unit": {
                        "type": "string",
                        "enum": [
                            "daily",
                            "weekly",
                            "monthly",
                            "yearly",
                            "weekdays"
                        ]
                    },
                    "repeat_every": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 365
                    },
                    "repeat_weekdays": {
                        "type": "array",
                        "items": {
                            "type": "string",
                            "enum": [
                                "mon",
                                "tue",
                                "wed",
                                "thu",
                                "fri",
                                "sat",
                                "sun"
                            ]
                        }
                    },
                    "repeat_until": {
                        "type": "string",
                        "format": "date",
                        "nullable": true
                    },
                    "sound_id": {
                        "type": "integer",
                        "nullable": true,
                        "description": "ID of a sound from GET /api/v1/sounds. Optional."
                    }
                }
            }
        },
        "responses": {
            "BadRequest": {
                "description": "Validation failed",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "Unauthorized": {
                "description": "Missing/invalid token",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "Forbidden": {
                "description": "Account suspended",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "NotFound": {
                "description": "Resource not found",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "ServerError": {
                "description": "Server error",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "TooMany": {
                "description": "Rate limit exceeded",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            }
        }
    },
    "paths": {
        "/api/v1/auth/register": {
            "post": {
                "tags": [
                    "Auth"
                ],
                "summary": "Register a new user",
                "security": [
                    {
                        "AppKey": []
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "name",
                                    "email",
                                    "phone",
                                    "password",
                                    "password_confirmation"
                                ],
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "minLength": 2,
                                        "maxLength": 100,
                                        "example": "Ahmed Hamdi"
                                    },
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "example": "ahmed@example.com"
                                    },
                                    "phone": {
                                        "type": "string",
                                        "minLength": 6,
                                        "maxLength": 25,
                                        "example": "+201000000000"
                                    },
                                    "password": {
                                        "type": "string",
                                        "minLength": 8,
                                        "example": "Sup3rSecret!"
                                    },
                                    "password_confirmation": {
                                        "type": "string",
                                        "minLength": 8,
                                        "example": "Sup3rSecret!"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "User created",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/AuthSuccess"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "500": {
                        "$ref": "#/components/responses/ServerError"
                    }
                }
            }
        },
        "/api/v1/auth/login": {
            "post": {
                "tags": [
                    "Auth"
                ],
                "summary": "Log in with email + password",
                "security": [
                    {
                        "AppKey": []
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "email",
                                    "password"
                                ],
                                "properties": {
                                    "email": {
                                        "type": "string",
                                        "format": "email"
                                    },
                                    "password": {
                                        "type": "string"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/AuthSuccess"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                }
            }
        },
        "/api/v1/auth/forget": {
            "post": {
                "tags": [
                    "Auth"
                ],
                "summary": "Request a password-reset email",
                "description": "Always returns success to prevent email enumeration. The reset link is only sent if the email is registered.",
                "security": [
                    {
                        "AppKey": []
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "email"
                                ],
                                "properties": {
                                    "email": {
                                        "type": "string",
                                        "format": "email"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Email dispatched if registered"
                    }
                }
            }
        },
        "/api/v1/auth/reset": {
            "post": {
                "tags": [
                    "Auth"
                ],
                "summary": "Complete a password reset using the emailed token",
                "security": [
                    {
                        "AppKey": []
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "email",
                                    "token",
                                    "password",
                                    "password_confirmation"
                                ],
                                "properties": {
                                    "email": {
                                        "type": "string",
                                        "format": "email"
                                    },
                                    "token": {
                                        "type": "string",
                                        "description": "The token from the reset email link."
                                    },
                                    "password": {
                                        "type": "string",
                                        "minLength": 8
                                    },
                                    "password_confirmation": {
                                        "type": "string",
                                        "minLength": 8
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Password updated"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    }
                }
            }
        },
        "/api/v1/auth/logout": {
            "post": {
                "tags": [
                    "Auth"
                ],
                "summary": "Logout (client discards token)",
                "description": "Stateless — the server does not maintain a blacklist. Clients should drop their stored token.",
                "security": [
                    {
                        "AppKey": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/api/v1/profile": {
            "get": {
                "tags": [
                    "Profile"
                ],
                "summary": "Show the current user",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/User"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                }
            },
            "put": {
                "tags": [
                    "Profile"
                ],
                "summary": "Update name and/or phone",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "name": {
                                        "type": "string"
                                    },
                                    "phone": {
                                        "type": "string"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "202": {
                        "description": "Updated",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/User"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Profile"
                ],
                "summary": "Permanently delete the current account",
                "description": "Cascades to firebase_tokens and reminders.",
                "responses": {
                    "202": {
                        "description": "Deleted"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                }
            }
        },
        "/api/v1/profile/change-password": {
            "post": {
                "tags": [
                    "Profile"
                ],
                "summary": "Change current user password",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "current_password",
                                    "password",
                                    "password_confirmation"
                                ],
                                "properties": {
                                    "current_password": {
                                        "type": "string"
                                    },
                                    "password": {
                                        "type": "string",
                                        "minLength": 8
                                    },
                                    "password_confirmation": {
                                        "type": "string",
                                        "minLength": 8
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Changed"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                }
            }
        },
        "/api/v1/profile/firebase-token": {
            "post": {
                "tags": [
                    "Profile"
                ],
                "summary": "Register or update a Firebase device token",
                "description": "Upserts on (user_id, device_id). Send the same `device_id` to refresh a token; omit it for one-off registrations.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "token"
                                ],
                                "properties": {
                                    "token": {
                                        "type": "string",
                                        "maxLength": 512
                                    },
                                    "device_id": {
                                        "type": "string",
                                        "maxLength": 191
                                    },
                                    "platform": {
                                        "type": "string",
                                        "enum": [
                                            "ios",
                                            "android",
                                            "web"
                                        ]
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Created"
                    },
                    "202": {
                        "description": "Updated"
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                }
            }
        },
        "/api/v1/reminders": {
            "get": {
                "tags": [
                    "Reminders"
                ],
                "summary": "List the current user's reminders, with optional filters",
                "parameters": [
                    {
                        "name": "from",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        },
                        "description": "Lower bound on remind_date"
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        },
                        "description": "Upper bound on remind_date"
                    },
                    {
                        "name": "is_repeat",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "0",
                                "1",
                                "true",
                                "false",
                                "yes",
                                "no"
                            ]
                        }
                    },
                    {
                        "name": "q",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "maxLength": 100
                        },
                        "description": "Substring match on name"
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100,
                            "default": 20
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "default": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "total": {
                                                            "type": "integer"
                                                        },
                                                        "page": {
                                                            "type": "integer"
                                                        },
                                                        "limit": {
                                                            "type": "integer"
                                                        },
                                                        "items": {
                                                            "type": "array",
                                                            "items": {
                                                                "$ref": "#/components/schemas/Reminder"
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                }
            },
            "post": {
                "tags": [
                    "Reminders"
                ],
                "summary": "Create a reminder",
                "description": "If `is_repeat` is true:\n- For unit ∈ {daily,weekly,monthly,yearly}: send `repeat_every` (>= 1) and optionally `repeat_until`.\n- For unit = `weekdays`: send `repeat_weekdays` as a non-empty array of `mon..sun`.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/ReminderInput"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Created",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Reminder"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                }
            }
        },
        "/api/v1/reminders/{id}": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "schema": {
                        "type": "integer"
                    }
                }
            ],
            "get": {
                "tags": [
                    "Reminders"
                ],
                "summary": "Get a single reminder",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Reminder"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                }
            },
            "put": {
                "tags": [
                    "Reminders"
                ],
                "summary": "Update a reminder",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/ReminderInput"
                            }
                        }
                    }
                },
                "responses": {
                    "202": {
                        "description": "Updated",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Reminder"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Reminders"
                ],
                "summary": "Delete a reminder",
                "responses": {
                    "202": {
                        "description": "Deleted"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/api/v1/sounds": {
            "get": {
                "tags": [
                    "Sounds"
                ],
                "summary": "List alarm sounds available to me",
                "description": "Returns admin-uploaded **public** sounds plus your own **private** uploads. Each item carries a playable `url` you can use for previewing.\n\nPick any returned `id` and pass it as `sound_id` on a reminder.",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "items": {
                                                            "type": "array",
                                                            "items": {
                                                                "$ref": "#/components/schemas/Sound"
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                }
            },
            "post": {
                "tags": [
                    "Sounds"
                ],
                "summary": "Upload a private alarm sound (only visible to you)",
                "description": "The file is stored against your user. Only you can see it in `GET /sounds`, only you can use it on reminders, only you can delete it.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "name",
                                    "file"
                                ],
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "maxLength": 100,
                                        "example": "My favourite chime"
                                    },
                                    "file": {
                                        "type": "string",
                                        "format": "binary",
                                        "description": "Audio file. Allowed: mp3, wav, ogg, m4a, aac. Max 5 MB."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Created",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Sound"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                }
            }
        },
        "/api/v1/sounds/{id}": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "schema": {
                        "type": "integer"
                    }
                }
            ],
            "delete": {
                "tags": [
                    "Sounds"
                ],
                "summary": "Delete one of your private sounds",
                "description": "Only the owner of a private sound can delete it. Public (admin-uploaded) sounds cannot be deleted via this endpoint and will return 404.",
                "responses": {
                    "202": {
                        "description": "Deleted"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/api/v1/base/{type}": {
            "parameters": [
                {
                    "name": "type",
                    "in": "path",
                    "required": true,
                    "schema": {
                        "type": "string",
                        "enum": [
                            "upload",
                            "notify"
                        ]
                    }
                }
            ],
            "post": {
                "tags": [
                    "Misc"
                ],
                "summary": "Legacy utility endpoint (file upload / FCM passthrough)",
                "description": "Pre-existing endpoint kept for backwards compatibility.",
                "security": [
                    {
                        "AppKey": []
                    }
                ],
                "requestBody": {
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "file": {
                                        "type": "string",
                                        "format": "binary"
                                    },
                                    "device_id": {
                                        "type": "string"
                                    },
                                    "title": {
                                        "type": "string"
                                    },
                                    "body": {
                                        "type": "string"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "security": [
        {
            "AppKey": [],
            "UserToken": []
        },
        {
            "AppKey": [],
            "BearerAuth": []
        }
    ]
}