44 min readDeterministic automation

Implementation Guide: Trigger content approval workflows and route assets to correct stakeholders

Step-by-step implementation guide for deploying AI to trigger content approval workflows and route assets to correct stakeholders for Marketing & Creative Agencies clients.

Hardware Procurement

VPS for n8n Automation Engine

VPS for n8n Automation Engine

DigitalOceanDroplet - s-2vcpu-4gb (Regular Intel SSD)Qty: 1

$24/month MSP cost / $150/month suggested resale as managed automation hosting

Hosts the self-hosted n8n Community Edition instance that serves as the central orchestration engine for all workflow triggers, routing logic, and inter-platform integrations. Sized at 2 vCPU, 4 GB RAM, 80 GB SSD which exceeds n8n minimum requirements and provides headroom for concurrent workflow executions across multiple client accounts.

Managed PostgreSQL Database

DigitalOceandb-s-1vcpu-1gb (PostgreSQL 16)Qty: 1

$15/month MSP cost (included in managed hosting resale price)

Provides persistent, backed-up storage for n8n workflow execution history, credentials, and configuration. Managed PostgreSQL eliminates database maintenance burden and provides automatic daily backups, failover, and connection pooling. Required for production n8n deployments to replace the default SQLite which is not suitable for concurrent workflow executions.

Software Procurement

monday.com Pro Plan

monday.comper-seat SaaSQty: 15 seats

$19/seat/month billed annually (MSP cost via partner program) / $23/seat/month suggested resale — ~$285/month cost / $345/month resale

Core project management platform and approval task backbone. Pro tier is required for its 25,000 automations/month limit, time tracking, formula columns, and chart views. Agencies use this as their single source of truth for project status, and approval tasks are created and tracked as native monday.com items with status columns mapped to approval states (Pending Review, Approved, Revision Requested, Final Approved).

Ziflow Standard Plan

ZiflowStandard PlanQty: Up to 15 licensed users, unlimited reviewers

$249/month MSP cost / $325/month suggested resale

Dedicated creative proofing platform that handles the actual asset review experience — markup, annotations, version comparison, and structured reviewer workflows. Supports PDF, PSD, AI, video, HTML5 banners, and live web pages. Unlimited external reviewers means client stakeholders can review and approve without consuming paid seats. SOC 2 compliant with SSO support.

Zapier Team Plan

ZapierSaaS usage-based

$69/month MSP cost / $99/month suggested resale

Secondary integration layer used specifically for connecting Ziflow approval events to monday.com status updates and Slack notifications where direct webhooks are not available. The Team plan provides 2,000 tasks/month and multi-step Zaps with conditional logic. Used as a complement to n8n for vendor-specific connectors that Zapier handles more reliably out of the box.

n8n Community Edition

n8n GmbHCommunity Edition

$0 software cost (infrastructure cost covered by DigitalOcean VPS above)

Primary workflow automation and orchestration engine. Handles the deterministic routing logic: when an asset enters the system, n8n evaluates its metadata (content type, client account, campaign phase, compliance flags) and triggers the appropriate approval chain. Self-hosting gives the MSP full control, zero per-execution fees, and the highest margin opportunity in the stack.

Slack Pro Plan

Slack (Salesforce)per-seat SaaSQty: 15 users

$8.75/user/month billed annually — assumed client already has this; if not, ~$131/month for 15 users

Real-time notification layer for approval requests, reminders, and status updates. Slack channels are created per client account, and bot notifications are posted when approvals are needed, overdue, or completed. Most agencies already have Slack; this line item is included only if procurement is needed.

$14/user/month (Google) or $12.50/user/month (Microsoft) — assumed client already has this

Provides SSO identity provider for all platforms in the stack, shared drive storage for asset staging, and email for external stakeholder notifications when reviewers are outside the Slack workspace. Also provides the calendar integration for deadline tracking.

Prerequisites

  • Client must have an active Google Workspace or Microsoft 365 tenant with admin access for SSO configuration and API consent grants
  • Minimum 25 Mbps symmetrical internet connection at the agency office (100+ Mbps recommended for agencies producing video content regularly)
  • Client must provide a complete list of all active client accounts, typical content types produced (social, print, video, web, email), and the current approval chain for each — this becomes the routing rules matrix
  • Client must identify at minimum: one Agency Admin (workflow owner), Creative Directors per team, Account Managers per client account, and any external client reviewers with email addresses
  • Outbound HTTPS (port 443) must be open to monday.com, Ziflow, Slack, Zapier, and the n8n VPS — no special firewall rules beyond standard business configuration
  • MSP must have a DigitalOcean account (or equivalent VPS provider) with billing configured and SSH key pairs generated for the n8n server
  • DNS access is required to configure a subdomain (e.g., automations.agencyname.com) pointed at the n8n VPS with SSL via Let's Encrypt
  • Client must provide or agree to create a dedicated service account email (e.g., automations@agencyname.com) for API integrations — this account should not be tied to any individual employee
  • All stakeholders who will participate in approval workflows must have accepted invitations to the agency Slack workspace before go-live
  • Docker and Docker Compose must be installed on the MSP technician's local machine for testing n8n configurations before deploying to production VPS

Installation Steps

Step 1: Provision and Secure the n8n VPS

Create a DigitalOcean Droplet to host the n8n automation engine. This server will run 24/7 and process all workflow triggers. We use Docker Compose for deployment to ensure reproducible configuration and easy updates.

bash
doctl compute droplet create n8n-agency --region nyc3 --size s-2vcpu-4gb --image docker-20-04 --ssh-keys $(doctl compute ssh-key list --format ID --no-header | head -1) --tag-names n8n,production
doctl compute firewall create --name n8n-firewall --inbound-rules 'protocol:tcp,ports:22,address:YOUR_MSP_OFFICE_IP/32 protocol:tcp,ports:443,address:0.0.0.0/0 protocol:tcp,ports:80,address:0.0.0.0/0' --outbound-rules 'protocol:tcp,ports:all,address:0.0.0.0/0 protocol:udp,ports:all,address:0.0.0.0/0' --droplet-ids $(doctl compute droplet list --format ID --no-header | head -1)
ssh root@<DROPLET_IP>
apt update && apt upgrade -y
adduser n8nuser && usermod -aG sudo n8nuser && usermod -aG docker n8nuser
ufw allow OpenSSH && ufw allow 'Nginx Full' && ufw enable
apt install -y nginx certbot python3-certbot-nginx
Note

Replace YOUR_MSP_OFFICE_IP with the MSP's static office IP to restrict SSH access. Never leave SSH open to 0.0.0.0/0. Enable DigitalOcean monitoring alerts for CPU > 80% and disk > 75%. If client prefers AWS, use a t3.medium EC2 instance (~$30/month) with equivalent security groups.

Step 2: Configure DNS and SSL for n8n

Point a subdomain to the VPS and configure Nginx as a reverse proxy with automatic SSL certificate renewal. This gives the n8n instance a professional URL and encrypted connections.

