n8n Integration
Self-hosted workflow automation with full control over your data.
Overview
n8n is an open-source, self-hostable automation tool. Keep photo data on your infrastructure while automating workflows with 200+ integrations.
Prerequisites
- Visiono account with API access
- n8n instance (self-hosted or cloud)
- API Key from Visiono
Why n8n?
| Feature | Benefit |
|---|---|
| Self-hosted | Full data control |
| Open source | Inspect and modify code |
| No execution limits | Unlimited workflows |
| Custom nodes | Build integrations |
| Fair-code license | Free for most uses |
Setup Steps
1. Create Webhook Node
- Open n8n workflow editor
- Add Webhook node
- Set method: POST
- Copy the webhook URL (Production or Test)
2. Configure in Visiono
- Go to Workspace Settings → Webhooks
- Click Add Webhook
- Paste n8n webhook URL
- Select events to trigger
- Save configuration
3. Test the Connection
- In n8n, click Listen for Test Event
- Submit a test photo in Visiono
- n8n displays received data
- Click Stop Listening
4. Build Your Workflow
Add nodes to process data:
[Webhook] → [IF] → [HTTP Request] → [Email]
↘ [Slack]Workflow Examples
Photo Backup Workflow
Save photos to local storage or S3:
json
{
"nodes": [
{
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"parameters": {
"path": "visiono-photos",
"httpMethod": "POST"
}
},
{
"name": "Loop Photos",
"type": "n8n-nodes-base.splitInBatches",
"parameters": {
"batchSize": 1
}
},
{
"name": "Download Photo",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"url": "={{$json.url}}",
"responseFormat": "file"
}
},
{
"name": "Save to S3",
"type": "n8n-nodes-base.awsS3",
"parameters": {
"operation": "upload",
"bucketName": "visiono-backups",
"fileName": "={{$json.slot_name}}.jpg"
}
}
]
}Notification Workflow
Alert team on new submissions:
Nodes:
- Webhook - Receive Visiono event
- Set - Format message data
- Slack - Send to channel
- Email - Send summary
Database Logging
Record submissions to PostgreSQL:
Nodes:
- Webhook - Receive event
- Postgres - Insert record
- IF - Check photo count
- HTTP Request - Call external API
Node Configuration
Webhook Node
yaml
HTTP Method: POST
Path: visiono-webhook
Response Mode: On Received
Response Data: SuccessHTTP Request Node
For downloading photos:
yaml
Method: GET
URL: ={{ $json.data.photos[0].url }}
Response Format: FileIF Node
Conditional routing:
yaml
Condition: Number
Value 1: ={{ $json.data.photos.length }}
Operation: Larger
Value 2: 5Data Reference
Access webhook data in expressions:
| Expression | Data |
|---|---|
{{ $json.event }} | Event type |
{{ $json.data.smart_link.name }} | Permanent Link name |
{{ $json.data.photos[0].url }} | First photo URL |
{{ $json.data.photos.length }} | Photo count |
{{ $json.data.metadata.full_name }} | Submitter name |
{{ $json.data.metadata.unique_field }} | Identifier |
Loops and Iteration
Process All Photos
Use Split In Batches node:
- Add after Webhook
- Set items:
{{ $json.data.photos }} - Batch size: 1
- Connect processing nodes
- Add Merge at end
Aggregate Results
Collect processed data:
- Code node for aggregation
- Store in workflow static data
- Output combined results
Error Handling
Retry on Failure
Configure per-node:
- Continue on Fail: Process next item
- Retry on Fail: Attempt again
- Max Retries: 3
Error Trigger
Catch and handle errors:
- Add Error Trigger node
- Connect to notification node
- Log or alert on failures
Self-Hosting Tips
Docker Deployment
yaml
version: "3"
services:
n8n:
image: n8nio/n8n
ports:
- "5678:5678"
environment:
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=admin
- N8N_BASIC_AUTH_PASSWORD=secure-password
- WEBHOOK_URL=https://n8n.yourdomain.com/
volumes:
- n8n_data:/home/node/.n8nWebhook URL
For production webhooks:
- Use production URL (not test)
- Configure
WEBHOOK_URLenvironment variable - Use HTTPS with valid certificate
Security
- Enable authentication
- Use HTTPS
- Restrict network access
- Regular backups
Advanced Features
Custom Code
Use Code node for JavaScript:
javascript
const photos = items[0].json.data.photos;
const processed = photos.map(photo => ({
url: photo.url,
name: photo.slot_name,
downloaded: new Date().toISOString()
}));
return [{ json: { photos: processed } }];Credentials
Store API keys securely:
- Go to Credentials
- Add new credential
- Reference in nodes
Sub-Workflows
Modularize workflows:
- Create reusable workflow
- Call via Execute Workflow node
- Pass data between workflows
Troubleshooting
Webhook Not Receiving
- Check n8n is running
- Verify URL includes port if needed
- Check firewall allows traffic
- Test with curl
Expression Errors
- Verify data structure
- Check property paths
- Use optional chaining:
$json.data?.photos
Execution Issues
- Check execution log
- Review node outputs
- Test individual nodes
- Verify credentials
Performance Optimization
Batch Processing
- Group similar operations
- Use bulk API calls
- Limit concurrent executions
Resource Management
- Monitor memory usage
- Limit workflow executions
- Archive old data
Related Resources
- Webhooks - Event configuration
- API Reference - Direct API access
- Zapier Integration - Cloud alternative
- Make Integration - Visual builder
