Documentação Api de Integrações (Spotify, Deezer, Apple Music, Vimeo)

Todas as rotas abaixo estão marcadas com Auth->allow() nos seus controllers (não exigem login via componente Auth), mas parte delas depende da sessão de navegador do usuário logado no painel (cookie de sessão) para resolver a empresa/filial/distribuidora (UserLogged.companyID, role.branch_id, UserLogged.distributorID). Não usam header Authorization: Bearer.

Atenção: nas actions do Spotify, Deezer e Apple Music o servidor sempre responde com HTTP 200 (o controller nunca altera o status code da resposta). O sucesso/erro real deve ser lido no campo code do corpo JSON. Já as actions do Vimeo alteram o status HTTP de fato ($this->response->withStatus($code)).

Spotify

Rota morta: /spotify/app/:model/:fk aponta para a action app, que não existe em SpotifyController — chamar essa URL resulta em erro (rota quebrada, sem uso real). Código sem rota: SpotifyController::refreshApi() existe no controller, mas nenhuma rota o conecta — método morto/inacessível via HTTP.

GET /spotify/auth/:model/:fk Autorizar conta Spotify (passo 1)

Inicia o fluxo de OAuth do Spotify. Deve ser aberto direto no navegador (ex: popup), pois faz um redirect (302) para a tela de autorização do Spotify (accounts.spotify.com).

Parâmetros de rota

modelb = filial (Branch), d = distribuidora (Distributor), qualquer outro valor = empresa (Company).
fkID do registro correspondente ao model, ou a string auth para resolver automaticamente a partir da sessão do usuário logado.

Resposta

Sucesso: redirect HTTP 302 para a URL de autorização do Spotify.

Erro (texto puro, não é JSON, HTTP 200):

fk inválido ou nulo
GET /spotify/get-return Callback de retorno do Spotify (passo 2)

Chamado automaticamente pelo Spotify após o usuário autorizar o app (não deve ser chamado manualmente). Troca o code recebido pelo primeiro access/refresh token e os grava na sessão.

Parâmetros GET (querystring)

codeCódigo de autorização enviado pelo Spotify via query string.

Resposta

Sucesso: redirect HTTP 302 para /spotify/authenticated.

Erro (texto puro, não é JSON, HTTP 200):

SpotifyService Error: could not request the access token
GET /spotify/authenticated Persistir autorização (passo 3)

Finaliza o fluxo: persiste o CompanySpotify/BranchSpotify/DistributorSpotify com os tokens obtidos. Renderiza uma página HTML (sem layout), usada dentro do popup de autorização - não retorna JSON.

Sem parâmetros diretos, depende dos dados gravados em sessão pelos passos 1 e 2.

Variável $response disponível na view

successSucesso

{
    "status": "success",
    "message": "Spotify autorizado com sucesso."
}

errorErro

{
    "status": "error",
    "message": "Autorização negada, verifique seus conta do Spotify.",
    "data": null
}
GET /spotify/setup/:model/:fk Preparar sessão da API (setup)

Deve ser chamado antes das actions de busca/playlist. Carrega o token ativo do banco, força o refresh do access token junto ao Spotify e grava a sessão ApiSpotify usada pelas demais actions.

Parâmetros de rota

modelb = filial, d = distribuidora, outro valor = empresa.
fkID do registro, ou auth para resolver pela sessão do usuário logado.

200Sucesso

{
    "status": "success",
    "message": "successfully prepared",
    "data": null,
    "code": 200
}

401fk inválido/nulo ou sem integração ativa

{
    "status": "error",
    "message": "Não foi possível autenticar com Spotify.\n Acesse o menu (Configurações => Integrações => SpotifyAPI) e verifique a autorização.",
    "data": null,
    "code": 401
}

500Falha ao renovar o access token junto ao Spotify

{
    "status": "error",
    "message": "Não foi possível autenticar com Spotify.\n Acesse o menu (Configurações => Integrações => SpotifyAPI) e verifique a autorização.",
    "data": null,
    "code": 500
}
POST /spotify/revoke/:model/:fk Revogar autorização (desativar)

Marca a integração como inativa (não apaga o registro do banco). É necessário ter chamado setup antes (depende da sessão ApiSpotify).

Parâmetros de rota

model / fkMesma convenção das demais actions do Spotify.

Body

