Connect n8n to Python Archive API
Connect n8n to a Python API over Docker and report ready jobs to Discord.
Introduction
30 Second Summary
A working automation can still break when one service tries to reach another from inside a container. The familiar address that works from your browser can lead to the wrong place from inside the workflow.
In this project, you will extend your existing archive workflow into a three-service pipeline that sends each job from PowerShell through n8n to the Python processor before Discord reports the result. A user-defined Docker bridge network will give n8n a stable route to the processor.
What You'll Build
Picture running your familiar PowerShell sender to produce a processor-backed archive report in Discord.
By the end of this project, you'll have:
- A traceable archive run where n8n shows jobId, course, lesson, status, and processedBy from the processor.
- An inspectable container connection where Docker shows both existing containers attached to archive-automation.
- A processor-backed Discord report that appears only when status equals ready.
- Secret Mission: Require both ready and Python before Discord receives a success report.
Are there any prerequisites?
This project builds on Projects 1 and 2 plus Containerize a Python Archive Processor. No new installation is required.
You'll need the existing PowerShell sender, published n8n workflow, Discord credential, archive-processor image, and archive-processor container.
Before We Start
This step locks in the pipeline you are extending without rebuilding the Python processor. PowerShell sends each archive job to the existing archive-processor service before Discord receives the success report.
Confirm the Existing Automation
Your existing Windows PowerShell sender begins the archive pipeline. The n8n workflow carries that job to Discord.
A stopped container in Docker Desktop can make the next networking change look broken. A stale Discord credential can create the same confusion.
In this step, get ready to:
- Record the exact n8n container name from the existing container inventory.
- Confirm the existing n8n workflow plus processor endpoint are available.
- Prove the original PowerShell-to-Discord path still works.
Inventory the containers
The container inventory includes running resources plus stopped resources. This gives you one place to find both existing services.
Docker Desktop can take a minute to start its engine. A short wait here is normal.
- Press the Windows key to open the Windows search bar.
- Type Docker Desktop and press Enter to start it.
- Wait until Docker Desktop finishes starting.
- Press the Windows key to return to the Windows search bar.
- Type Windows PowerShell and press Enter to open it.
- Show every existing container by running this command:
docker ps -a
What does this command show?
- The command lists containers that are currently running.
- It also includes stopped containers from earlier sessions.
- The result lets you identify each container by its exact name.
- Locate archive-processor in the command output.
- Locate the existing n8n container in the command output.
- Record its exact container name as YOUR_N8N_CONTAINER.
- Check the installed n8n version by running this command:
docker exec -u node -it [[YOUR_N8N_CONTAINER="YOUR_N8N_CONTAINER"]] n8n --version
You should see one version number printed in PowerShell.
- Record the exact installed version here: your installed n8n version.
Why Record the n8n Version?
These instructions use labels from the current n8n documentation. Your recorded version provides the evidence needed to verify every label against your own instance.
Version Command Failing?
- Confirm that the container name in the command matches the n8n name from your inventory.
- Confirm that the n8n container is running before you try the command again.
- Help me retrieve the installed n8n version from my Docker container.
Can't see the existing containers?
Confirm Docker Desktop has finished starting. The inventory remains unavailable while its engine is still loading.
Make sure you are using the same Windows account that held the prerequisite containers.
Help me understand why docker ps -a does not list my existing containers.
Start and open the existing services
Container status proves each service is running. Firefox proves Windows can reach each published port.
- Review the running state shown for each container.
- Replace YOUR_N8N_CONTAINER in the second command with YOUR_N8N_CONTAINER.
- Start each stopped container by running its matching command below:
docker start archive-processor
docker start YOUR_N8N_CONTAINER
What do these commands do?
- The first command starts the existing Python processor container.
- The second command starts the existing n8n container by its recorded name.
- Both commands preserve the containers' existing files plus configuration.
- Refresh the container inventory by running this command:
docker ps -a
What does this second check prove?
- The refreshed inventory shows the current state after your start commands.
- It confirms both prerequisite services are ready for browser checks.
You should now see archive-processor plus your recorded n8n container listed as running.
Is a container still stopped?
Check that you copied the n8n container name exactly. Container names must match the inventory output.
If the processor does not start, confirm the existing archive-processor container still appears in the inventory.
Help me start my existing Docker container.
- Press the Windows key to open the Windows search bar.
- Type Firefox and press Enter to open it.
- Enter http://localhost:5678 in the address bar.
- Sign in with the existing local n8n account if prompted.
- Open the existing published workflow from the workflow list.
You should see the workflow from the prerequisite projects. Its path should run from Webhook through Edit Fields to Discord, with the existing Discord configuration still present.
- Create another tab in Firefox.
- Enter http://127.0.0.1:8000/docs in the address bar.
You should see the processor documentation with POST /process listed as an available endpoint.
Prove the original path still works
The baseline run tests the existing production path as one unit. Its Discord message proves the sender still reaches the published workflow.
Before you submit the job, do you expect the untouched workflow to reach Discord successfully?
- Return to the existing PowerShell sender from the prerequisite projects.
- Run the sender with a complete archive job.
- Return to the existing n8n workflow in Firefox.
- Select Executions to view recent production runs.
- Open the latest execution.
You should see a successful baseline execution from the job you just submitted.
- Return to the existing Discord channel from the prerequisite projects.
You should see one new copy of the workflow's original report. This confirms the existing Discord credential still works.
- Keep the baseline message in Discord for comparison later.
Your baseline is locked in: the original report still reaches Discord. Next, you'll add the processor call to the existing workflow.
Test the Container Boundary
Your baseline proved that the existing Webhook still reaches Discord through Edit Fields. The next request starts inside the n8n container.
Windows reached the Python processor through http://127.0.0.1:8000/docs earlier. This test checks where the same address leads when n8n makes the request.
In this step, get ready to:
- Add a new processor request between the existing Edit Fields and Discord nodes.
- Map the edited archive job into the processor's required request body.
- Publish the workflow to test the request from inside n8n.
Insert the processor call
An HTTP Request node lets the workflow call the processor before Discord receives anything. You will add this new node to the existing connection from Edit Fields to Discord, then rename it Process Archive Job.
- Switch back to the existing workflow in Firefox.
- Select the connection line from Edit Fields to the existing Discord node.
- Select the plus control on that connection.
- Search for HTTP Request in the node picker.
- Select HTTP Request.
- Rename the new node Process Archive Job.
- Leave the existing Webhook, Edit Fields, and Discord node configurations unchanged.
Good progress. Your canvas now shows Webhook feeding Edit Fields, then Process Archive Job, before the existing Discord node.
Why Insert the Request Here?
This position keeps Edit Fields as the source of the processor request. It makes the processor response the input for every later decision while preserving the existing Discord credential.
Configure the archive request
The processor accepts a JSON body containing three required fields. Each value comes from the Edit Fields output, while the PowerShell sender remains the source of the archive job.
- Open Process Archive Job.
- Set Method to POST.
- Enter http://127.0.0.1:8000/process in the URL field.
- Turn on Send Body.
- Choose JSON for Body Content Type.
- Choose Fields Below.
What Does This Configuration Mean?
- The POST method submits one archive job for processing.
- The /process endpoint validates the incoming archive job.
- The JSON body keeps the request fields structured.
- Add a body field named jobId.
- Drag jobId from the Edit Fields output into the jobId field.
- Add a body field named course.
- Drag course from the Edit Fields output into the course field.
- Add a body field named lesson.
- Drag lesson from the Edit Fields output into the lesson field.
The request now mirrors the processor's required contract. n8n holds these changes in the workflow draft.
Publish and test the boundary
n8n keeps canvas edits as a draft until you publish them. Publishing puts this request on the production Webhook used by your existing sender.
Protect Live Archive Requests
Publishing this draft replaces the version used by production Webhook executions. The deliberate loopback URL makes incoming archive requests fail at Process Archive Job until you correct it in Return the Processor Result.
If this workflow handles real requests, run this boundary test on a non-production copy with its own webhook URL. Continue on the live workflow only when a temporary interruption is acceptable.
- Select Publish in the canvas header.
- Approve the publication if n8n asks for confirmation.
- Wait until Publishing changes to Published in the canvas header.
- Return to Windows PowerShell from the baseline test.
Prediction time: will n8n receive a processor response or a connection failure.
- Run the existing PowerShell sender with a complete archive job.
- Return to the workflow in Firefox.
- Open the workflow's Executions view.
- Open the newest execution.
- Select Process Archive Job in the failed execution.
You will see ECONNREFUSED on Process Archive Job. The request reached the n8n container's own loopback interface.
This Failure Is Intentional
Inside the n8n container, 127.0.0.1 identifies that same n8n container. No processor listens on port 8000 there.
The processor remains available through Windows at its published host port. The failed request proves that the container needs its own route to the processor.
- Return to the existing Discord channel.
- Confirm its latest entry is still the baseline report from the previous test.
That is the container boundary proven. The failed processor call stopped the workflow before it could send a new Discord success report.
Did You Miss the Expected Failure?
- Return to the workflow draft if Process Archive Job succeeded.
- Set its URL to exactly http://127.0.0.1:8000/process.
- Confirm the canvas routes Webhook through Edit Fields, then Process Archive Job, before Discord.
- Select Publish again if the latest execution does not include the new node.
- Wait until Publishing changes to Published before you run the PowerShell sender again.
Help me diagnose why my n8n boundary test did not produce ECONNREFUSED.
You have exposed the exact boundary that blocks the pipeline. Next, you will give both containers a shared Docker network where they can find each other by name.
Connect Both Containers
The first processor request reached n8n's own loopback interface. Its ECONNREFUSED result proved that the two containers still lack a shared route.
A user-defined bridge network gives both running containers that route. Docker can then resolve each container by name.
This step changes only the Docker topology. Your published workflow keeps its deliberate loopback URL for the next step.
In this step, get ready to:
- Create a bridge network named archive-automation.
- Attach both running containers to the shared network.
- Verify that Docker lists both containers on the network.
Create the shared bridge network
A Docker network is an independent resource that containers can join. Creating it first gives both containers the same named route.
Why a bridge network?
A host-routed connection would send traffic through Windows. A user-defined network keeps communication directly between the containers.
Docker can discover containers by name on this network. That keeps the route stable without static IP addresses.
- Create the archive-automation network by running this command in Windows PowerShell from earlier:
docker network create archive-automation
What does this command do?
- Docker creates a network called archive-automation.
- Docker uses the bridge driver because the command does not specify another driver.
- Confirm the network was created by locating the network identifier printed below the command.
That is the foundation in place: the shared route now exists without rebuilding either container.
Network not created?
- Switch back to Docker Desktop from earlier if the command cannot reach Docker.
- Run the network creation block again after Docker Desktop is ready.
- Continue with the existing network if Docker reports that archive-automation already exists.
- Help me diagnose why Docker could not create my bridge network.
Attach both running containers
The network remains empty until containers join it. Docker can attach each running container without rebuilding its image or changing its host ports.
- Attach the running archive-processor container to the new network by running this command:
docker network connect archive-automation archive-processor
What does this connection do?
- Docker connects archive-processor to archive-automation while the container keeps running.
- The processor keeps its existing host port mapping for access from Windows.
- Replace YOUR_N8N_CONTAINER below with the exact n8n container name you recorded earlier.
- Attach the n8n container by running the edited command:
docker network connect archive-automation YOUR_N8N_CONTAINER
How will the containers find each other?
- Both running containers now share archive-automation.
- Docker assigns network addresses automatically.
- Container-name discovery removes the need for static IP addresses.
🙋♀️ Container not connected?
- Compare the n8n name you substituted with the exact container name you recorded earlier.
- Keep an attachment in place if Docker reports that the container is already connected.
- Help me diagnose why Docker cannot connect one of my running containers.
Persist the Compose Network
Manual docker network connect is right for these existing containers. A container recreated by Docker Compose receives its networks from the Compose file.
Add archive-automation to each service's networks list. Declare the top-level network with name: archive-automation and external: true so Compose reuses the existing network.
Inspect the network topology
Network inspection reveals which containers have joined the route. This check proves the topology before you change the processor URL.
Before you inspect the network, which two container names do you expect to find under Containers?
- Inspect the shared network by running this command:
docker network inspect archive-automation
What should you see?
- Docker returns the network details as JSON.
- The Containers section includes archive-processor.
- The same section includes the exact n8n container name you recorded earlier.
- The containers keep their existing host port mappings after joining the network.
- Find the Containers section in the PowerShell output.
- Confirm that archive-processor appears in that section.
- Confirm that your recorded n8n container name appears in that section.
You have closed the container boundary: both services now share a Docker-native route while their Windows access remains available.
Next, you will replace the loopback address with the processor's container name and watch the archive job cross the new network.
Return the Processor Result
Your shared Docker bridge network now gives n8n a route to the Python processor. The failed loopback request proved that the workflow still points inward.
This step replaces loopback with the processor's stable container name. The returned JSON then stays structured for the rest of the workflow.
In this step, get ready to:
- Address the processor through its container name.
- Submit a complete archive job through the corrected workflow.
- Match the returned job identifier to the processor log entry.
Address the processor by container name
User-defined bridge networks include container-name DNS. The name archive-processor now resolves to the processor container from inside n8n.
- Switch back to the existing n8n workflow in Firefox.
- Select the Process Archive Job node on the workflow canvas.
- Replace the current URL in the node's parameters panel with http://archive-processor:8000/process.
- Confirm that Method shows POST.
- Confirm that Body Content Type shows JSON.
- Confirm that jobId, course, and lesson remain mapped from the Edit Fields output.
- Set Response Format to JSON in the response settings.
Why use the container name?
The address 127.0.0.1 remains local to the n8n container. The name archive-processor resolves to the sibling container through the shared network.
The existing host port mapping still serves the processor documentation to Windows. Container-name routing keeps the workflow request inside Docker.
The request now targets http://archive-processor:8000/process with a structured response format. The existing Discord node stays untouched.
Run the corrected request
n8n saves workflow edits as a draft. Publishing makes the corrected processor address live for production webhook executions.
- Click Publish in the canvas header.
- Wait until Publishing changes to Published before you return to PowerShell.
Before you send the job, predict whether the container name turns the previous refusal into structured data.
- Switch back to Windows PowerShell from earlier.
- Run the existing PowerShell sender with a complete archive job.
- Return to the workflow's Executions view in Firefox.
- Open the latest execution.
- Select Process Archive Job in the execution path.
You'll see separate fields for message, jobId, course, lesson, status, and processedBy.
The status value reads ready. The processedBy value reads Python.
That is the container boundary crossed. n8n now receives the processor's validated response as structured data.
- Record the returned jobId here: your submitted job identifier.
Request still failing?
- Confirm that the node URL is exactly http://archive-processor:8000/process.
- Confirm that you clicked Publish after changing the URL.
Help me diagnose why n8n cannot reach archive-processor through the shared Docker network.
Trace the job inside Python
The structured response proves that n8n received data. The processor log proves that the same job reached Python.
Before you inspect the log, predict whether its job identifier matches the value you recorded.
- Switch back to Windows PowerShell.
- Retrieve the processor's captured logs by running this command:
docker logs archive-processor
What does this command show?
This command retrieves the logs captured for the archive-processor container. The processor writes an entry beginning with Processed archive job: whenever it accepts a job.
- Find Processed archive job: followed by your submitted job identifier.
- Compare the log identifier with your recorded your submitted job identifier.
You'll see the same identifier in both places. That match proves that one archive job crossed the Webhook boundary before reaching the Python processor.
Can't find the job entry?
- Run the existing PowerShell sender again if the latest job is absent.
- Rerun the log command above after the sender completes.
Help me find the submitted archive job in the processor logs.
Your workflow now reaches the processor by name and receives its validated result. Next, you will let only ready results reach your existing Discord report.
Report Ready Jobs to Discord
The processor call now crosses your shared Docker network. The n8n workflow receives a structured JSON result from the processor.
A reachable processor still needs a decision before it can report success. In this step, conditional routing checks the returned status before Discord receives a report.
In this step, get ready to:
- Route processor results with status equal to ready.
- Build a processor-backed Discord report.
- Publish the workflow and prove the complete path.
Gate the success path
An If node sends each processor result down a path based on its data. Your condition allows only results marked ready to reach the reporting node.
- In Firefox, switch back to the n8n workflow canvas from earlier.
- Insert an If node between Process Archive Job and the existing Discord node.
You should now see the If node directly after Process Archive Job on the canvas.
- Add a String condition inside the If node.
- Drag the returned status field from the Process Archive Job output into the condition value.
The condition should now evaluate the processor's returned status field.
- Select is equal to as the String operator.
- Enter ready as the comparison value.
The If node now checks whether the processor returned status equal to ready.
- Connect the If node's true output to the existing Discord node.
- Leave the If node's false output unconnected.
Your canvas should show a reporting path from the If node's true output. The false output should end without another node.
Condition Not Matching Ready?
- Confirm the condition uses status from the output of Process Archive Job.
- Check that the comparison value is lowercase ready.
- Help me diagnose why my n8n If condition does not match the returned status.
Build the processor-backed report
The existing Discord credential already handles access to the channel. The message now needs to use the processor result that passed your condition.
- In the existing Discord node, keep the existing credential selected.
- Set Resource to Message.
The Discord node should still show the credential from your prerequisite workflow.
- Set Operation to Send.
- Remove the old webhook-only message from the message field.
The message field is now ready for a report built from the processor response.
- Switch the Discord node's Message field to Expression mode.
- Replace the previous message by pasting this expression into the Message field:
{{ 'Job ID: ' + $json.jobId + '\nCourse: ' + $json.course + '\nLesson: ' + $json.lesson + '\nStatus: ' + $json.status + '\nProcessed by: ' + $json.processedBy }}
- Check the preview below the Message field.
You should see five labelled lines in the preview: Job ID, Course, Lesson, Status, and Processed by. The final two lines should show ready and Python.
Why Use the Returned Fields?
The processor returns jobId, course, lesson, status, and processedBy as top-level fields. The expression reads each one directly from $json.
Discord now shows which job was processed and which material it covers. It also shows the returned status plus processor identity.
Publish and prove the complete path
n8n keeps canvas edits in a draft until you publish them. Workflow publishing makes this conditional reporting path live for the existing PowerShell sender.
- Select Publish in the canvas header.
- Wait until Publishing changes to Published before you return to PowerShell.
The published workflow now contains the If gate plus the processor-backed Discord message.
Before you send the job, which If output do you expect a processor result with status equal to ready to follow?
- Switch back to the existing Windows PowerShell window.
- Run the existing PowerShell sender with a complete archive job.
The sender should complete its request to the published workflow.
- Return to the latest execution in n8n.
- Inspect the route taken by the submitted job.
You should see the path run through the Webhook, Edit Fields, Process Archive Job, the If node's true output, and the Discord node.
- Return to the existing Discord channel from earlier.
You should see one new Discord message with Job ID, Course, Lesson, Status, and Processed by on separate lines. The final two values should be ready and Python, while the job identifier matches the job you submitted.
Report Missing From Discord?
- Confirm the latest execution followed the If node's true output.
- Confirm the Process Archive Job output contains top-level jobId, course, lesson, status, and processedBy fields.
- Confirm the Discord Message field uses the five-field expression shown above.
- Help me diagnose why my Discord report is missing processor fields.
That completes the local pipeline. A PowerShell job now crosses both containers before a verified result reaches Discord.
Secret mission
Verify the Processor Identity
Strengthen the route by requiring the response to carry both its success status and expected processor identity. Then spoof the identity with pinned data to prove the workflow blocks the report.
Clean Up Your Resources
Clean Up Your Resources
Your new Docker resources run locally with no ongoing service charge. Pick the cleanup option that matches what you want to do next.
Resources you used:
- The archive-automation user-defined bridge network.
- The container network attachments that connect archive-processor with YOUR_N8N_CONTAINER.
- The published n8n workflow additions, including the Process Archive Job node, the If trust gate, plus the processor-backed Discord report.
Keep everything running
No action is needed. Choose this if you want the complete archive pipeline ready for more jobs.
- Leave archive-automation attached to both containers.
- Keep the n8n workflow published so the existing PowerShell sender can trigger the complete path.
- Continue sending archive jobs whenever you want a processor-backed Discord report.
Pause - I'll come back to this later
Pausing frees local system resources while preserving the network plus the published workflow. Everything remains ready for your return.
- Switch back to Windows PowerShell.
- Replace YOUR_N8N_CONTAINER in the command below with the exact n8n container name you recorded.
- Stop both containers by running this command:
docker stop archive-processor YOUR_N8N_CONTAINER
What Does This Command Do?
The docker stop command stops the two existing containers. Their images plus workflow data remain available.
The archive-automation network also remains in place. Its container attachments are ready when you resume.
- Confirm Docker Desktop shows both archive-processor plus your n8n container as stopped.
Container Name Not Working?
- Replace YOUR_N8N_CONTAINER with the exact container name you recorded earlier.
- Check Docker Desktop to confirm that the named container still exists.
Help me check the container name in this cleanup command.
- Restart both containers when you return by running this command:
docker start archive-processor YOUR_N8N_CONTAINER
What Happens When You Resume?
The docker start command restarts the existing containers without recreating them. Their saved network attachments let n8n resolve archive-processor again.
- Run the existing PowerShell sender with a complete archive job.
- Return to the existing Discord channel.
You should see a new accepted-and-ready archive report. That result confirms the paused pipeline has resumed.
Pipeline Not Resuming?
- Confirm Docker Desktop shows both containers as running.
- Check that the start command contains your recorded n8n container name.
- Confirm that both containers remain attached to archive-automation.
Help me restore this local archive pipeline.
Delete - I don't want to use this again
Removing the shared network sounds bigger than it is. These actions preserve your prerequisite containers, processor image, PowerShell sender, plus Discord credential.
- Switch back to Windows PowerShell.
- Replace YOUR_N8N_CONTAINER in the commands below with the exact n8n container name you recorded.
- Disconnect both existing containers from archive-automation by running these commands:
docker network disconnect archive-automation archive-processor
docker network disconnect archive-automation YOUR_N8N_CONTAINER
What Do These Commands Remove?
The docker network disconnect commands remove each container from archive-automation. The containers plus their images remain available for the prerequisite projects.
- Remove the empty bridge network by running this command:
docker network rm archive-automation
What Does This Remove?
The docker network rm command removes the empty archive-automation network. Docker requires both disconnect commands to finish first.
- Confirm that archive-automation is gone by running this check. The command is expected to fail because the network no longer exists:
docker network inspect archive-automation
Why Is This Failure Expected?
This failure is the cleanup signal. Docker can no longer return details for archive-automation because the network is gone.
🙋♀️ Network Still Exists?
- Check that you substituted the real n8n container name in the disconnect command.
- Repeat the relevant disconnect command for any container that remains attached.
- Repeat the network removal command after both disconnect commands succeed.
Help me remove this network safely.
Finding the correct saved workflow version can be a little fiddly because several drafts may look similar.
- Return to the existing n8n workflow canvas in Firefox.
- Restore the original workflow version containing only Webhook, Edit Fields, and Discord.
- Click Publish in the canvas header.
- Run the existing PowerShell sender with a complete archive job.
- Return to the existing Discord channel.
You should see the original report from the prerequisite workflow. That result proves this project's HTTP Request plus If additions are no longer live.
Cleanup complete. Your prerequisite containers, image, sender, workflow, plus Discord credential remain available.
Nice Work!
Nice Work!
You did it. Your complete archive pipeline now sends trusted processor results to Discord.
You can now demonstrate each archive job moving from n8n to the Python processor. The success report appears only after both trust checks pass.
You've learned how to:
- Proved the container boundary when n8n could not reach the sibling processor through 127.0.0.1. Fixed the route with a user-defined Docker bridge network that discovers archive-processor by name.
- Sent archive-job JSON to POST /process. Traced the structured processor response to the matching container log.
- Routed only ready results through a conditional gate to the existing Discord node. Confirmed a real archive job produced a processor-backed report.
- Secret Mission: Required two trust conditions before reporting success: status equal to ready plus processedBy equal to Python. Used pinned mock data to prove that Unknown follows the false path without sending a Discord message.
Ready to quiz yourself?