1
In client's DNS provider, add an A record: automations.agencyname.com -> <DROPLET_IP>
2
On the VPS, create Nginx config:
Create Nginx reverse proxy config, enable site, and provision SSL certificate
bash
cat > /etc/nginx/sites-available/n8n << 'EOF'
server {
    server_name automations.agencyname.com;
    location / {
        proxy_pass http://localhost:5678;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        chunked_transfer_encoding off;
        proxy_buffering off;
        proxy_cache off;
    }
}
EOF
ln -s /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
certbot --nginx -d automations.agencyname.com --non-interactive --agree-tos -m msp-admin@mspcompany.com
Note

DNS propagation can take up to 48 hours but typically completes in 15 minutes with low TTL. Verify with 'dig automations.agencyname.com' before running certbot. Certbot auto-renewal is configured by default via systemd timer.

Step 3: Deploy n8n with Docker Compose

Deploy n8n using Docker Compose with PostgreSQL as the database backend, environment variables for configuration, and persistent volumes for data durability. This is the core automation engine that all routing logic runs on.

1
Switch to the n8n user account
2
Create the n8n-docker directory and navigate into it
3
Write the docker-compose.yml configuration file
4
Start the containers in detached mode
5
Follow the n8n container logs
Create docker-compose.yml and start n8n with PostgreSQL
bash
su - n8nuser
mkdir -p ~/n8n-docker && cd ~/n8n-docker
cat > docker-compose.yml << 'COMPOSE'
version: '3.8'
services:
  n8n:
    image: docker.n8n.io/n8nio/n8n:latest
    restart: always
    ports:
      - '127.0.0.1:5678:5678'
    environment:
      - N8N_HOST=automations.agencyname.com
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - WEBHOOK_URL=https://automations.agencyname.com/
      - N8N_BASIC_AUTH_ACTIVE=true
      - N8N_BASIC_AUTH_USER=mspadmin
      - N8N_BASIC_AUTH_PASSWORD=CHANGE_THIS_STRONG_PASSWORD
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=db
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=CHANGE_THIS_DB_PASSWORD
      - GENERIC_TIMEZONE=America/New_York
      - N8N_LOG_LEVEL=info
      - N8N_METRICS=true
      - EXECUTIONS_DATA_PRUNE=true
      - EXECUTIONS_DATA_MAX_AGE=168
    volumes:
      - n8n_data:/home/node/.n8n
    depends_on:
      - db
  db:
    image: postgres:16-alpine
    restart: always
    environment:
      - POSTGRES_USER=n8n
      - POSTGRES_PASSWORD=CHANGE_THIS_DB_PASSWORD
      - POSTGRES_DB=n8n
    volumes:
      - postgres_data:/var/lib/postgresql/data
volumes:
  n8n_data:
  postgres_data:
COMPOSE
docker compose up -d
docker compose logs -f n8n
Critical

Change both CHANGE_THIS_STRONG_PASSWORD and CHANGE_THIS_DB_PASSWORD to unique, randomly generated 32+ character passwords. Store these in the MSP's password manager (e.g., IT Glue, Hudu). The WEBHOOK_URL must match the exact public URL or inbound webhooks will fail. Set GENERIC_TIMEZONE to the agency's local timezone. Execution data is pruned after 168 hours (7 days) to manage disk usage.

Step 4: Provision and Configure monday.com Workspace

Set up the monday.com workspace with a standardized board structure that supports approval workflow tracking. Each client account gets its own board, and approval items follow a consistent column schema that n8n can read and write via the API.

1
monday.com API — Create a workspace via GraphQL API: POST https://api.monday.com/v2 | Header: Authorization: Bearer <MONDAY_API_TOKEN> | Header: Content-Type: application/json
2
Query to create a new board for a client (see command below)
3
After board creation, add required columns via the UI or API:
Create a new monday.com board for a client via GraphQL API
bash
curl -X POST https://api.monday.com/v2 \
  -H 'Authorization: Bearer MONDAY_API_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"query": "mutation { create_board (board_name: \"[Client Name] - Content Approvals\", board_kind: public, workspace_id: WORKSPACE_ID) { id } }"}'
  • Status Column: 'Approval Status' (labels: Pending Upload, In Review, Revision Requested, Approved, Final Approved, Published)
  • People Column: 'Current Reviewer'
  • People Column: 'Asset Owner'
  • Dropdown Column: 'Content Type' (values: Social Post, Blog Article, Email Campaign, Print Collateral, Video, Web Banner, Landing Page)
  • Dropdown Column: 'Client Account'
  • Date Column: 'Review Deadline'
  • Link Column: 'Ziflow Proof Link'
  • Text Column: 'Revision Notes'
  • Number Column: 'Revision Count'
  • Status Column: 'Compliance Check' (labels: Not Required, Pending, Cleared, Flagged)
Note

Create a monday.com Template board first, then duplicate it for each new client account. This ensures consistency. The API token should come from the service account (automations@agencyname.com), not a personal account. monday.com Pro plan is required for the automation actions/month limit (25,000) and the API rate limits needed for integration. Enable board-level permissions so external client reviewers can only see their own board.

Step 5: Configure Ziflow Proofing Workspace

Set up Ziflow with separate project folders per client account, configure reviewer groups matching the approval chains documented in discovery, and establish proof settings for each content type. Ziflow handles the actual asset review experience — markup, comments, version comparison.

1
Navigate to Settings > SSO and configure SAML with Google Workspace / Azure AD: Entity ID: https://app.ziflow.com | ACS URL: Provided in Ziflow SSO settings | Map email attribute for user provisioning
2
Create Client Folders: For each client account, create a Project folder | Set default reviewer groups per folder
3
Create Workflow Templates (Settings > Workflow Templates): 'Standard Review': Creative Director → Account Manager → Client | 'Rush Review': Creative Director + Account Manager (parallel) → Client | 'Compliance Required': Compliance Officer → Creative Director → Account Manager → Client | 'Internal Only': Creative Director → Account Manager (no client stage)
4
Configure Webhook for n8n integration: Settings > Integrations > Webhooks | Create webhook for events: proof.created, proof.decision.made, proof.comment.added | Note the webhook secret for n8n configuration
Ziflow webhook endpoint URL for n8n integration
text
Webhook URL: https://automations.agencyname.com/webhook/ziflow-events
Note

Ziflow allows unlimited external reviewers on the Standard plan, so client stakeholders reviewing proofs do not consume paid seats. Set up email notification templates in Ziflow under Settings > Notifications to match the agency's brand. Configure proof expiration to 30 days to prevent stale proofs from cluttering the workspace. Ensure the webhook secret is stored in the MSP password manager.

Step 6: Configure Slack Integration Channels and Bot

Create a structured Slack channel hierarchy for approval notifications and set up the Slack bot that will post approval requests, reminders, and status updates. This is the real-time notification layer that keeps reviewers responsive.

1
Create Slack channels via Slack admin or API using the pattern #approvals-[client-name] for each client account, plus #approvals-internal for agency-wide approval activity, plus #approvals-urgent for escalations and overdue items
2
Go to https://api.slack.com/apps
3
Click 'Create New App' > 'From scratch'
4
App Name: 'Approval Bot'
5
Select the agency's Slack workspace
6
Navigate to 'OAuth & Permissions'
7
Add Bot Token Scopes: chat:write, chat:write.public, channels:read, groups:read, users:read, users:read.email, files:write
8
Install to workspace and copy Bot User OAuth Token — it starts with xoxb-
9
Store the token in n8n credentials as 'Slack Approval Bot'
Note