session_idobrigatórioID da sessão Spotify vinculada à integração (enviado no corpo da requisição).

200Sucesso

{
    "status": "success",
    "message": "Spotify desabilitado com sucesso.",
    "data": null,
    "code": 200
}

400Sessão ApiSpotify não iniciada (setup não foi chamado)

{
    "status": "error",
    "message": "API não autenticada",
    "data": null,
    "code": 400
}

403Sessão iniciada mas sem tokens válidos

{
    "status": "error",
    "message": "Conta não autenticada",
    "data": null,
    "code": 403
}

401Registro ativo não encontrado (session_id/fk)

{
    "status": "error",
    "message": "Não foi possível encontrar esta API, tente novamente.",
    "data": null,
    "code": 401
}

500Falha ao salvar o registro

{
    "status": "error",
    "message": "Não foi possível desativar esta API, tente novamente.",
    "data": null,
    "code": 500
}
POST /spotify/remvoe/:model/:fk Remover autorização (excluir do banco)

Remove definitivamente o registro de integração. Diferente do revoke, não exige a sessão ApiSpotify ativa.

Parâmetros de rota

model / fkMesma convenção das demais actions do Spotify.

Body

session_idobrigatórioID da sessão Spotify vinculada à integração (enviado no corpo da requisição).

200Sucesso

{
    "status": "success",
    "message": "Spotify desabilitado com sucesso.",
    "data": null,
    "code": 200
}

401Registro ativo não encontrado (session_id/fk)

{
    "status": "error",
    "message": "Não foi possível encontrar esta API, tente novamente.",
    "data": null,
    "code": 401
}

500Falha ao excluir o registro

{
    "status": "error",
    "message": "Não foi possível desativar esta API, tente novamente.",
    "data": null,
    "code": 500
}
GET /spotify/get-data/{:artist}/{:name}/{:album} Buscar melhor faixa (artista/título/álbum)

Requer setup prévio na mesma sessão de navegador.

Parâmetros de rota

artistNome do artista (segmento de URL).
nameTítulo da faixa (segmento de URL).
albumÁlbum (opcional) (segmento de URL).

200Sucesso

{
    "code": 200,
    "data": {
        "image": "https://i.scdn.co/image/...",
        "artist": "Artista",
        "title": "Título",
        "album": "Álbum",
        "year": "2020",
        "spotify_id": "3n3Ppam7vgaVa1iaRUc9Lp"
    },
    "query": {
        "artist": "Artista",
        "title": "Título",
        "last_query": "Título artist:Artista"
    },
    "message": "Melhor resultado encontrado"
}

400Sessão ApiSpotify não iniciada

{
    "code": 400,
    "query": null,
    "data": null,
    "message": "API não autenticada"
}

403Sessão iniciada mas sem tokens válidos

{
    "code": 403,
    "query": null,
    "data": null,
    "message": "Conta não autenticada"
}

404Nenhum resultado, ou falha na API do Spotify

{
    "code": 404,
    "query": null,
    "data": null,
    "message": "Falha ao buscar informações."
}

200 (falha)Rate limit do Spotify (HTTP 429 externo)

{
    "code": 200,
    "query": null,
    "data": null,
    "message": "Falha ao buscar informações, por favor tente novamente após alguns segundos"
}
POST /spotify/advanced-search Busca avançada de faixas (até 10 resultados)

Requer setup prévio na mesma sessão de navegador.

Body

artistNome do artista (opcional).
titleTítulo da faixa (opcional).

200Sucesso

{
    "code": 200,
    "data": [
        {
            "image": "https://i.scdn.co/image/...",
            "artist": "Artista",
            "title": "Título",
            "album": "Álbum",
            "year": "2020",
            "spotify_id": "3n3Ppam7vgaVa1iaRUc9Lp"
        }
    ],
    "query": {
        "artist": "Artista",
        "title": "Título",
        "last_query": "Título artist:Artista"
    },
    "message": "Resultado encontrados"
}

iguais ao anteriorMesmas respostas de erro do endpoint acima

400 (API não autenticada), 403 (Conta não autenticada), 404 (sem resultados/falha na API) e 200 (rate limit).

GET /spotify/search-code/{:code} Buscar faixa por código Spotify

Requer setup prévio na mesma sessão de navegador.

Parâmetros de rota

