{
    "openapi": "3.1.0",
    "info": {
        "title": "Agafy API",
        "version": "1.0.0",
        "description": "API REST publique.\n\nAuthentification par jeton personnel (Bearer). Les jetons se créent dans l'espace **Développeur** du compte, avec des portées limitant leur accès.\n\nLimite : 60 requêtes par minute et par jeton."
    },
    "servers": [
        {
            "url": "https://agafy.fr/api"
        }
    ],
    "components": {
        "securitySchemes": {
            "bearerAuth": {
                "type": "http",
                "scheme": "bearer",
                "bearerFormat": "Sanctum"
            }
        },
        "schemas": {
            "Paginated": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "array",
                        "items": {
                            "type": "object"
                        }
                    },
                    "current_page": {
                        "type": "integer"
                    },
                    "last_page": {
                        "type": "integer"
                    },
                    "total": {
                        "type": "integer"
                    }
                }
            }
        }
    },
    "tags": [
        {
            "name": "Compte"
        },
        {
            "name": "Catalogue"
        },
        {
            "name": "Artistes"
        },
        {
            "name": "Statistiques"
        },
        {
            "name": "Fans"
        },
        {
            "name": "Plateforme"
        }
    ],
    "paths": {
        "/v1/me": {
            "get": {
                "summary": "Profil du porteur du jeton",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "description": "Portée requise : `read:profile`.",
                "responses": {
                    "200": {
                        "description": "Succès"
                    },
                    "401": {
                        "description": "Jeton absent ou invalide"
                    },
                    "403": {
                        "description": "Portée insuffisante"
                    }
                },
                "tags": [
                    "Compte"
                ]
            }
        },
        "/v1/tracks": {
            "get": {
                "summary": "Catalogue public paginé",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "description": "Portée requise : `read:tracks`.",
                "responses": {
                    "200": {
                        "description": "Succès"
                    },
                    "401": {
                        "description": "Jeton absent ou invalide"
                    },
                    "403": {
                        "description": "Portée insuffisante"
                    }
                },
                "tags": [
                    "Catalogue"
                ],
                "parameters": [
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "maximum": 50
                        }
                    }
                ]
            }
        },
        "/v1/search": {
            "get": {
                "summary": "Recherche de titres",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "description": "Portée requise : `read:tracks`.",
                "responses": {
                    "200": {
                        "description": "Succès"
                    },
                    "401": {
                        "description": "Jeton absent ou invalide"
                    },
                    "403": {
                        "description": "Portée insuffisante"
                    }
                },
                "tags": [
                    "Catalogue"
                ],
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ]
            }
        },
        "/v1/recommendations": {
            "get": {
                "summary": "Recommandations personnalisées",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "description": "Portée requise : `read:tracks`.",
                "responses": {
                    "200": {
                        "description": "Succès"
                    },
                    "401": {
                        "description": "Jeton absent ou invalide"
                    },
                    "403": {
                        "description": "Portée insuffisante"
                    }
                },
                "tags": [
                    "Catalogue"
                ]
            }
        },
        "/v1/tracks/{track}": {
            "get": {
                "summary": "Détail d'un titre",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "description": "Portée requise : `read:tracks`.",
                "responses": {
                    "200": {
                        "description": "Succès"
                    },
                    "401": {
                        "description": "Jeton absent ou invalide"
                    },
                    "403": {
                        "description": "Portée insuffisante"
                    }
                },
                "tags": [
                    "Catalogue"
                ],
                "parameters": [
                    {
                        "name": "track",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ]
            },
            "patch": {
                "summary": "Mise à jour des métadonnées",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "description": "Portée requise : `write:tracks`.",
                "responses": {
                    "200": {
                        "description": "Succès"
                    },
                    "401": {
                        "description": "Jeton absent ou invalide"
                    },
                    "403": {
                        "description": "Portée insuffisante"
                    }
                },
                "tags": [
                    "Catalogue"
                ],
                "parameters": [
                    {
                        "name": "track",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "title": {
                                        "type": "string"
                                    },
                                    "description": {
                                        "type": "string"
                                    },
                                    "tags": {
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        }
                                    },
                                    "is_public": {
                                        "type": "boolean"
                                    },
                                    "isrc": {
                                        "type": "string"
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "/v1/tracks/{track}/stream-url": {
            "get": {
                "summary": "URL de lecture temporaire",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "description": "Portée requise : `read:tracks`.",
                "responses": {
                    "200": {
                        "description": "Succès"
                    },
                    "401": {
                        "description": "Jeton absent ou invalide"
                    },
                    "403": {
                        "description": "Portée insuffisante"
                    }
                },
                "tags": [
                    "Catalogue"
                ],
                "parameters": [
                    {
                        "name": "track",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ]
            }
        },
        "/v1/artists/{artist}": {
            "get": {
                "summary": "Profil public d'un artiste",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "description": "Portée requise : `read:tracks`.",
                "responses": {
                    "200": {
                        "description": "Succès"
                    },
                    "401": {
                        "description": "Jeton absent ou invalide"
                    },
                    "403": {
                        "description": "Portée insuffisante"
                    }
                },
                "tags": [
                    "Artistes"
                ],
                "parameters": [
                    {
                        "name": "artist",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ]
            }
        },
        "/v1/artists/{artist}/tracks": {
            "get": {
                "summary": "Titres publics d'un artiste",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "description": "Portée requise : `read:tracks`.",
                "responses": {
                    "200": {
                        "description": "Succès"
                    },
                    "401": {
                        "description": "Jeton absent ou invalide"
                    },
                    "403": {
                        "description": "Portée insuffisante"
                    }
                },
                "tags": [
                    "Artistes"
                ],
                "parameters": [
                    {
                        "name": "artist",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ]
            }
        },
        "/v1/analytics": {
            "get": {
                "summary": "Statistiques du catalogue du porteur",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "description": "Portée requise : `read:analytics`.",
                "responses": {
                    "200": {
                        "description": "Succès"
                    },
                    "401": {
                        "description": "Jeton absent ou invalide"
                    },
                    "403": {
                        "description": "Portée insuffisante"
                    }
                },
                "tags": [
                    "Statistiques"
                ],
                "parameters": [
                    {
                        "name": "days",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "maximum": 365
                        }
                    }
                ]
            }
        },
        "/v1/fans": {
            "get": {
                "summary": "Synthèse de l'audience",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "description": "Portée requise : `read:fans`.",
                "responses": {
                    "200": {
                        "description": "Succès"
                    },
                    "401": {
                        "description": "Jeton absent ou invalide"
                    },
                    "403": {
                        "description": "Portée insuffisante"
                    }
                },
                "tags": [
                    "Fans"
                ]
            }
        },
        "/v1/platform": {
            "get": {
                "summary": "Indicateurs plateforme (admin)",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "description": "Portée requise : `read:analytics`.",
                "responses": {
                    "200": {
                        "description": "Succès"
                    },
                    "401": {
                        "description": "Jeton absent ou invalide"
                    },
                    "403": {
                        "description": "Portée insuffisante"
                    }
                },
                "tags": [
                    "Plateforme"
                ]
            }
        }
    },
    "x-webhooks": [
        {
            "event": "track.published",
            "description": "Titre publié",
            "signature": "HMAC-SHA256 du corps brut, en-tête X-Melodix-Signature (préfixe sha256=)."
        },
        {
            "event": "presave.created",
            "description": "Pré-enregistrement de fan",
            "signature": "HMAC-SHA256 du corps brut, en-tête X-Melodix-Signature (préfixe sha256=)."
        },
        {
            "event": "tip.received",
            "description": "Pourboire reçu",
            "signature": "HMAC-SHA256 du corps brut, en-tête X-Melodix-Signature (préfixe sha256=)."
        },
        {
            "event": "subscription.created",
            "description": "Abonnement artiste créé",
            "signature": "HMAC-SHA256 du corps brut, en-tête X-Melodix-Signature (préfixe sha256=)."
        },
        {
            "event": "test.ping",
            "description": "Test manuel",
            "signature": "HMAC-SHA256 du corps brut, en-tête X-Melodix-Signature (préfixe sha256=)."
        }
    ],
    "x-scopes": {
        "read:profile": "Lire le profil",
        "read:tracks": "Lire le catalogue",
        "read:analytics": "Lire les statistiques",
        "write:tracks": "Modifier les titres",
        "read:fans": "Lire les fans et segments"
    }
}