The Slack bot token must be stored in n8n's credential manager, NOT hardcoded in workflows. Create a #approvals-test channel for development and testing. Consider setting Slack channel notification defaults to 'All new messages' for approval channels so reviewers don't miss requests. If the agency uses Microsoft Teams instead of Slack, replace this step with a Teams Incoming Webhook connector per channel.

Step 7: Build the Asset Routing Rules Matrix in n8n

Create the core n8n workflow that implements the deterministic routing logic. When a new asset enters the system (via Ziflow webhook, monday.com status change, or direct API call), this workflow evaluates the asset metadata and routes it to the correct approval chain, updates monday.com, and sends Slack notifications.

1
This is configured in the n8n web UI at https://automations.agencyname.com
2
Import the workflow JSON provided in the custom_ai_components section
3
After importing, configure credentials: monday.com API Token (Settings > Credentials > monday.com), Ziflow API Key (Settings > Credentials > HTTP Header Auth), Slack Bot Token (Settings > Credentials > Slack OAuth2), Zapier Webhook URLs (for any Zapier-bridged integrations)
4
Activate the workflow and test with a sample asset upload
Note

The routing rules matrix must be built from the discovery document created in prerequisites. Every combination of content type + client account + compliance requirement should map to a specific Ziflow workflow template and reviewer sequence. See the custom_ai_components section for the complete workflow specification. Test each routing path individually before activating the full workflow.

Step 8: Configure Zapier Bridges for Native Connectors

Set up Zapier Zaps that handle specific integration paths where Zapier's pre-built connectors are more reliable than raw API calls — specifically the Ziflow-to-monday.com proof status sync and the monday.com-to-Ziflow proof creation trigger.

Zapier Zap 1: Ziflow Proof Decision → monday.com Status Update

1
Trigger: Ziflow > Proof Decision Made
2
Action 1: Filter — only continue if decision is 'Approved' or 'Revision Requested'
3
Action 2: monday.com > Update Item — Board: Match by client name in proof folder — Item: Match by Ziflow proof name = monday.com item name — Approval Status column: Map decision to status label — Revision Notes: Map Ziflow decision comments — Revision Count: Increment by 1 if 'Revision Requested'

Zapier Zap 2: monday.com New Item → Ziflow Create Proof

1
Trigger: monday.com > Status Change on 'Approval Status' to 'Pending Upload'
2
Filter: Only when a file URL is present in the 'Asset URL' column
3
Action: Ziflow > Create Proof — Folder: Map from 'Client Account' column — Workflow Template: Map from 'Content Type' column — File URL: From monday.com file column

Zapier Zap 3: Overdue Reminder Escalation

1
Trigger: Schedule > Every 2 hours
2
Action 1: monday.com > Find Items where Review Deadline < today AND Approval Status = 'In Review'
3
Action 2: Slack > Send Channel Message to #approvals-urgent — Message: '⚠️ OVERDUE: [Item Name] for [Client] was due [Deadline]. Current reviewer: [Reviewer Name]. Please review immediately.'
Note

Zapier Team plan allows 2,000 tasks/month which is sufficient for a 15-person agency processing ~200-400 assets/month. Monitor task usage in the first month and upgrade if needed. Each Zap should have error notification emails sent to the MSP's support inbox. Name Zaps with a consistent prefix like '[Agency] Approval -' for easy identification.

Step 9: Configure monday.com Native Automations

Set up monday.com's built-in automation recipes that handle intra-board logic — moving items between groups, assigning reviewers, setting deadlines, and triggering status changes. These complement the n8n and Zapier integrations by handling logic that lives entirely within monday.com.

In each client approval board, add these automations:

1
Automation 1: Auto-assign reviewer on status change Recipe: 'When Status changes to In Review, assign Current Reviewer to [person]' Configure per content type using conditional automations: - Social Post → Social Media Manager - Blog Article → Content Lead - Print Collateral → Creative Director - Video → Video Producer - Email Campaign → Email Marketing Manager
2
Automation 2: Set review deadline Recipe: 'When Status changes to In Review, set Review Deadline to today + 2 days' (Adjust per content type: Video = +3 days, Print = +2 days, Social = +1 day)
3
Automation 3: Notify on revision request Recipe: 'When Status changes to Revision Requested, notify Asset Owner'
4
Automation 4: Move to Completed group Recipe: 'When Status changes to Final Approved, move item to Completed group'
5
Automation 5: Send external client notification Recipe: 'When Status changes to Approved (internal), send email to Client Contact' Email template: 'Your [Content Type] for [Campaign Name] has been internally approved. Please review in Ziflow: [Ziflow Proof Link]'
Note

monday.com Pro plan includes 25,000 automation actions/month. Monitor usage in the first month — a 15-person agency typically uses 3,000-8,000 actions. If approaching the limit, move lower-priority automations to n8n. Use monday.com's Automation Activity Log to troubleshoot any misfires during testing.

Step 10: Set Up SSO and User Provisioning

Configure Single Sign-On across all platforms using the agency's Google Workspace or Azure AD identity provider. This ensures one login for all tools, automatic user deprovisioning when employees leave, and meets compliance requirements for access control.

Google Workspace SSO Configuration (if using Google)

1
In Google Admin Console > Apps > Web and mobile apps > Add app > Search for app: Add monday.com SAML app; Add Ziflow SAML app (if available; otherwise use Google OAuth); Add Slack (likely already configured)
2
For each app, configure: ACS URL (from the vendor's SSO settings page); Entity ID (from the vendor's SSO settings page); Name ID: Primary email; Map attributes: firstName, lastName, email
3
Turn ON for the agency's organizational unit

Azure AD SSO Configuration (if using Microsoft 365)

1
Azure Portal > Enterprise Applications > New Application: Search for monday.com, Ziflow in the gallery; Configure SAML settings with metadata from each vendor
2
Assign users/groups to each application
3
Enable automatic provisioning (SCIM) where supported: monday.com supports SCIM provisioning on Enterprise plan; If on Pro plan, use manual user management with SSO for authentication
Note

SSO configuration requires admin access to both the identity provider and each SaaS platform. Ziflow SSO is available on Standard plan. monday.com SSO (SAML) requires Enterprise plan — if client is on Pro, use Google/Microsoft OAuth sign-in instead (less secure but still single-identity). Test SSO login for each platform before removing password-based access. Create a break-glass local admin account for each platform in case SSO fails.

Step 11: Import Existing Projects and Historical Data

Migrate the agency's current active projects into the new approval workflow system. This includes creating monday.com boards for each active client, importing any in-progress approval items, and setting up the initial state so the team can start using the system without a gap in tracking.

1
Export current project list from existing PM tool (Basecamp, Trello, spreadsheets)
2
Map columns to monday.com schema: - Item Name = Asset/Deliverable Name - Status = Current approval state (map to new status labels) - People = Assigned reviewer - Date = Deadline - Text = Any existing notes
3
Import via monday.com Board Settings > Import
  • For each active client board: Create client folder in Ziflow
  • Upload any assets currently in review
  • Link Ziflow proofs to monday.com items via the Ziflow Proof Link column