codeID da faixa no Spotify (segmento de URL).

200Sucesso

{
    "code": 200,
    "data": [
        {
            "image": "https://i.scdn.co/image/...",
            "artist": "Artista",
            "title": "Título",
            "album": "Álbum",
            "year": "2020",
            "spotify_id": "3n3Ppam7vgaVa1iaRUc9Lp"
        }
    ],
    "query": {
        "code": "3n3Ppam7vgaVa1iaRUc9Lp"
    },
    "message": "Track encontrada"
}

iguais à busca por artista/títuloMesmas respostas de erro

400 (API não autenticada), 403 (Conta não autenticada), 404 (código inválido/sem resultado) e 200 (rate limit).

POST /spotify/create-playlist Criar playlist vazia no Spotify

Requer setup prévio na mesma sessão de navegador.

Body

nameobrigatórioNome da playlist.
descriptionobrigatórioDescrição da playlist (o sufixo " - by superaudio.com.br" é adicionado automaticamente).

200Sucesso

{
    "message": "success",
    "data": {
        "id": "37i9dQZF1DXcBWIGoYBM5M",
        "name": "Minha Playlist",
        "public": true,
        "external_url": "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M"
    },
    "code": 200
}

401name/description não enviados

{
    "message": "SpotifyPlaylistService Error: playlist incompleta.",
    "data": null,
    "code": 401
}

400 - sessão ApiSpotify não iniciada, ou 403 - conta sem tokens válidos (mesmo comportamento das demais actions).

POST /spotify/update-playlist Vincular ID de playlist do Spotify a um programa

Não depende da sessão ApiSpotify/setup: apenas grava/atualiza o vínculo ProgramSpotify no banco.

Body

modelobrigatórioModel dono do programa (ex: Companies).
fkobrigatórioID do registro dono do programa.
program_idobrigatórioID do programa.
spotify_idobrigatórioID da playlist no Spotify.

200Sucesso

{
    "message": "SpotifyId successfully updated",
    "data": null,
    "code": 200
}

500Falha ao salvar (implícito, código não informado na exceção)

{
    "message": "ProgramSpotifyManagerService Error: could not update SpotifyId",
    "data": null,
    "code": 0
}
POST /spotify/mount-playlist Popular playlist(s) do Spotify com as faixas da geração

Usado pelo Gerador para publicar, no Spotify, as faixas ordenadas de uma geração. Usa as credenciais salvas em CompanySpotify (não depende do setup/sessão ApiSpotify).

Body

data[generation_id]obrigatórioID da geração.
data[programs][][program_id]ID do programa (opcional; se omitido, considera todos os programas da geração).
data[programs][][spotify_id]ID da playlist no Spotify vinculada ao programa.

200Sucesso

{
    "message": null,
    "data": {
        "123": ["4iV5W9uYEdYUVa79Axb7Rh"]
    },
    "code": 200
}

500Geração sem arquivo de conteúdo processado

{
    "message": "ProgramSpotifyManagerService Error: fala ao carregar o arquivo de geração",
    "data": null,
    "code": 500
}

500Sem credenciais Spotify ativas para a empresa

{
    "message": "Não foi possível autenticar com Spotify. Acesse o menu (Configurações => Integrações => SpotifyAPI) e verifique a autorização.",
    "data": null,
    "code": 500
}
POST /spotify/get-base64 Converter imagem em base64

Utilitário genérico (não é exclusivo do Spotify, mas está hospedado no SpotifyController). Baixa a imagem da URL informada e retorna como data URL base64.

Body

urlobrigatórioURL pública da imagem a ser convertida.

200Sucesso

{
    "code": 200,
    "message": null,
    "data": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD..."
}

500URL inválida ou falha ao baixar a imagem

{
    "code": 500,
    "message": "Could not fetch image",
    "data": null
}

Se chamado com outro método que não POST, o CakePHP retorna HTTP 405 (Method Not Allowed).

Deezer

POST /deezer/advanced-search Busca avançada de faixas (até 10 resultados)

Não exige autenticação/sessão - consulta direto a API pública do Deezer (api.deezer.com).

Body

artistNome do artista (opcional).
titleTítulo da faixa (opcional).

200Sucesso

