The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "BIC Container Tracking - Agentic Scraping System (Mock Data)",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "container-track",
"responseMode": "lastNode",
"options": {}
},
"id": "webhook-trigger",
"name": "Webhook Trigger",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1.1,
"position": [
250,
300
]
},
{
"parameters": {
"jsCode": "// Mock Maersk API response\nconst bicNumber = $input.first().json.body?.bic || $input.first().json.bic || 'MAEU1234567';\n\nconst mockData = {\n carrier: \"Maersk Line\",\n containerNumber: bicNumber,\n status: \"In Transit\",\n currentLocation: {\n port: \"Port of Rotterdam\",\n country: \"Netherlands\",\n coordinates: { lat: 51.9244, lon: 4.4777 }\n },\n vessel: {\n name: \"Maersk Sealand\",\n imo: \"9632101\",\n voyage: \"142N\"\n },\n events: [\n {\n timestamp: \"2025-10-10T08:30:00Z\",\n location: \"Shanghai, China\",\n status: \"Loaded on Vessel\",\n description: \"Container loaded onto vessel\"\n },\n {\n timestamp: \"2025-10-11T14:20:00Z\",\n location: \"At Sea\",\n status: \"Departed\",\n description: \"Vessel departed from Shanghai\"\n },\n {\n timestamp: \"2025-10-12T09:15:00Z\",\n location: \"Rotterdam, Netherlands\",\n status: \"Arrived at Port\",\n description: \"Vessel arrived at destination port\"\n }\n ],\n estimatedDelivery: \"2025-10-14T10:00:00Z\",\n responseTime: 245\n};\n\nreturn [{ json: mockData }];"
},
"id": "maersk-agent",
"name": "Maersk Scraping Agent",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
500,
100
]
},
{
"parameters": {
"jsCode": "// Mock MSC API response\nconst bicNumber = $input.first().json.body?.bic || $input.first().json.bic || 'MSCU9876543';\n\nconst mockData = {\n carrier: \"Mediterranean Shipping Company\",\n containerNumber: bicNumber,\n status: \"At Port\",\n currentLocation: {\n port: \"Port of Hamburg\",\n country: \"Germany\",\n coordinates: { lat: 53.5488, lon: 9.9872 }\n },\n vessel: {\n name: \"MSC Gulsun\",\n imo: \"9837753\",\n voyage: \"FM251A\"\n },\n events: [\n {\n timestamp: \"2025-10-08T10:00:00Z\",\n location: \"Singapore\",\n status: \"Gate In\",\n description: \"Container received at terminal\"\n },\n {\n timestamp: \"2025-10-09T16:45:00Z\",\n location: \"Singapore\",\n status: \"Loaded\",\n description: \"Loaded on vessel MSC Gulsun\"\n },\n {\n timestamp: \"2025-10-12T07:30:00Z\",\n location: \"Hamburg, Germany\",\n status: \"Discharged\",\n description: \"Container discharged from vessel\"\n }\n ],\n estimatedDelivery: \"2025-10-13T15:00:00Z\",\n responseTime: 189\n};\n\nreturn [{ json: mockData }];"
},
"id": "msc-agent",
"name": "MSC Scraping Agent",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
500,
200
]
},
{
"parameters": {
"jsCode": "// Mock CMA CGM API response\nconst bicNumber = $input.first().json.body?.bic || $input.first().json.bic || 'CMAU5555555';\n\nconst mockData = {\n carrier: \"CMA CGM\",\n containerNumber: bicNumber,\n status: \"Delivered\",\n currentLocation: {\n port: \"Port of Le Havre\",\n country: \"France\",\n coordinates: { lat: 49.4938, lon: 0.1077 }\n },\n vessel: {\n name: \"CMA CGM Antoine De Saint Exupery\",\n imo: \"9454436\",\n voyage: \"0MFBGW1MA\"\n },\n events: [\n {\n timestamp: \"2025-10-05T11:20:00Z\",\n location: \"Hong Kong\",\n status: \"Empty to Shipper\",\n description: \"Empty container released to shipper\"\n },\n {\n timestamp: \"2025-10-06T09:15:00Z\",\n location: \"Hong Kong\",\n status: \"Full from Shipper\",\n description: \"Full container received from shipper\"\n },\n {\n timestamp: \"2025-10-07T14:30:00Z\",\n location: \"Hong Kong\",\n status: \"Loaded on Vessel\",\n description: \"Container loaded for departure\"\n },\n {\n timestamp: \"2025-10-11T08:45:00Z\",\n location: \"Le Havre, France\",\n status: \"Unloaded\",\n description: \"Container unloaded at destination\"\n },\n {\n timestamp: \"2025-10-12T10:00:00Z\",\n location: \"Le Havre, France\",\n status: \"Delivered\",\n description: \"Container delivered to consignee\"\n }\n ],\n estimatedDelivery: \"2025-10-12T10:00:00Z\",\n responseTime: 312\n};\n\nreturn [{ json: mockData }];"
},
"id": "cma-cgm-agent",
"name": "CMA CGM Scraping Agent",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
500,
300
]
},
{
"parameters": {
"jsCode": "// Mock COSCO API response\nconst bicNumber = $input.first().json.body?.bic || $input.first().json.bic || 'COSU3333333';\n\nconst mockData = {\n carrier: \"COSCO Shipping Lines\",\n containerNumber: bicNumber,\n status: \"In Transit\",\n currentLocation: {\n port: \"At Sea - Indian Ocean\",\n country: \"International Waters\",\n coordinates: { lat: 8.5241, lon: 76.9366 }\n },\n vessel: {\n name: \"COSCO Shipping Universe\",\n imo: \"9795147\",\n voyage: \"025E\"\n },\n events: [\n {\n timestamp: \"2025-10-09T13:00:00Z\",\n location: \"Ningbo, China\",\n status: \"Gate In\",\n description: \"Container gate in at terminal\"\n },\n {\n timestamp: \"2025-10-10T18:20:00Z\",\n location: \"Ningbo, China\",\n status: \"Vessel Departure\",\n description: \"Vessel departed with container\"\n }\n ],\n estimatedDelivery: \"2025-10-20T12:00:00Z\",\n responseTime: 278\n};\n\nreturn [{ json: mockData }];"
},
"id": "cosco-agent",
"name": "COSCO Scraping Agent",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
500,
400
]
},
{
"parameters": {
"jsCode": "// Mock Hapag-Lloyd API response\nconst bicNumber = $input.first().json.body?.bic || $input.first().json.bic || 'HLXU7777777';\n\nconst mockData = {\n carrier: \"Hapag-Lloyd\",\n containerNumber: bicNumber,\n status: \"On Rail\",\n currentLocation: {\n port: \"Chicago Rail Terminal\",\n country: \"United States\",\n coordinates: { lat: 41.8781, lon: -87.6298 }\n },\n vessel: {\n name: \"Hapag-Lloyd Express\",\n imo: \"9642211\",\n voyage: \"089W\"\n },\n events: [\n {\n timestamp: \"2025-10-01T07:30:00Z\",\n location: \"Busan, South Korea\",\n status: \"Loaded\",\n description: \"Container loaded on vessel\"\n },\n {\n timestamp: \"2025-10-08T15:00:00Z\",\n location: \"Los Angeles, USA\",\n status: \"Discharged\",\n description: \"Container discharged from vessel\"\n },\n {\n timestamp: \"2025-10-09T09:30:00Z\",\n location: \"Los Angeles, USA\",\n status: \"Rail Departure\",\n description: \"Container departed by rail\"\n },\n {\n timestamp: \"2025-10-12T11:45:00Z\",\n location: \"Chicago, USA\",\n status: \"Rail Arrival\",\n description: \"Container arrived at rail terminal\"\n }\n ],\n estimatedDelivery: \"2025-10-13T09:00:00Z\",\n responseTime: 156\n};\n\nreturn [{ json: mockData }];"
},
"id": "hapag-lloyd-agent",
"name": "Hapag-Lloyd Scraping Agent",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
500,
500
]
},
{
"parameters": {
"jsCode": "// Mock ONE Line API response\nconst bicNumber = $input.first().json.body?.bic || $input.first().json.bic || 'ONEU4444444';\n\nconst mockData = {\n carrier: \"Ocean Network Express\",\n containerNumber: bicNumber,\n status: \"At Terminal\",\n currentLocation: {\n port: \"Port of Yokohama\",\n country: \"Japan\",\n coordinates: { lat: 35.4437, lon: 139.6380 }\n },\n vessel: {\n name: \"ONE Innovation\",\n imo: \"9843596\",\n voyage: \"0P3JS1MA\"\n },\n events: [\n {\n timestamp: \"2025-10-10T10:20:00Z\",\n location: \"Tokyo, Japan\",\n status: \"Empty Pick Up\",\n description: \"Empty container picked up\"\n },\n {\n timestamp: \"2025-10-11T14:15:00Z\",\n location: \"Tokyo, Japan\",\n status: \"Full Return\",\n description: \"Full container returned to depot\"\n },\n {\n timestamp: \"2025-10-12T08:00:00Z\",\n location: \"Yokohama, Japan\",\n status: \"Gate In\",\n description: \"Container at terminal awaiting vessel\"\n }\n ],\n estimatedDelivery: \"2025-10-16T14:00:00Z\",\n responseTime: 201\n};\n\nreturn [{ json: mockData }];"
},
"id": "one-line-agent",
"name": "ONE Line Scraping Agent",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
500,
600
]
},
{
"parameters": {
"jsCode": "// Mock Evergreen API response\nconst bicNumber = $input.first().json.body?.bic || $input.first().json.bic || 'EGHU8888888';\n\nconst mockData = {\n carrier: \"Evergreen Line\",\n containerNumber: bicNumber,\n status: \"Customs Hold\",\n currentLocation: {\n port: \"Port of Long Beach\",\n country: \"United States\",\n coordinates: { lat: 33.7701, lon: -118.1937 }\n },\n vessel: {\n name: \"Ever Given\",\n imo: \"9811000\",\n voyage: \"0FHQJW1MA\"\n },\n events: [\n {\n timestamp: \"2025-10-03T12:00:00Z\",\n location: \"Kaohsiung, Taiwan\",\n status: \"Loaded\",\n description: \"Container loaded on vessel\"\n },\n {\n timestamp: \"2025-10-10T19:30:00Z\",\n location: \"Long Beach, USA\",\n status: \"Vessel Arrival\",\n description: \"Vessel arrived at port\"\n },\n {\n timestamp: \"2025-10-11T08:15:00Z\",\n location: \"Long Beach, USA\",\n status: \"Discharged\",\n description: \"Container discharged from vessel\"\n },\n {\n timestamp: \"2025-10-11T16:45:00Z\",\n location: \"Long Beach, USA\",\n status: \"Customs Hold\",\n description: \"Container held for customs inspection\"\n }\n ],\n estimatedDelivery: \"2025-10-15T10:00:00Z\",\n responseTime: 423\n};\n\nreturn [{ json: mockData }];"
},
"id": "evergreen-agent",
"name": "Evergreen Scraping Agent",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
500,
700
]
},
{
"parameters": {
"jsCode": "// Mock Yang Ming API response\nconst bicNumber = $input.first().json.body?.bic || $input.first().json.bic || 'YMLU6666666';\n\nconst mockData = {\n carrier: \"Yang Ming Marine Transport\",\n containerNumber: bicNumber,\n status: \"Empty Return\",\n currentLocation: {\n port: \"Port of Antwerp\",\n country: \"Belgium\",\n coordinates: { lat: 51.2663, lon: 4.4014 }\n },\n vessel: {\n name: \"YM Wealth\",\n imo: \"9299812\",\n voyage: \"0107\"\n },\n events: [\n {\n timestamp: \"2025-09-28T09:00:00Z\",\n location: \"Keelung, Taiwan\",\n status: \"Loaded\",\n description: \"Container loaded for shipment\"\n },\n {\n timestamp: \"2025-10-07T13:20:00Z\",\n location: \"Antwerp, Belgium\",\n status: \"Discharged\",\n description: \"Container unloaded at destination\"\n },\n {\n timestamp: \"2025-10-08T10:30:00Z\",\n location: \"Antwerp, Belgium\",\n status: \"Delivered\",\n description: \"Container delivered to consignee\"\n },\n {\n timestamp: \"2025-10-12T14:00:00Z\",\n location: \"Antwerp, Belgium\",\n status: \"Empty Return\",\n description: \"Empty container returned to depot\"\n }\n ],\n estimatedDelivery: \"2025-10-08T10:30:00Z\",\n responseTime: 167\n};\n\nreturn [{ json: mockData }];"
},
"id": "yangming-agent",
"name": "Yang Ming Scraping Agent",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
500,
800
]
},
{
"parameters": {
"jsCode": "// Mock HMM API response\nconst bicNumber = $input.first().json.body?.bic || $input.first().json.bic || 'HMMU2222222';\n\nconst mockData = {\n carrier: \"Hyundai Merchant Marine\",\n containerNumber: bicNumber,\n status: \"Transshipment\",\n currentLocation: {\n port: \"Port of Colombo\",\n country: \"Sri Lanka\",\n coordinates: { lat: 6.9271, lon: 79.8612 }\n },\n vessel: {\n name: \"HMM Algeciras\",\n imo: \"9863629\",\n voyage: \"134N\"\n },\n events: [\n {\n timestamp: \"2025-10-08T11:30:00Z\",\n location: \"Chennai, India\",\n status: \"Loaded\",\n description: \"Container loaded on feeder vessel\"\n },\n {\n timestamp: \"2025-10-11T06:00:00Z\",\n location: \"Colombo, Sri Lanka\",\n status: \"Transshipment\",\n description: \"Container at transshipment hub\"\n },\n {\n timestamp: \"2025-10-12T15:30:00Z\",\n location: \"Colombo, Sri Lanka\",\n status: \"Loaded on Main Vessel\",\n description: \"Container loaded on main line vessel\"\n }\n ],\n estimatedDelivery: \"2025-10-22T08:00:00Z\",\n responseTime: 234\n};\n\nreturn [{ json: mockData }];"
},
"id": "hmm-agent",
"name": "HMM Scraping Agent",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
500,
900
]
},
{
"parameters": {
"jsCode": "// Mock ZIM API response\nconst bicNumber = $input.first().json.body?.bic || $input.first().json.bic || 'ZIMU9999999';\n\nconst mockData = {\n carrier: \"ZIM Integrated Shipping\",\n containerNumber: bicNumber,\n status: \"Pending Pickup\",\n currentLocation: {\n port: \"Port of Haifa\",\n country: \"Israel\",\n coordinates: { lat: 32.8191, lon: 34.9983 }\n },\n vessel: {\n name: \"ZIM Sammy Ofer\",\n imo: \"9708389\",\n voyage: \"056A\"\n },\n events: [\n {\n timestamp: \"2025-10-02T08:45:00Z\",\n location: \"Piraeus, Greece\",\n status: \"Gate In\",\n description: \"Container received at terminal\"\n },\n {\n timestamp: \"2025-10-03T15:20:00Z\",\n location: \"Piraeus, Greece\",\n status: \"Loaded\",\n description: \"Container loaded for transport\"\n },\n {\n timestamp: \"2025-10-06T11:00:00Z\",\n location: \"Haifa, Israel\",\n status: \"Vessel Arrival\",\n description: \"Vessel arrived at port\"\n },\n {\n timestamp: \"2025-10-06T18:30:00Z\",\n location: \"Haifa, Israel\",\n status: \"Discharged\",\n description: \"Container discharged from vessel\"\n },\n {\n timestamp: \"2025-10-07T09:15:00Z\",\n location: \"Haifa, Israel\",\n status: \"Available for Pickup\",\n description: \"Container available for collection\"\n }\n ],\n estimatedDelivery: \"2025-10-14T12:00:00Z\",\n responseTime: 198\n};\n\nreturn [{ json: mockData }];"
},
"id": "zim-agent",
"name": "ZIM Scraping Agent",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
500,
1000
]
},
{
"parameters": {
"mode": "combine",
"combinationMode": "mergeByPosition",
"options": {}
},
"id": "merge-results",
"name": "Merge All Results",
"type": "n8n-nodes-base.merge",
"typeVersion": 2.1,
"position": [
750,
550
]
},
{
"parameters": {
"jsCode": "const items = $input.all();\nconst bicNumber = items[0]?.json?.body?.bic || items[0]?.json?.bic || 'DEMO1234567';\nconst results = [];\n\nconst agentNames = [\n 'Maersk Line',\n 'Mediterranean Shipping Company',\n 'CMA CGM',\n 'COSCO Shipping Lines',\n 'Hapag-Lloyd',\n 'Ocean Network Express',\n 'Evergreen Line',\n 'Yang Ming Marine Transport',\n 'Hyundai Merchant Marine',\n 'ZIM Integrated Shipping'\n];\n\n// Process each agent response\nfor (let i = 0; i < items.length; i++) {\n const item = items[i];\n const agentName = item.json.carrier || agentNames[i] || 'Unknown Agent';\n \n if (item.json.containerNumber) {\n results.push({\n agent: agentName,\n status: 'success',\n containerStatus: item.json.status,\n currentLocation: item.json.currentLocation?.port || 'Unknown',\n vessel: item.json.vessel?.name || 'N/A',\n lastEvent: item.json.events?.[item.json.events.length - 1] || null,\n estimatedDelivery: item.json.estimatedDelivery,\n responseTime: item.json.responseTime + 'ms',\n totalEvents: item.json.events?.length || 0,\n fullData: item.json,\n timestamp: new Date().toISOString()\n });\n } else {\n results.push({\n agent: agentName,\n status: 'no_data',\n error: 'Container not found in this carrier system',\n timestamp: new Date().toISOString()\n });\n }\n}\n\n// Count successful scrapes\nconst successCount = results.filter(r => r.status === 'success').length;\nconst noDataCount = results.filter(r => r.status === 'no_data').length;\n\n// Calculate average response time\nconst avgResponseTime = results\n .filter(r => r.responseTime)\n .reduce((sum, r) => sum + parseInt(r.responseTime), 0) / successCount;\n\nreturn [\n {\n json: {\n summary: {\n bicNumber: bicNumber,\n totalAgents: 10,\n successfulScrapes: successCount,\n noDataFound: noDataCount,\n averageResponseTime: Math.round(avgResponseTime) + 'ms',\n processedAt: new Date().toISOString()\n },\n agentResults: results,\n recommendations: {\n primaryCarrier: results.find(r => r.status === 'success')?.agent || 'Unknown',\n dataQuality: successCount >= 7 ? 'Excellent' : successCount >= 4 ? 'Good' : 'Limited',\n actionRequired: results.some(r => r.containerStatus === 'Customs Hold') ? 'Customs clearance needed' : 'None'\n }\n }\n }\n];"
},
"id": "aggregate-format",
"name": "Aggregate & Format Results",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
950,
550
]
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ JSON.stringify($json, null, 2) }}",
"options": {
"responseCode": 200,
"responseHeaders": {
"entries": [
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "X-Processing-Time",
"value": "={{ $json.summary.averageResponseTime }}"
}
]
}
}
},
"id": "respond-webhook",
"name": "Respond to Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [
1150,
550
]
}
],
"connections": {
"Webhook Trigger": {
"main": [
[
{
"node": "Maersk Scraping Agent",
"type": "main",
"index": 0
},
{
"node": "MSC Scraping Agent",
"type": "main",
"index": 0
},
{
"node": "CMA CGM Scraping Agent",
"type": "main",
"index": 0
},
{
"node": "COSCO Scraping Agent",
"type": "main",
"index": 0
},
{
"node": "Hapag-Lloyd Scraping Agent",
"type": "main",
"index": 0
},
{
"node": "ONE Line Scraping Agent",
"type": "main",
"index": 0
},
{
"node": "Evergreen Scraping Agent",
"type": "main",
"index": 0
},
{
"node": "Yang Ming Scraping Agent",
"type": "main",
"index": 0
},
{
"node": "HMM Scraping Agent",
"type": "main",
"index": 0
},
{
"node": "ZIM Scraping Agent",
"type": "main",
"index": 0
}
]
]
},
"Maersk Scraping Agent": {
"main": [
[
{
"node": "Merge All Results",
"type": "main",
"index": 0
}
]
]
},
"MSC Scraping Agent": {
"main": [
[
{
"node": "Merge All Results",
"type": "main",
"index": 1
}
]
]
},
"CMA CGM Scraping Agent": {
"main": [
[
{
"node": "Merge All Results",
"type": "main",
"index": 0
}
]
]
},
"COSCO Scraping Agent": {
"main": [
[
{
"node": "Merge All Results",
"type": "main",
"index": 0
}
]
]
},
"Hapag-Lloyd Scraping Agent": {
"main": [
[
{
"node": "Merge All Results",
"type": "main",
"index": 0
}
]
]
},
"ONE Line Scraping Agent": {
"main": [
[
{
"node": "Merge All Results",
"type": "main",
"index": 0
}
]
]
},
"Evergreen Scraping Agent": {
"main": [
[
{
"node": "Merge All Results",
"type": "main",
"index": 0
}
]
]
},
"Yang Ming Scraping Agent": {
"main": [
[
{
"node": "Merge All Results",
"type": "main",
"index": 0
}
]
]
},
"HMM Scraping Agent": {
"main": [
[
{
"node": "Merge All Results",
"type": "main",
"index": 0
}
]
]
},
"ZIM Scraping Agent": {
"main": [
[
{
"node": "Merge All Results",
"type": "main",
"index": 0
}
]
]
},
"Merge All Results": {
"main": [
[
{
"node": "Aggregate & Format Results",
"type": "main",
"index": 0
}
]
]
},
"Aggregate & Format Results": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
},
"staticData": null,
"tags": [],
"triggerCount": 1,
"updatedAt": "2025-10-12T10:00:00.000Z",
"versionId": "1"
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
BIC Container Tracking - Agentic Scraping System (Mock Data). Webhook trigger; 14 nodes.
Source: https://github.com/Rigos0/justshipit-container-tracking/blob/8885ceeb9414ca23a7f9e6821e2c2293e7b280b6/n8n/gen_workflow.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Jigsaw API key for image processing, I use this as a gatekeeper/second pair of eyes. LINK to their website https://jigsawstack.com/ SECOND A postgress DATABASE (I use Supabase) LlamaCloud for the pars
Onsite Photos to Jobs (SMS Agent). Uses dataTable, twilio, httpRequest, airtable. Webhook trigger; 62 nodes.
W1 - IN WhatsApp Adapter (Secure + Fast ACK). Uses postgres, redis, httpRequest. Webhook trigger; 50 nodes.
W1 - IN WhatsApp Adapter (Secure + Fast ACK). Uses postgres, redis, httpRequest. Webhook trigger; 48 nodes.