Run the n8n Initial Sync workflow to validate all connections after migration
bash
# Run the n8n 'Initial Sync' workflow (see custom_ai_components) to validate all connections
Note

Do NOT attempt to migrate historical completed projects — only active and recent (last 30 days) items. Historical data creates noise and confusion. Allocate 2-4 hours per client account for migration depending on volume. Have the Account Manager for each client verify the migrated data before go-live.

Step 12: Conduct User Acceptance Testing

Execute a structured testing protocol that validates every routing path, notification, and integration before going live. Use test assets that represent each content type and client account combination documented in the routing rules matrix.

1
Create a test client board: '[TEST] Acme Corp - Content Approvals'
2
Create a test Ziflow folder: 'TEST - Acme Corp'
3
Create a test Slack channel: #approvals-test
4
Execute test cases (see testing_validation section for full list)

For each test, verify:

Note

Testing should be performed by the MSP technician first, then repeated with 2-3 agency power users as a supervised pilot. Keep the test board and channels active for 1 week post-go-live as a safe space for users to experiment. Common failure points: webhook URL mismatches, timezone differences causing incorrect deadline calculations, and Slack channel ID vs. channel name confusion in n8n.

Custom AI Components

Asset Routing Engine

Type: workflow The core n8n workflow that receives webhook events from Ziflow and monday.com, evaluates asset metadata against the routing rules matrix, and triggers the appropriate approval chain. This is the central orchestration component that replaces manual asset routing with deterministic automation. It handles: new asset upload routing, approval stage progression, revision loop management, escalation triggers, and cross-platform state synchronization.

n8n Workflow: Asset Routing Engine

Workflow JSON (Import into n8n)

Asset Routing Engine — n8n Workflow JSON
json
{
  "name": "Asset Routing Engine",
  "nodes": [
    {
      "name": "Ziflow Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [250, 300],
      "parameters": {
        "path": "ziflow-events",
        "httpMethod": "POST",
        "responseMode": "onReceived",
        "responseData": "allEntries"
      }
    },
    {
      "name": "Parse Event Type",
      "type": "n8n-nodes-base.switch",
      "position": [450, 300],
      "parameters": {
        "dataType": "string",
        "value1": "={{$json.event_type}}",
        "rules": {
          "rules": [
            {"value2": "proof.created", "output": 0},
            {"value2": "proof.decision.made", "output": 1},
            {"value2": "proof.comment.added", "output": 2}
          ]
        }
      }
    },
    {
      "name": "Extract Metadata",
      "type": "n8n-nodes-base.set",
      "position": [650, 200],
      "parameters": {
        "values": {
          "string": [
            {"name": "asset_name", "value": "={{$json.proof.name}}"},
            {"name": "client_account", "value": "={{$json.proof.folder_name}}"},
            {"name": "content_type", "value": "={{$json.proof.tags[0] || 'General'}}"},
            {"name": "proof_id", "value": "={{$json.proof.id}}"},
            {"name": "proof_url", "value": "={{$json.proof.url}}"}
          ]
        }
      }
    },
    {
      "name": "Routing Rules",
      "type": "n8n-nodes-base.switch",
      "position": [850, 200],
      "parameters": {
        "dataType": "string",
        "value1": "={{$json.content_type}}",
        "rules": {
          "rules": [
            {"value2": "Social Post", "output": 0},
            {"value2": "Blog Article", "output": 1},
            {"value2": "Email Campaign", "output": 2},
            {"value2": "Print Collateral", "output": 3},
            {"value2": "Video", "output": 4},
            {"value2": "Web Banner", "output": 5},
            {"value2": "Landing Page", "output": 6}
          ]
        },
        "fallbackOutput": "extra"
      }
    },
    {
      "name": "Set Social Routing",
      "type": "n8n-nodes-base.set",
      "position": [1050, 50],
      "parameters": {
        "values": {
          "string": [
            {"name": "workflow_template", "value": "Standard Review"},
            {"name": "reviewer_sequence", "value": "Social Media Manager,Account Manager,Client"},
            {"name": "sla_hours", "value": "24"},
            {"name": "slack_channel_prefix", "value": "approvals"}
          ]
        }
      }
    },
    {
      "name": "Set Print Routing",
      "type": "n8n-nodes-base.set",
      "position": [1050, 250],
      "parameters": {
        "values": {
          "string": [
            {"name": "workflow_template", "value": "Compliance Required"},
            {"name": "reviewer_sequence", "value": "Creative Director,Compliance Officer,Account Manager,Client"},
            {"name": "sla_hours", "value": "48"},
            {"name": "slack_channel_prefix", "value": "approvals"}
          ]
        }
      }
    },
    {
      "name": "Set Video Routing",
      "type": "n8n-nodes-base.set",
      "position": [1050, 450],
      "parameters": {
        "values": {
          "string": [
            {"name": "workflow_template", "value": "Standard Review"},
            {"name": "reviewer_sequence", "value": "Video Producer,Creative Director,Account Manager,Client"},
            {"name": "sla_hours", "value": "72"},
            {"name": "slack_channel_prefix", "value": "approvals"}
          ]
        }
      }
    },
    {
      "name": "Create Monday Item",
      "type": "n8n-nodes-base.mondayCom",
      "position": [1300, 300],
      "parameters": {
        "resource": "boardItem",
        "operation": "create",
        "boardId": "={{$env.MONDAY_BOARD_MAP[$json.client_account]}}",
        "itemName": "={{$json.asset_name}}",
        "columnValues": {
          "approval_status": "In Review",
          "content_type": "={{$json.content_type}}",
          "current_reviewer": "={{$json.reviewer_sequence.split(',')[0]}}",
          "review_deadline": "={{$now.plus({hours: parseInt($json.sla_hours)}).toISO()}}",
          "ziflow_proof_link": "={{$json.proof_url}}",
          "revision_count": 0
        }
      }
    },
    {
      "name": "Notify Slack",
      "type": "n8n-nodes-base.slack",
      "position": [1500, 300],
      "parameters": {
        "channel": "={{$json.slack_channel_prefix + '-' + $json.client_account.toLowerCase().replace(/ /g, '-')}}",
        "text": "",
        "blocksUi": {
          "blocksValues": [
            {
              "type": "section",
              "text": {
                "type": "mrkdwn",
                "text": "🎨 *New Approval Request*\n*Asset:* {{$json.asset_name}}\n*Type:* {{$json.content_type}}\n*Client:* {{$json.client_account}}\n*Reviewer:* {{$json.reviewer_sequence.split(',')[0]}}\n*Deadline:* {{$now.plus({hours: parseInt($json.sla_hours)}).toFormat('MMM dd, yyyy h:mm a')}}"
              }
            },
            {
              "type": "actions",
              "elements": [
                {
                  "type": "button",
                  "text": {"type": "plain_text", "text": "Review in Ziflow"},
                  "url": "{{$json.proof_url}}",
                  "style": "primary"
                }
              ]
            }
          ]
        }
      }
    }
  ],
  "connections": {
    "Ziflow Webhook": {"main": [[{"node": "Parse Event Type", "type": "main", "index": 0}]]},
    "Parse Event Type": {"main": [[{"node": "Extract Metadata", "type": "main", "index": 0}], [{"node": "Handle Decision", "type": "main", "index": 0}], [{"node": "Handle Comment", "type": "main", "index": 0}]]},
    "Extract Metadata": {"main": [[{"node": "Routing Rules", "type": "main", "index": 0}]]},
    "Routing Rules": {"main": [[{"node": "Set Social Routing"}], [{"node": "Set Blog Routing"}], [{"node": "Set Email Routing"}], [{"node": "Set Print Routing"}], [{"node": "Set Video Routing"}], [{"node": "Set WebBanner Routing"}], [{"node": "Set LandingPage Routing"}]]},
    "Set Social Routing": {"main": [[{"node": "Create Monday Item"}]]},
    "Set Print Routing": {"main": [[{"node": "Create Monday Item"}]]},
    "Set Video Routing": {"main": [[{"node": "Create Monday Item"}]]},
    "Create Monday Item": {"main": [[{"node": "Notify Slack"}]]}
  }
}