{
    "code": 200,
    "data": [
        {
            "image": "https://e-cdns-images.dzcdn.net/images/cover/xl/...",
            "artist": "Artista",
            "title": "Título",
            "album": "Álbum",
            "year": "2020",
            "deezer_id": "3135556"
        }
    ],
    "query": {
        "artist": "Artista",
        "title": "Título",
        "last_query": "Título Artista"
    },
    "message": "Resultado encontrados"
}

404artist/title vazios, sem resultados, ou falha na API do Deezer

{
    "code": 404,
    "query": null,
    "data": null,
    "message": "Não foram encontrados resultados"
}
{
    "code": 404,
    "query": null,
    "data": null,
    "message": "Falha ao buscar informações."
}

Assim como no Spotify, o HTTP retornado é sempre 200; o status real deve ser lido no campo code.

Apple Music

POST /apple-music/advanced-search Busca avançada de faixas (até 10 resultados)

Não exige autenticação/sessão - usa a API pública do iTunes Search (itunes.apple.com/search), não precisa de token do MusicKit.

Body

artistNome do artista (opcional).
titleTítulo da faixa (opcional).

200Sucesso

{
    "code": 200,
    "data": [
        {
            "image": "https://is1-ssl.mzstatic.com/image/thumb/.../600x600bb.jpg",
            "artist": "Artista",
            "title": "Título",
            "album": "Álbum",
            "year": "2020",
            "apple_itunes_track_id": "1440833098"
        }
    ],
    "query": {
        "artist": "Artista",
        "title": "Título",
        "last_query": "Título Artista"
    },
    "message": "Resultado encontrados"
}

400artist e title vazios

{
    "code": 400,
    "query": null,
    "data": null,
    "message": "Não foram encontrados resultados"
}

404Sem resultados, ou falha na API do iTunes

{
    "code": 404,
    "query": null,
    "data": null,
    "message": "Não foram encontrados resultados"
}
{
    "code": 404,
    "query": null,
    "data": null,
    "message": "Falha ao buscar informações."
}

Assim como no Spotify e Deezer, o HTTP retornado é sempre 200; o status real deve ser lido no campo code.

Vimeo

Diferente das demais integrações desta página, os endpoints do Vimeo exigem usuário logado (não usam Auth->allow()) e alteram de fato o status HTTP da resposta ($this->response->withStatus($code)).

POST /vimeo/upload-video Upload de vídeo (resumable/TUS)

Exige usuário logado e um vimeo_token configurado na galeria de vídeos da empresa. Faz upload em chunks (approach "tus" da API do Vimeo); o upload final do binário é processado de forma assíncrona (via comando artisan send_upload_vimeo).

Headers

Content-RangeobrigatórioFaixa de bytes do chunk enviado, no formato bytes {offset}-{size}/{total} (padrão do upload resumable).

Body (multipart/form-data)

video_gallery_idobrigatórioID do registro na galeria de vídeos.
titleTítulo do vídeo no Vimeo (opcional, default: "Sem título").
files[]obrigatórioChunk binário do arquivo de vídeo.

sucessoChunk intermediário

{
    "status": "success"
}

sucessoÚltimo chunk

{
    "status": "success",
    "gallery_video": {
        "video_embed_link": ""
    }
}

403Empresa sem vimeo_token configurado

{
    "message": "Vimeo Token não encontrado, acesse as configurações da galeria e adicione um token válido."
}

403Método HTTP diferente de POST

{
    "message": "Method not allowed"
}

400Falhas de validação/upload

Nenhum arquivo enviado, header Content-Range ausente, upload já em andamento, limite de vídeos da conta Vimeo excedido, título ausente, link de upload inválido:

{
    "message": "Nenhum arquivo informado."
}
DELETE /vimeo/remove-video/:videoId Remover vídeo do Vimeo

Exige usuário logado, assim como o upload.

Parâmetros de rota

videoIdobrigatórioID do registro na galeria de vídeos (não é o ID do Vimeo).

200Sucesso

{
    "code": 200,
    "message": "Upload removido com sucesso!"
}

403Sem vimeo_token, ou método diferente de DELETE

{
    "message": "Method not allowed"
}

400videoId inexistente na galeria

{
    "message": "Vídeo não encontrado"
}

401/404/500...Repassados diretamente da API do Vimeo

{
    "message": "Não foi possivel remover o upload do vimeo, verifique as permissões concedidas ao seu token do token."
}