This workflow corresponds to n8n.io template #8801 — we link there as the canonical source.
This workflow follows the Agent → Form recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"nodes": [
{
"id": "cad152e6-b878-4ecc-9d6c-c35cd456881c",
"name": "Get track IDs",
"type": "n8n-nodes-base.set",
"position": [
2464,
1072
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "a35cb340-5917-4981-9627-6c6189a0a0f4",
"name": "Track ID",
"type": "string",
"value": "={{ $json.id }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "fa700f73-8477-46fe-b037-0eddd4634977",
"name": "Create playlist",
"type": "n8n-nodes-base.spotify",
"notes": "Create a blank playlist with the chosen name.",
"position": [
1568,
1072
],
"parameters": {
"name": "={{ $json.output.playlistName }}",
"resource": "playlist",
"operation": "create",
"additionalFields": {
"public": true
}
},
"credentials": {
"spotifyOAuth2Api": {
"name": "<your credential>"
}
},
"notesInFlow": true,
"retryOnFail": true,
"typeVersion": 1
},
{
"id": "9a95a7c1-b655-4078-88ba-1cc5eefd9fbe",
"name": "Split out tracks",
"type": "n8n-nodes-base.splitOut",
"position": [
2016,
1072
],
"parameters": {
"options": {},
"fieldToSplitOut": "Tracks"
},
"typeVersion": 1
},
{
"id": "f8503606-eaf1-484f-9bf4-260f1dbce716",
"name": "Get tracks array",
"type": "n8n-nodes-base.set",
"position": [
1792,
1072
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "c03ede2c-3d1a-4b94-ba72-d9ac518300d3",
"name": "Tracks",
"type": "array",
"value": "={{ $('Ideate playlist').item.json.output.tracks }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "5462894f-ddfe-4e80-a5af-07d57b39d9dd",
"name": "Add track to playlist",
"type": "n8n-nodes-base.spotify",
"position": [
2688,
1072
],
"parameters": {
"id": "=spotify:playlist:{{ $('Create playlist').first().json.id }}",
"trackID": "=spotify:track:{{ $json[\"Track ID\"] }}",
"resource": "playlist",
"additionalFields": {}
},
"credentials": {
"spotifyOAuth2Api": {
"name": "<your credential>"
}
},
"retryOnFail": true,
"typeVersion": 1
},
{
"id": "8363b3a8-710f-42a6-b977-7ba7b4fc3076",
"name": "Get the final playlist",
"type": "n8n-nodes-base.spotify",
"position": [
2256,
1360
],
"parameters": {
"id": "=spotify:playlist:{{ $('Create playlist').item.json.id }}",
"resource": "playlist",
"operation": "get"
},
"credentials": {
"spotifyOAuth2Api": {
"name": "<your credential>"
}
},
"executeOnce": true,
"typeVersion": 1
},
{
"id": "660044f8-d9e3-4b7a-b5ec-9100d315d87f",
"name": "Search the track",
"type": "n8n-nodes-base.spotify",
"position": [
2240,
1072
],
"parameters": {
"limit": 1,
"query": "={{ $json.artist }} - {{ $json.title }}",
"filters": {},
"resource": "track",
"operation": "search"
},
"credentials": {
"spotifyOAuth2Api": {
"name": "<your credential>"
}
},
"retryOnFail": true,
"typeVersion": 1
},
{
"id": "749dd63f-a0cc-449f-9289-c3628bfdcbbf",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
848,
912
],
"parameters": {
"color": 5,
"width": 652,
"height": 756,
"content": "## AI agent to plan the playlist\n\nThis agent uses the AI web-search API Linkup to search for the perfect tracks and returns a structured output containing the playlist title and all tracks to include."
},
"typeVersion": 1
},
{
"id": "0bcc422d-d223-409b-b13c-e4be95f4dc0e",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
1984,
912
],
"parameters": {
"color": 7,
"width": 840,
"height": 320,
"content": "## For each track\nEach track gets searched in Spotify to get their specific IDs to then add them one by one to the playlist."
},
"typeVersion": 1
},
{
"id": "f63a650e-3612-4bc0-bb4a-94d804d86459",
"name": "On form submission",
"type": "n8n-nodes-base.formTrigger",
"position": [
640,
1072
],
"parameters": {
"options": {
"path": "spotify-playlist-generator",
"customCss": ":root {\n /* Fonts */\n --font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;\n --font-weight-normal: 400;\n --font-weight-bold: 700;\n\n /* Font sizes */\n --font-size-body: 14px;\n --font-size-label: 16px;\n --font-size-test-notice: 14px;\n --font-size-input: 16px;\n --font-size-header: 24px;\n --font-size-paragraph: 16px;\n --font-size-link: 14px;\n --font-size-error: 14px;\n --font-size-html-h1: 36px;\n --font-size-html-h2: 28px;\n --font-size-html-h3: 22px;\n --font-size-html-h4: 18px;\n --font-size-html-h5: 16px;\n --font-size-html-h6: 14px;\n --font-size-subheader: 18px;\n\n /* Colours \u2013 Dark Theme */\n --color-background: #191414; /* Spotify dark background */\n --color-card-bg: #212121; /* Dark card background */\n --color-card-border: #2a2a2a;\n --color-card-shadow: rgba(0, 0, 0, 0.6);\n\n --color-header: #FFFFFF;\n --color-label: #EAEAEA;\n --color-input-bg: #212121; /* \u2705 Dark background for inputs */\n --color-input-text: #FFFFFF; /* \u2705 White text */\n --color-input-border: #444444;\n --color-focus-border: #1DB954;\n\n --color-link: #1DB954;\n --color-link-hover: #1AA34A;\n --color-header-subtext: #B3B3B3;\n\n --color-submit-btn-bg: #1DB954;\n --color-submit-btn-text: #FFFFFF;\n --color-submit-btn-hover: #1AA34A;\n\n --color-clear-button-bg: #333333;\n --color-clear-button-text: #FFFFFF;\n\n --color-test-notice-text: #FFFFFF;\n --color-test-notice-bg: #2a2a2a;\n --color-test-notice-border: #3a3a3a;\n\n --color-error: #E22134;\n --color-required: #1DB954;\n\n --color-html-text: #EAEAEA;\n --color-html-link: #1DB954;\n\n /* Border Radii */\n --border-radius-card: 8px;\n --border-radius-input: 4px;\n --border-radius-clear-btn: 50%;\n --card-border-radius: 8px;\n\n /* Spacing */\n --padding-container-top: 32px;\n --padding-card: 24px;\n --padding-test-notice-vertical: 16px;\n --padding-test-notice-horizontal: 24px;\n --margin-bottom-card: 24px;\n --padding-form-input: 12px;\n --card-padding: 24px;\n --card-margin-bottom: 24px;\n\n /* Dimensions */\n --container-width: 480px;\n --submit-btn-height: 48px;\n --checkbox-size: 20px;\n\n /* Other visuals */\n --box-shadow-card: 0px 4px 16px rgba(0, 0, 0, 0.6);\n --opacity-placeholder: 0.8;\n}\n\n/* Inputs */\ninput, textarea {\n background-color: var(--color-input-bg);\n color: var(--color-input-text);\n border: 1px solid var(--color-input-border);\n border-radius: var(--border-radius-input);\n padding: var(--padding-form-input);\n}\n\ninput:focus, textarea:focus {\n outline: none;\n border-color: var(--color-focus-border);\n box-shadow: 0 0 0 2px rgba(29, 185, 84, 0.3); /* Spotify green glow */\n}\n\n/* Placeholder styling */\n::placeholder {\n font-family: system-ui, sans-serif;\n font-size: 0.9em;\n font-weight: 400;\n color: #B3B3B3; /* \u2705 More readable grey */\n opacity: 1;\n}",
"buttonLabel": "Generate the playlist",
"appendAttribution": false
},
"formTitle": "Spotify playlist AI generator",
"formFields": {
"values": [
{
"fieldType": "textarea",
"fieldLabel": "Playlist request",
"placeholder": "=Describe the playlist you'd like, its style, artists, mood, anything",
"requiredField": true
},
{
"fieldType": "number",
"fieldLabel": "Number of tracks",
"placeholder": "How many tracks to include",
"requiredField": true
}
]
},
"responseMode": "lastNode"
},
"typeVersion": 2.3
},
{
"id": "32bcb9a6-89d3-4aa6-a38f-459cbef72398",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
896,
1296
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4.1-mini"
},
"options": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "5ae73327-327c-4add-8068-f0e202101577",
"name": "Web query to find tracks",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
1136,
1312
],
"parameters": {
"url": "https://api.linkup.so/v1/search",
"method": "POST",
"options": {},
"sendBody": true,
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "q",
"value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('parameters0_Value', `The tracks research query.\n(e.g. \"12 tracks released in 2010 in Spain on the topic of passionate love, RNB style\" or \"10 most famous Daft Punk tracks\" ...)`, 'string') }}"
},
{
"name": "depth",
"value": "deep"
},
{
"name": "outputType",
"value": "structured"
},
{
"name": "structuredOutputSchema",
"value": "={\n \"type\": \"object\",\n \"properties\": {\n \"tracks\": {\n \"type\": \"array\",\n \"description\": \"A list of music tracks included in the selection\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"title\": {\n \"type\": \"string\",\n \"description\": \"The title of the track\"\n },\n \"artist\": {\n \"type\": \"string\",\n \"description\": \"The artist or group who performed the track\"\n },\n \"explanation\": {\n \"type\": \"string\",\n \"description\": \"A 1-line explanation of why this track was chosen\"\n }\n }\n }\n }\n }\n}"
},
{
"name": "includeImages",
"value": "false"
}
]
},
"genericAuthType": "httpBearerAuth",
"toolDescription": "=Call this tool with a specific query to get a list of recommended tracks to include in the playlist."
},
"credentials": {
"httpBearerAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "4733dee8-34fd-4e20-b91a-e5f5a16abb42",
"name": "Ideate playlist",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1056,
1072
],
"parameters": {
"text": "=# Playlist guidelines\n\n{{ $json['Playlist request'] }}\n\n\n# Number of songs to include\n\n{{ $json['Number of tracks'] }}",
"options": {
"systemMessage": "=# Role\n\nYou are a very experienced DJ and your task is to create a playlist of {{ $json['Number of tracks'] }} tracks and give it a name, based on the user message which contains the playlist instructions and number of tracks to include. \n\n# How to find the {{ $json['Number of tracks'] }} tracks to include within a playlist\n\nYou'll recommend an interesting and relevant mix of tracks, exactly {{ $json['Number of tracks'] }} tracks - ideally not from the same artist (except if the instructions tell so), nailing implementing the instructions given by the user message.\n\nTo achieve that, you'll call the tool \"Web query to find tracks\" with a query you'll craft - this tool has web access and knows all tracks so you can pass queries and it will return track suggestions. Run this tool only once.\nYou'll then be able to make your selection based on those recommendations.\n\nFor each track you will (and this will be detailed later) provide the artist name and the title of the track.\n\n\n# How to craft the playlist title\n\nBased on the user message and the songs to fit into the playlist, the playlist name should be between 5 and 9 words and perfectly fit for a playlist name.\nIt is possible that the user message contains more direct instructions for the title.\n\n# Strict output format:\n\nHere's an example of your output so you have a good idea of the schema of the JSON output and a little idea of how the values can look like in the case of a 5-track playlist (but adapt the values to the user message!):\n\n\n{\n \"playlistName\":\"Summer dancing with a Spritz and attitude\",\n \"tracks\":[\n {\n \"artist\":\"David Guetta, Sia\",\n \"title\":\"Beautiful People\"\n },\n {\n \"artist\":\"Ed Sheeran\",\n \"title\":\"Azizam\"\n },\n {\n \"artist\":\"Doechii\",\n \"title\":\"Anxiety\"\n },\n {\n \"artist\":\"OneRepublic\",\n \"title\":\"Nobody (from Kaiju No.8)\"\n },\n {\n \"artist\":\"The Weeknd\",\n \"title\":\"Cry For Me\"\n }\n ]\n}\n\n\n"
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 2.2
},
{
"id": "d370dbad-7b59-4e88-ab36-5058112af9ab",
"name": "Structured Output Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
1360,
1312
],
"parameters": {
"jsonSchemaExample": "{\n \"playlistName\":\"Summer dancing with a Spritz and attitude\",\n \"tracks\":[\n {\n \"artist\":\"David Guetta, Sia\",\n \"title\":\"Beautiful People\"\n },\n {\n \"artist\":\"Ed Sheeran\",\n \"title\":\"Azizam\"\n },\n {\n \"artist\":\"Doechii\",\n \"title\":\"Anxiety\"\n },\n {\n \"artist\":\"OneRepublic\",\n \"title\":\"Nobody (from Kaiju No.8)\"\n },\n {\n \"artist\":\"The Weeknd\",\n \"title\":\"Cry For Me\"\n }\n ]\n}\n"
},
"typeVersion": 1.3
},
{
"id": "90f4b20f-4e85-4069-9d1e-e54c41778ac7",
"name": "Opening the playlist",
"type": "n8n-nodes-base.form",
"position": [
2464,
1360
],
"parameters": {
"options": {},
"operation": "completion",
"redirectUrl": "={{ $json.external_urls.spotify }}",
"respondWith": "redirect"
},
"typeVersion": 2.3
},
{
"id": "277b77d3-8f2f-462c-9dd0-71704acd4256",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
1056,
1280
],
"parameters": {
"color": 6,
"height": 368,
"content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## AI web-search with Linkup\nConnect your Linkup.so credentials"
},
"typeVersion": 1
},
{
"id": "3f440854-0af9-4676-93c8-1674255c5d66",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
48,
720
],
"parameters": {
"width": 528,
"height": 960,
"content": "\n\n# AI DJ: Prompt-to-Playlist Generator\n\nThis workflow uses an AI Agent as a \"DJ\" to turn any text prompt into a Spotify playlist. It's smart, fast, and creates a seamless experience from start to finish.\n\n## **How it works**\n1. It takes your playlist idea from the **web form**.\n2. An AI Agent uses **Linkup** to search the web for the latest and most relevant tracks.\n3. The agent curates a final list and the workflow automatically builds the playlist in your **Spotify** account.\n4. Finally, it **redirects you** straight to your new playlist!\n\n**How to use**\n1. **Connect your accounts:** Add your credentials for **Spotify**, **Linkup**, and an **AI provider** (like OpenAI) to the relevant nodes.\n2. **Activate the workflow.**\n3. **Open the Form URL** from the trigger node and describe your perfect playlist.\n\n@[youtube](EgvaD7j4c1A)\n\n\n\n*A template developed by Guillaume Duvernay*"
},
"typeVersion": 1
}
],
"connections": {
"Get track IDs": {
"main": [
[
{
"node": "Add track to playlist",
"type": "main",
"index": 0
}
]
]
},
"Create playlist": {
"main": [
[
{
"node": "Get tracks array",
"type": "main",
"index": 0
}
]
]
},
"Ideate playlist": {
"main": [
[
{
"node": "Create playlist",
"type": "main",
"index": 0
}
]
]
},
"Get tracks array": {
"main": [
[
{
"node": "Split out tracks",
"type": "main",
"index": 0
}
]
]
},
"Search the track": {
"main": [
[
{
"node": "Get track IDs",
"type": "main",
"index": 0
}
]
]
},
"Split out tracks": {
"main": [
[
{
"node": "Search the track",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "Ideate playlist",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"On form submission": {
"main": [
[
{
"node": "Ideate playlist",
"type": "main",
"index": 0
}
]
]
},
"Add track to playlist": {
"main": [
[
{
"node": "Get the final playlist",
"type": "main",
"index": 0
}
]
]
},
"Get the final playlist": {
"main": [
[
{
"node": "Opening the playlist",
"type": "main",
"index": 0
}
]
]
},
"Structured Output Parser": {
"ai_outputParser": [
[
{
"node": "Ideate playlist",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Web query to find tracks": {
"ai_tool": [
[
{
"node": "Ideate playlist",
"type": "ai_tool",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
httpBearerAuthopenAiApispotifyOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Stop manually searching for songs and let an AI DJ do the work for you. This template provides a complete, end-to-end system that transforms any text prompt into a ready-to-play Spotify playlist. It combines the creative understanding of a powerful AI Agent with the real-time…
Source: https://n8n.io/workflows/8801/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow serves as a comprehensive "Workflow Nodes SEO & Documentation Generator". It uses AI to analyze, rename, and document n8n workflows, offering a streamlined way to optimize workflow reada
🧠 Automate end-to-end SEO blog creation and WordPress publishing using a GPT-5 multi-agent workflow with real-time research, metadata generation, and optional featured images.
This is an automated blog post generation system that: Researches topics using AI agents and web search tools Writes complete blog posts with proper SEO structure Generates custom images for each post
📄 Documentation: Notion Guide
This workflow generates comprehensive B2B leads, from a selected Business type in ANY CITY IN THE WORLD, including: Company name; Website; Email (enriched with AI Agent); Phone number; Address; Main L