Configuration Notes

  • The MONDAY_BOARD_MAP environment variable in n8n should be a JSON object mapping client account names to monday.com board IDs: {"Acme Corp": "1234567890", "Globex": "0987654321"}
  • Add Set nodes for each content type following the Social/Print/Video pattern above
  • The reviewer_sequence is a comma-separated string parsed at each approval stage
  • Duplicate the Routing Rules switch for additional content types specific to the agency
  • The fallback output handles any unrecognized content types by routing to the Creative Director as default reviewer

Approval Stage Progression Workflow

Type: workflow Handles the progression of assets through multi-stage approval chains. When a reviewer approves at one stage, this workflow automatically advances to the next reviewer in the sequence, updates monday.com, notifies the next reviewer via Slack, and handles revision loops where a reviewer requests changes.

n8n Workflow: Approval Stage Progression

Trigger: Ziflow webhook event `proof.decision.made`

Logic Flow

1
Receive Decision Event from Ziflow webhook — Extract: proof_id, decision (approved/changes_requested), reviewer_email, comments
2
Lookup Monday Item by Ziflow proof URL — Use monday.com API: items_page_by_column_values where ziflow_proof_link = proof_url — Extract: current monday item ID, current reviewer_sequence position, revision_count
3
Switch on Decision (see branches below)
4
Error Handling (see details below)

If APPROVED

  • Parse reviewer_sequence string, find current reviewer's position
  • If NOT last reviewer: Advance current_reviewer to next in sequence
  • Update monday.com item: current_reviewer = next person
  • If next reviewer is 'Client': Update status to 'Client Review'
  • Post Slack notification to next reviewer
  • Post Slack update to channel: '✅ [Reviewer] approved [Asset]. Next: [Next Reviewer]'
  • If LAST reviewer (final approval): Update monday.com status to 'Final Approved'
  • Move item to Completed group
  • Post Slack celebration: '🎉 [Asset] for [Client] is FINAL APPROVED! Ready for publishing.'
  • Send email notification to Asset Owner

If CHANGES_REQUESTED

  • Increment revision_count on monday.com
  • Update status to 'Revision Requested'
  • Reset current_reviewer to Asset Owner
  • Copy Ziflow revision comments to monday.com Revision Notes column
  • Post Slack notification to Asset Owner: '🔄 Revision requested on [Asset] by [Reviewer]: [Comments summary]'
  • If revision_count > 3: Also post to #approvals-urgent with escalation flag

Error Handling

  • If monday.com item not found: Log error, post to #approvals-urgent
  • If Slack post fails: Fall back to email notification
  • All errors logged to n8n execution log with full context

Key Implementation Detail — Reviewer Sequence Tracking

In a Function node, track stage progression:

Function node logic for advancing reviewer sequence position
javascript
const sequence = $json.reviewer_sequence.split(',');
const currentIndex = sequence.indexOf($json.current_reviewer_role);
const nextIndex = currentIndex + 1;

if (nextIndex < sequence.length) {
  return {
    json: {
      ...$json,
      next_reviewer: sequence[nextIndex],
      is_final: false,
      stage_number: nextIndex + 1,
      total_stages: sequence.length
    }
  };
} else {
  return {
    json: {
      ...$json,
      next_reviewer: null,
      is_final: true,
      stage_number: sequence.length,
      total_stages: sequence.length
    }
  };
}

Revision Loop Prevention

  • Maximum 5 revision cycles before automatic escalation to Creative Director + Account Manager
  • After 3 revisions, Slack message includes: '⚠️ This asset has been revised 3+ times. Consider scheduling a live review call.'
  • Track revision reasons in monday.com for pattern analysis

Overdue Escalation Monitor

Type: workflow A scheduled n8n workflow that runs every 2 hours during business hours, checks all monday.com boards for items past their review deadline, and sends escalation notifications to the appropriate managers. Implements a tiered escalation: first reminder at deadline, second to manager at deadline +4 hours, third to director at deadline +8 hours.

Implementation

n8n Workflow: Overdue Escalation Monitor

Trigger: Cron schedule — every 2 hours, Monday-Friday, 8 AM - 8 PM agency timezone

