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
| model | b = filial (Branch), d = distribuidora (Distributor), qualquer outro valor = empresa (Company). |
| fk | ID 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)
| code | Có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
| model | b = filial, d = distribuidora, outro valor = empresa. |
| fk | ID 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 / fk | Mesma convenção das demais actions do Spotify. |
Body
| session_idobrigatório | ID 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 / fk | Mesma convenção das demais actions do Spotify. |
Body
| session_idobrigatório | ID 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
| artist | Nome do artista (segmento de URL). |
| name | Tí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
| artist | Nome do artista (opcional). |
| title | Tí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
| code | ID 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ório | Nome da playlist. |
| descriptionobrigatório | Descriçã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ório | Model dono do programa (ex: Companies). |
| fkobrigatório | ID do registro dono do programa. |
| program_idobrigatório | ID do programa. |
| spotify_idobrigatório | ID 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ório | ID 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ório | URL 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
| artist | Nome do artista (opcional). |
| title | Tí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
| artist | Nome do artista (opcional). |
| title | Tí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ório | Faixa de bytes do chunk enviado, no formato bytes {offset}-{size}/{total} (padrão do upload resumable). |
Body (multipart/form-data)
| video_gallery_idobrigatório | ID do registro na galeria de vídeos. |
| title | Título do vídeo no Vimeo (opcional, default: "Sem título"). |
| files[]obrigatório | Chunk 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ório | ID 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."
}