Full n8n workflow JSON for the Overdue Escalation Monitor
json
{
  "name": "Overdue Escalation Monitor",
  "nodes": [
    {
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "parameters": {
        "rule": {
          "interval": [{"field": "hours", "hoursInterval": 2}]
        }
      }
    },
    {
      "name": "Get All Approval Boards",
      "type": "n8n-nodes-base.mondayCom",
      "parameters": {
        "resource": "board",
        "operation": "getAll",
        "returnAll": true
      }
    },
    {
      "name": "Filter Approval Boards",
      "type": "n8n-nodes-base.filter",
      "parameters": {
        "conditions": {
          "string": [{"value1": "={{$json.name}}", "operation": "contains", "value2": "Content Approvals"}]
        }
      }
    },
    {
      "name": "Get Items In Review",
      "type": "n8n-nodes-base.mondayCom",
      "parameters": {
        "resource": "boardItem",
        "operation": "getAll",
        "boardId": "={{$json.id}}",
        "returnAll": true
      }
    },
    {
      "name": "Check Overdue",
      "type": "n8n-nodes-base.function",
      "parameters": {
        "functionCode": "const items = $input.all();\nconst now = new Date();\nconst overdueItems = [];\n\nfor (const item of items) {\n  const data = item.json;\n  const status = data.column_values?.find(c => c.id === 'approval_status');\n  const deadline = data.column_values?.find(c => c.id === 'review_deadline');\n  \n  if (status?.text === 'In Review' || status?.text === 'Client Review') {\n    const deadlineDate = new Date(deadline?.text);\n    if (deadlineDate < now) {\n      const hoursOverdue = Math.floor((now - deadlineDate) / (1000 * 60 * 60));\n      let escalation_level = 'reminder';\n      if (hoursOverdue >= 8) escalation_level = 'director';\n      else if (hoursOverdue >= 4) escalation_level = 'manager';\n      \n      overdueItems.push({\n        json: {\n          item_name: data.name,\n          board_name: data.board?.name || 'Unknown',\n          current_reviewer: data.column_values?.find(c => c.id === 'current_reviewer')?.text,\n          hours_overdue: hoursOverdue,\n          escalation_level: escalation_level,\n          ziflow_link: data.column_values?.find(c => c.id === 'ziflow_proof_link')?.text,\n          client_account: data.column_values?.find(c => c.id === 'client_account')?.text\n        }\n      });\n    }\n  }\n}\n\nreturn overdueItems;"
      }
    },
    {
      "name": "Route by Escalation Level",
      "type": "n8n-nodes-base.switch",
      "parameters": {
        "dataType": "string",
        "value1": "={{$json.escalation_level}}",
        "rules": {
          "rules": [
            {"value2": "reminder", "output": 0},
            {"value2": "manager", "output": 1},
            {"value2": "director", "output": 2}
          ]
        }
      }
    },
    {
      "name": "Send Reminder",
      "type": "n8n-nodes-base.slack",
      "parameters": {
        "channel": "={{$json.client_account ? 'approvals-' + $json.client_account.toLowerCase().replace(/ /g, '-') : 'approvals-internal'}}",
        "text": "⏰ *Reminder:* {{$json.item_name}} for {{$json.client_account}} is {{$json.hours_overdue}} hours past deadline. {{$json.current_reviewer}}, please review: {{$json.ziflow_link}}"
      }
    },
    {
      "name": "Send Manager Escalation",
      "type": "n8n-nodes-base.slack",
      "parameters": {
        "channel": "approvals-urgent",
        "text": "⚠️ *ESCALATION:* {{$json.item_name}} for {{$json.client_account}} is {{$json.hours_overdue}} hours overdue. Assigned reviewer: {{$json.current_reviewer}}. Account Manager — please intervene. {{$json.ziflow_link}}"
      }
    },
    {
      "name": "Send Director Escalation",
      "type": "n8n-nodes-base.slack",
      "parameters": {
        "channel": "approvals-urgent",
        "text": "🚨 *CRITICAL:* {{$json.item_name}} for {{$json.client_account}} is {{$json.hours_overdue}} hours overdue (8+ hours). Creative Director — immediate action required. Reviewer: {{$json.current_reviewer}}. {{$json.ziflow_link}}"
      }
    }
  ]
}

Schedule Configuration

  • Run every 2 hours between 8 AM and 8 PM, Monday through Friday
  • Agency timezone configured in n8n environment variable GENERIC_TIMEZONE
  • Do NOT run on weekends or agency-designated holidays (maintain a holiday list in n8n static data)
  • First run at 10 AM to allow morning processing time

Client Board Provisioning Workflow

Type: workflow

An on-demand n8n workflow triggered via a simple form or API call that automates the setup of a new client account across all platforms — creates the monday.com board from template, Ziflow folder, Slack channel, and configures the routing rules for the new client. Reduces new client onboarding from 2 hours of manual setup to a 5-minute form submission.

Implementation

n8n Workflow: Client Board Provisioning

Trigger: n8n Form Trigger or Webhook POST with payload:

Webhook POST payload to trigger client provisioning workflow
json
{
  "client_name": "Acme Corp",
  "account_manager_email": "am@agency.com",
  "creative_director_email": "cd@agency.com",
  "client_reviewer_emails": ["marketing@acme.com", "cmo@acme.com"],
  "content_types": ["Social Post", "Blog Article", "Email Campaign"],
  "compliance_required": false,
  "default_sla_hours": 48
}

Steps

1
Validate Input (Function node): Verify all required fields present, sanitize client_name for use in channel names (lowercase, hyphens, no special chars), generate slug: acme-corp

Step 2 — Create monday.com Board (HTTP Request node)

Duplicate monday.com board from template for new client
http
POST https://api.monday.com/v2
Authorization: Bearer {{$credentials.mondayApi.apiToken}}

{
  "query": "mutation { duplicate_board (board_id: TEMPLATE_BOARD_ID, duplicate_type: duplicate_board_with_structure, board_name: \"{{$json.client_name}} - Content Approvals\") { board { id } } }"
}
  • Store returned board_id
  • Update the MONDAY_BOARD_MAP environment variable (or a static data store in n8n)

Step 3 — Create Ziflow Folder (HTTP Request node)

Create Ziflow folder for new client, selecting compliance or standard workflow
http
POST https://api.ziflow.com/v1/folders
Authorization: Bearer {{$credentials.ziflowApi.apiToken}}

{
  "name": "{{$json.client_name}}",
  "default_workflow_id": "{{$json.compliance_required ? COMPLIANCE_WORKFLOW_ID : STANDARD_WORKFLOW_ID}}"
}

Step 4 — Invite External Reviewers to Ziflow (Loop node): For each email in client_reviewer_emails:

Invite each client reviewer to the Ziflow folder (looped per email)
http
POST https://api.ziflow.com/v1/users/invite

{
  "email": "{{$json.email}}",
  "role": "reviewer",
  "folder_ids": ["{{$json.ziflow_folder_id}}"]
}
1
Create Slack Channel (Slack node): Channel name: approvals-{{$json.slug}} — Set channel topic: Approval notifications for {{$json.client_name}} — Invite Account Manager and Creative Director — Post welcome message with workflow overview
2
Update Routing Configuration (Function node): Add new client to the n8n static data routing map — Map content_types to appropriate workflow templates — Set SLA hours per content type
3
Send Confirmation (Slack node): Post to #approvals-internal: ✅ New client provisioned: {{$json.client_name}}. Board: [link], Ziflow: [link], Channel: #approvals-{{$json.slug}} — Send email to Account Manager with setup summary and onboarding checklist

Error Handling

Warning

If any step fails, roll back previous steps (delete created resources), post error details to #approvals-urgent, and log full error context to the n8n execution log for MSP troubleshooting.

Weekly Approval Analytics Report

Type: workflow A scheduled weekly workflow that compiles approval metrics from monday.com — average approval time by content type, number of revision cycles, overdue rate, and bottleneck identification — and posts a formatted summary to Slack and emails it to agency leadership. Provides the data needed to continuously optimize approval workflows.

Implementation

n8n Workflow: Weekly Approval Analytics

Trigger: Cron — Every Monday at 9:00 AM agency timezone

1
Query All Approval Boards via monday.com API: Get all items where status changed to 'Final Approved' in the past 7 days; Get all items currently 'In Review' with their creation dates; Get all items with status 'Revision Requested' and revision_count
2
Calculate Metrics (Function node)
3
Format Slack Report (Set node)
4
Post to Slack #approvals-internal channel
5
Send Email to agency leadership (Creative Director, Operations Manager)
Step 2: Calculate Metrics — Function node
javascript
const items = $input.all();
const now = new Date();
const weekAgo = new Date(now - 7 * 24 * 60 * 60 * 1000);

const metrics = {
  total_completed: 0,
  total_in_progress: 0,
  avg_approval_hours: 0,
  revision_rate: 0,
  overdue_count: 0,
  by_content_type: {},
  by_client: {},
  bottleneck_reviewer: null,
  longest_pending: null
};

let totalHours = 0;
let revisedCount = 0;

for (const item of items) {
  const d = item.json;
  const contentType = d.content_type || 'Unknown';
  const client = d.client_account || 'Unknown';
  
  if (!metrics.by_content_type[contentType]) {
    metrics.by_content_type[contentType] = { completed: 0, avg_hours: 0, revisions: 0 };
  }
  if (!metrics.by_client[client]) {
    metrics.by_client[client] = { completed: 0, avg_hours: 0, revisions: 0 };
  }
  
  if (d.status === 'Final Approved') {
    metrics.total_completed++;
    const hours = d.completion_hours || 0;
    totalHours += hours;
    metrics.by_content_type[contentType].completed++;
    metrics.by_client[client].completed++;
  }
  
  if (d.revision_count > 0) {
    revisedCount++;
    metrics.by_content_type[contentType].revisions += d.revision_count;
  }
  
  if (d.status === 'In Review' && new Date(d.deadline) < now) {
    metrics.overdue_count++;
  }
}

metrics.avg_approval_hours = metrics.total_completed > 0 ? 
  Math.round(totalHours / metrics.total_completed) : 0;
metrics.revision_rate = items.length > 0 ? 
  Math.round((revisedCount / items.length) * 100) : 0;

return [{ json: metrics }];
Step 3: Format Slack Report — Set node template
handlebars
📊 *Weekly Approval Report* ({{weekStart}} — {{weekEnd}})

*Overall Metrics:*
• Assets Completed: {{total_completed}}
• Currently In Progress: {{total_in_progress}}
• Average Approval Time: {{avg_approval_hours}} hours
• Revision Rate: {{revision_rate}}%
• Currently Overdue: {{overdue_count}}

*By Content Type:*
{{#each by_content_type}}
• {{@key}}: {{this.completed}} completed, avg {{this.avg_hours}}h, {{this.revisions}} revisions
{{/each}}

*By Client:*
{{#each by_client}}
• {{@key}}: {{this.completed}} completed
{{/each}}

*Action Items:*
{{#if overdue_count}}⚠️ {{overdue_count}} items currently overdue — review in #approvals-urgent{{/if}}
{{#if high_revision_types}}🔄 High revision rates on: {{high_revision_types}} — consider adding a brief checkpoint before formal review{{/if}}

Value to MSP

  • This report demonstrates ongoing value to the client
  • Metrics inform workflow optimization recommendations (upsell opportunity)
  • Trending data helps justify the managed services retainer

Testing & Validation

  • TEST 1 — Social Post Routing: Upload a test social media image to the test Ziflow folder tagged 'Social Post'. Verify within 60 seconds: (a) n8n execution log shows successful webhook receipt, (b) a new item appears on the test monday.com board with status 'In Review' and Content Type 'Social Post', (c) Current Reviewer is set to 'Social Media Manager', (d) Review Deadline is set to 24 hours from now, (e) Slack notification appears in #approvals-test with asset name, reviewer, and Ziflow link button.
  • TEST 2 — Print Collateral Compliance Routing: Upload a test PDF tagged 'Print Collateral' to the test Ziflow folder. Verify the Compliance Required workflow template is selected in Ziflow, and the reviewer sequence includes Compliance Officer as the first reviewer. Verify the monday.com item shows a 48-hour SLA deadline and the Compliance Check column is set to 'Pending'.
  • TEST 3 — Approval Stage Progression: In Ziflow, approve the test social post as the Social Media Manager. Verify: (a) monday.com current_reviewer updates to Account Manager, (b) Slack posts '✅ Social Media Manager approved [asset]. Next: Account Manager', (c) Ziflow advances to the next proof stage. Then approve as Account Manager and verify progression to Client stage.
  • TEST 4 — Revision Request Loop: In Ziflow, select 'Changes Requested' on a test proof and add a comment 'Please adjust the color palette'. Verify: (a) monday.com status changes to 'Revision Requested', (b) Revision Count increments to 1, (c) Revision Notes column contains the Ziflow comment text, (d) Slack notification goes to the Asset Owner with the revision details, (e) Current Reviewer resets to Asset Owner.
  • TEST 5 — Overdue Escalation Tier 1: Create a monday.com item with Review Deadline set to 1 hour ago and status 'In Review'. Manually trigger the Overdue Escalation Monitor workflow. Verify a reminder message posts to the appropriate client approval channel with the reviewer's name and Ziflow link.
  • TEST 6 — Overdue Escalation Tier 2: Create a monday.com item with Review Deadline set to 5 hours ago. Trigger the escalation workflow. Verify the message posts to #approvals-urgent (not just the client channel) with 'ESCALATION' prefix and mentions the Account Manager.
  • TEST 7 — Overdue Escalation Tier 3: Create a monday.com item with Review Deadline set to 9 hours ago. Verify the message posts to #approvals-urgent with 'CRITICAL' prefix and mentions the Creative Director.
  • TEST 8 — New Client Provisioning: Trigger the Client Board Provisioning workflow with test data for a fictional client 'Test Industries'. Verify: (a) A new monday.com board 'Test Industries - Content Approvals' is created with all required columns, (b) A Ziflow folder 'Test Industries' exists, (c) Slack channel #approvals-test-industries is created, (d) Confirmation message posts to #approvals-internal. Then clean up all test resources.
  • TEST 9 — Final Approval End-to-End: Walk through a complete approval lifecycle for one test asset — upload, route, review at each stage, approve at each stage, reach 'Final Approved'. Verify the celebration message in Slack, the item moves to the Completed group in monday.com, and the email notification reaches the Asset Owner. Time the entire process and confirm it completes in under 5 minutes of active reviewer time.
  • TEST 10 — Zapier Integration Sync: Create a proof in Ziflow and make a decision. Verify the Zapier Zap correctly updates the corresponding monday.com item status within 2 minutes. Check Zapier task history for successful execution with no errors.
  • TEST 11 — SSO Login Verification: Log out of all platforms. Attempt to log into monday.com, Ziflow, and Slack using SSO. Verify all three succeed with a single identity provider login and that user profiles (name, email) are correctly mapped.
  • TEST 12 — Error Handling: Temporarily disable the monday.com API token in n8n. Upload a test proof to Ziflow. Verify n8n logs the error, does NOT crash the workflow, and posts an error notification to #approvals-urgent indicating the monday.com integration failed. Re-enable the token and confirm normal operation resumes.
  • TEST 13 — Weekly Analytics Report: Manually trigger the Weekly Approval Analytics workflow. Verify a formatted report appears in #approvals-internal with all metric categories (completed count, average approval time, revision rate, overdue count, by content type, by client). Verify the email is received by the designated recipients.

Client Handoff

Client Handoff Checklist

Training Sessions (Schedule 2 sessions, 90 minutes each)

Session 1: Power Users — Agency Admin, Creative Directors, Account Managers (90 min)

  • How to read and manage the monday.com approval boards: item creation, status changes, column meanings
  • How to review and approve in Ziflow: markup tools, version comparison, decision buttons, comments
  • How the routing logic works: which content types go to which reviewers, SLA timelines, escalation tiers
  • How to add external client reviewers to Ziflow for a new campaign
  • How to interpret the weekly analytics report and identify bottlenecks
  • Live walkthrough of an asset from upload through final approval
  • Q&A and hands-on practice with test assets

Session 2: All Staff — Full team including designers and copywriters (60 min)

  • How to submit assets for approval: uploading to Ziflow, tagging content type, selecting client folder
  • How to respond to revision requests: reading comments, uploading new versions
  • How Slack notifications work: what each notification type means, what action to take
  • What NOT to do: approving via email/Slack instead of Ziflow, changing monday.com statuses manually
  • Quick reference card walkthrough

Documentation to Leave Behind

1
Quick Reference Card (1-page PDF): Visual flowchart of the approval process with screenshots of key actions in Ziflow, monday.com, and Slack. Print and post near workstations.
2
Routing Rules Matrix (spreadsheet): Complete mapping of content type → reviewer sequence → SLA → Ziflow workflow template for every client account. This is the source of truth for the automation logic.
3
New Client Onboarding Checklist: Step-by-step for the Agency Admin to provision a new client using the Client Board Provisioning workflow.
4
MSP Support Runbook: How to contact the MSP, what constitutes an emergency vs. a normal request, expected response times, and escalation contacts.
5
Platform Admin Credentials (stored in agency password manager): Break-glass admin accounts for monday.com, Ziflow, Slack app, and n8n (read-only access for agency admin).
6
Architecture Diagram: Visual diagram showing how monday.com, Ziflow, n8n, Zapier, and Slack connect, including data flow arrows and webhook URLs.

Success Criteria to Review Together at Handoff

Maintenance

Ongoing Maintenance Plan

...

Monthly Maintenance Tasks (MSP Responsibility)

1
n8n Server Health Check (30 min/month): SSH into VPS, verify Docker containers running, check disk usage (alert at 75%), review n8n execution logs for errors, verify SSL certificate auto-renewal status.
2
Workflow Execution Audit (30 min/month): Review n8n execution history for failed workflows. Investigate any execution with error status. Check Zapier task history for failures. Document recurring errors and implement fixes.
3
Platform Update Review (30 min/month): Check for n8n Docker image updates, review monday.com and Ziflow release notes for breaking API changes or new features, apply non-breaking updates.
4
Zapier Task Usage Monitoring (15 min/month): Log into Zapier, verify task consumption is within the plan limit (2,000/month). If consistently above 1,500, recommend plan upgrade or migrate Zaps to n8n to reduce costs.
5
User Account Audit (15 min/month): Verify all active users have SSO-linked accounts, deactivate accounts for departed employees, confirm external client reviewers list is current.
n8n Server Health Check & Update Commands
bash
docker compose ps
df -h
docker compose logs --tail=100 n8n | grep -i error
certbot certificates
docker pull docker.n8n.io/n8nio/n8n:latest

Quarterly Maintenance Tasks

1
Workflow Optimization Review (2 hours/quarter): Analyze the weekly analytics reports to identify bottlenecks (e.g., a content type consistently overdue, a reviewer consistently slow). Propose routing rule adjustments to the agency.
2
Security Audit (1 hour/quarter): Rotate n8n admin password and API tokens, review Ziflow external reviewer access list, verify monday.com board permissions, check VPS firewall rules.
3
Backup Verification (30 min/quarter): Verify PostgreSQL backups are completing via DigitalOcean managed DB dashboard. Perform a test restore to a temporary database to confirm data integrity. Export n8n workflow JSON files as backup:
4
Capacity Planning (30 min/quarter): Review VPS resource utilization trends. If CPU or RAM consistently above 70%, recommend upgrading to next tier. Review monday.com automation action usage and Zapier task counts.
Export n8n workflow JSON files as backup
bash
docker exec n8n n8n export:workflow --all --output=/backups/workflows.json

SLA Considerations

  • Response Time: 4-hour response for workflow-breaking issues (routing stopped, webhooks failing); 24-hour response for non-critical issues (notification formatting, report inaccuracies).
  • Uptime Target: 99.5% for the n8n automation engine (translates to ~3.6 hours/month allowed downtime). This is achievable with a single VPS but does not provide HA. If client requires higher uptime, recommend the n8n Cloud alternative.
  • Planned Maintenance Window: Sunday 2-6 AM agency timezone for updates and patches, communicated 48 hours in advance.

Escalation Path

1
Tier 1 — Agency Admin: Can restart stuck workflows via n8n UI (read-only access provided), manually update monday.com statuses, re-send Slack notifications.
2
Tier 2 — MSP Service Desk: Workflow configuration changes, API token rotation, Zapier Zap modifications, new client provisioning assistance.
3
Tier 3 — MSP Senior Engineer: n8n server issues, Docker/PostgreSQL troubleshooting, SSO configuration changes, security incident response.
4
Tier 4 — Vendor Support: Ziflow support (support@ziflow.com), monday.com partner support channel, n8n community forum or enterprise support.

Update and Change Management

  • All workflow changes are tested in a cloned n8n workflow before modifying production. The test workflow uses test monday.com boards and test Slack channels.
  • n8n Docker image updates are applied monthly, tested in staging first. Pin to specific version tags in production (e.g., n8nio/n8n:1.50.2) rather than latest after initial deployment stabilizes.
  • monday.com and Ziflow platform updates happen automatically (SaaS); monitor vendor changelogs for breaking changes to APIs or webhooks.
  • Document all changes in the MSP's ticketing system with before/after configuration screenshots.

Alternatives

All-in-One with monday.com + Make.com (No Ziflow)

Replace Ziflow with monday.com's native file proofing and markup features, and replace n8n + Zapier with Make.com as the single automation platform. monday.com has built-in file annotations and approval status columns, while Make.com provides visual workflow automation with strong monday.com integration at a lower price point than Zapier.

Asana + Filestage + Power Automate (Microsoft-Native Stack)

For agencies already invested in Microsoft 365, use Asana (which has native approval task types and a rules engine) as the PM backbone, Filestage for creative proofing (GDPR-compliant, flat-rate pricing), and Microsoft Power Automate for orchestration. Power Automate is included in many M365 plans or available at $15/user/month.

Teamwork.com + Ziflow + Zapier (Agency-Specialized PM)

Replace monday.com with Teamwork.com, which is specifically designed for client-facing agency work with built-in time tracking, budgeting, and resource planning. Keep Ziflow for proofing and Zapier for automation. This simplifies the stack by using an agency-purpose-built PM tool.

Enterprise: Workfront + Frame.io + Custom Integration

For large agencies (50+ staff) or agencies that are part of media conglomerates, use Adobe Workfront (enterprise work management with native Adobe CC integration), Frame.io (video-first proofing now owned by Adobe), and custom API integrations built on the agency's existing infrastructure. This is the premium stack for organizations already in the Adobe ecosystem.

Lightweight: Planable + Slack Workflows (Social-Only Agencies)

For agencies that exclusively produce social media content, use Planable ($33-49/workspace/month) which combines content planning, visual preview in platform-native formats, and built-in approval workflows in a single tool. Supplement with native Slack workflows for internal notifications. No additional automation platform needed.

Want early access to the full toolkit?