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 →
{
"updatedAt": "2026-05-27T19:35:46.469Z",
"createdAt": "2026-05-27T00:34:27.502Z",
"id": "l4FhC5LIhNxLpeHJ",
"name": "ST-02 Contract Manager",
"description": null,
"active": true,
"isArchived": false,
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "minutes",
"minutesInterval": 5
}
]
}
},
"id": "85f5a6b1",
"name": "Every 5 min",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.1,
"position": [
100,
300
]
},
{
"parameters": {
"method": "GET",
"url": "https://api.spacetraders.io/v2/my/contracts",
"options": {},
"authentication": "predefinedCredentialType",
"nodeCredentialType": "httpHeaderAuth",
"alwaysOutputData": true
},
"id": "d8dee384",
"name": "List Contracts",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
300,
300
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "\nconst raw = $input.first().json.data || [];\nconst all = Array.isArray(raw) ? raw : [];\nconst unaccepted = all.filter(c => !c.accepted);\nconst fulfilled = all.filter(c => c.accepted && !c.fulfilled &&\n c.terms?.deliver?.every(d => d.unitsFulfilled >= d.unitsRequired));\nconst active = all.filter(c => c.accepted && !c.fulfilled);\nreturn [{json: {unaccepted, fulfilled, active,\n summary: `Unaccepted: ${unaccepted.length}, Ready: ${fulfilled.length}, Active: ${active.length}`}}];\n"
},
"id": "3fc36162",
"name": "Categorize",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
500,
300
]
},
{
"parameters": {
"jsCode": "\nreturn ($json.unaccepted || []).map(c => ({json: {contractId: c.id}}));\n"
},
"id": "1dc88bb5",
"name": "Extract Unaccepted",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
700,
180
]
},
{
"parameters": {
"method": "POST",
"url": "=https://api.spacetraders.io/v2/my/contracts/{{$json.contractId}}/accept",
"options": {},
"continueOnFail": true,
"authentication": "predefinedCredentialType",
"nodeCredentialType": "httpHeaderAuth"
},
"id": "20152387",
"name": "Accept Contract",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
950,
180
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "\nreturn ($json.fulfilled || []).map(c => ({json: {contractId: c.id}}));\n"
},
"id": "120f5dbc",
"name": "Extract Fulfilled",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
700,
380
]
},
{
"parameters": {
"method": "POST",
"url": "=https://api.spacetraders.io/v2/my/contracts/{{$json.contractId}}/fulfill",
"options": {},
"continueOnFail": true,
"authentication": "predefinedCredentialType",
"nodeCredentialType": "httpHeaderAuth"
},
"id": "73a13ced",
"name": "Fulfill Contract",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
950,
380
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"method": "POST",
"url": "http://localhost:5678/webhook/spaceship-notify",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\"title\":\"Contract Manager\",\"message\":{{ JSON.stringify($json.summary) }},\"severity\":\"info\"}",
"options": {}
},
"id": "f1e81683",
"name": "Notify Summary",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
700,
500
]
},
{
"name": "Changed?",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"parameters": {
"jsCode": "\nconst staticData = $getWorkflowStaticData('global');\nconst d = $input.first().json;\n\nconst key = `${d.unaccepted.length}|${d.active.length}|${d.fulfilled.length}`;\nif (staticData.lastContractKey === key) return []; // no change, stop\n\nstaticData.lastContractKey = key;\nreturn [$input.first()]; // changed \u2014 pass through\n"
},
"position": [
720,
300
],
"id": "43060a21-859b-463b-8caf-55df937b3b2d"
},
{
"name": "Negotiate Check",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
500,
520
],
"parameters": {
"jsCode": "const d = $input.first().json;\n// Only negotiate when there is nothing to accept or actively work on\nif (d.unaccepted.length === 0 && d.active.length === 0) {\n return [{json: {negotiate: true}}];\n}\nreturn [];\n"
},
"id": "f4c13da2-b31d-4e39-99cb-84b4b3e064a6"
},
{
"name": "Negotiate Contract",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
720,
640
],
"parameters": {
"method": "POST",
"url": "https://api.spacetraders.io/v2/my/ships/HERMES-FLEET2-2/negotiate/contract",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "httpHeaderAuth",
"options": {},
"alwaysOutputData": true
},
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"id": "0cf1dd61-766b-42f8-b39f-461ef96b1121"
},
{
"name": "Accept Negotiated",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
950,
640
],
"parameters": {
"method": "POST",
"url": "=https://api.spacetraders.io/v2/my/contracts/{{ $input.first().json.data.contract.id }}/accept",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "httpHeaderAuth",
"options": {},
"alwaysOutputData": true
},
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"id": "064bc347-373e-4d3f-858e-0daec49151e6"
},
{
"name": "Notify Negotiated",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1180,
640
],
"parameters": {
"method": "POST",
"url": "http://localhost:5678/webhook/spaceship-notify",
"sendBody": true,
"contentType": "json",
"body": "={\"title\":\"New Contract Accepted\",\"message\":\"Negotiated + accepted new contract via HERMES-FLEET2-2. Trade: {{ $input.first().json.data.contract.terms.deliver[0].tradeSymbol }} x{{ $input.first().json.data.contract.terms.deliver[0].unitsRequired }}\",\"severity\":\"info\"}",
"options": {}
},
"id": "992af97c-318d-4424-bd84-b28a36426a8c"
}
],
"connections": {
"Every 5 min": {
"main": [
[
{
"node": "List Contracts",
"type": "main",
"index": 0
}
]
]
},
"List Contracts": {
"main": [
[
{
"node": "Categorize",
"type": "main",
"index": 0
}
]
]
},
"Categorize": {
"main": [
[
{
"node": "Changed?",
"type": "main",
"index": 0
},
{
"node": "Negotiate Check",
"type": "main",
"index": 0
}
]
]
},
"Extract Unaccepted": {
"main": [
[
{
"node": "Accept Contract",
"type": "main",
"index": 0
}
]
]
},
"Extract Fulfilled": {
"main": [
[
{
"node": "Fulfill Contract",
"type": "main",
"index": 0
}
]
]
},
"Changed?": {
"main": [
[
{
"node": "Extract Unaccepted",
"type": "main",
"index": 0
},
{
"node": "Extract Fulfilled",
"type": "main",
"index": 0
},
{
"node": "Notify Summary",
"type": "main",
"index": 0
}
]
]
},
"Negotiate Check": {
"main": [
[
{
"node": "Negotiate Contract",
"type": "main",
"index": 0
}
]
]
},
"Negotiate Contract": {
"main": [
[
{
"node": "Accept Negotiated",
"type": "main",
"index": 0
}
]
]
},
"Accept Negotiated": {
"main": [
[
{
"node": "Notify Negotiated",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1",
"errorWorkflow": "UBBtoeMsOM2deZTM"
},
"staticData": {
"node:Every 5 min": {
"recurrenceRules": []
}
},
"meta": null,
"versionId": "488ecede-55e2-484b-8cf4-fc683ad01d24",
"activeVersionId": "488ecede-55e2-484b-8cf4-fc683ad01d24",
"versionCounter": 48,
"triggerCount": 1,
"shared": [
{
"updatedAt": "2026-05-27T00:34:27.504Z",
"createdAt": "2026-05-27T00:34:27.504Z",
"role": "workflow:owner",
"workflowId": "l4FhC5LIhNxLpeHJ",
"projectId": "pQ9yqqsBtuSGk44p",
"project": {
"updatedAt": "2026-01-15T01:26:38.562Z",
"createdAt": "2026-01-15T01:25:22.740Z",
"id": "pQ9yqqsBtuSGk44p",
"name": "Martin Castaneda <martinjosecastaneda1@gmail.com>",
"type": "personal",
"icon": null,
"description": null,
"creatorId": "57a0ed57-85ea-48e0-a5d9-21b1a9cc107c"
}
}
],
"tags": [],
"activeVersion": {
"updatedAt": "2026-05-27T19:35:46.470Z",
"createdAt": "2026-05-27T19:35:46.470Z",
"versionId": "488ecede-55e2-484b-8cf4-fc683ad01d24",
"workflowId": "l4FhC5LIhNxLpeHJ",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "minutes",
"minutesInterval": 5
}
]
}
},
"id": "85f5a6b1",
"name": "Every 5 min",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.1,
"position": [
100,
300
]
},
{
"parameters": {
"method": "GET",
"url": "https://api.spacetraders.io/v2/my/contracts",
"options": {},
"authentication": "predefinedCredentialType",
"nodeCredentialType": "httpHeaderAuth",
"alwaysOutputData": true
},
"id": "d8dee384",
"name": "List Contracts",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
300,
300
],
"credentials": {
"httpHeaderAuth": {
"id": "56bs6PUHWdbliMlu",
"name": "SpaceTraders Auth"
}
}
},
{
"parameters": {
"jsCode": "\nconst raw = $input.first().json.data || [];\nconst all = Array.isArray(raw) ? raw : [];\nconst unaccepted = all.filter(c => !c.accepted);\nconst fulfilled = all.filter(c => c.accepted && !c.fulfilled &&\n c.terms?.deliver?.every(d => d.unitsFulfilled >= d.unitsRequired));\nconst active = all.filter(c => c.accepted && !c.fulfilled);\nreturn [{json: {unaccepted, fulfilled, active,\n summary: `Unaccepted: ${unaccepted.length}, Ready: ${fulfilled.length}, Active: ${active.length}`}}];\n"
},
"id": "3fc36162",
"name": "Categorize",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
500,
300
]
},
{
"parameters": {
"jsCode": "\nreturn ($json.unaccepted || []).map(c => ({json: {contractId: c.id}}));\n"
},
"id": "1dc88bb5",
"name": "Extract Unaccepted",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
700,
180
]
},
{
"parameters": {
"method": "POST",
"url": "=https://api.spacetraders.io/v2/my/contracts/{{$json.contractId}}/accept",
"options": {},
"continueOnFail": true,
"authentication": "predefinedCredentialType",
"nodeCredentialType": "httpHeaderAuth"
},
"id": "20152387",
"name": "Accept Contract",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
950,
180
],
"credentials": {
"httpHeaderAuth": {
"id": "56bs6PUHWdbliMlu",
"name": "SpaceTraders Auth"
}
}
},
{
"parameters": {
"jsCode": "\nreturn ($json.fulfilled || []).map(c => ({json: {contractId: c.id}}));\n"
},
"id": "120f5dbc",
"name": "Extract Fulfilled",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
700,
380
]
},
{
"parameters": {
"method": "POST",
"url": "=https://api.spacetraders.io/v2/my/contracts/{{$json.contractId}}/fulfill",
"options": {},
"continueOnFail": true,
"authentication": "predefinedCredentialType",
"nodeCredentialType": "httpHeaderAuth"
},
"id": "73a13ced",
"name": "Fulfill Contract",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
950,
380
],
"credentials": {
"httpHeaderAuth": {
"id": "56bs6PUHWdbliMlu",
"name": "SpaceTraders Auth"
}
}
},
{
"parameters": {
"method": "POST",
"url": "http://localhost:5678/webhook/spaceship-notify",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\"title\":\"Contract Manager\",\"message\":{{ JSON.stringify($json.summary) }},\"severity\":\"info\"}",
"options": {}
},
"id": "f1e81683",
"name": "Notify Summary",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
700,
500
]
},
{
"name": "Changed?",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"parameters": {
"jsCode": "\nconst staticData = $getWorkflowStaticData('global');\nconst d = $input.first().json;\n\nconst key = `${d.unaccepted.length}|${d.active.length}|${d.fulfilled.length}`;\nif (staticData.lastContractKey === key) return []; // no change, stop\n\nstaticData.lastContractKey = key;\nreturn [$input.first()]; // changed \u2014 pass through\n"
},
"position": [
720,
300
],
"id": "43060a21-859b-463b-8caf-55df937b3b2d"
},
{
"name": "Negotiate Check",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
500,
520
],
"parameters": {
"jsCode": "const d = $input.first().json;\n// Only negotiate when there is nothing to accept or actively work on\nif (d.unaccepted.length === 0 && d.active.length === 0) {\n return [{json: {negotiate: true}}];\n}\nreturn [];\n"
},
"id": "f4c13da2-b31d-4e39-99cb-84b4b3e064a6"
},
{
"name": "Negotiate Contract",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
720,
640
],
"parameters": {
"method": "POST",
"url": "https://api.spacetraders.io/v2/my/ships/HERMES-FLEET2-2/negotiate/contract",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "httpHeaderAuth",
"options": {},
"alwaysOutputData": true
},
"credentials": {
"httpHeaderAuth": {
"id": "56bs6PUHWdbliMlu",
"name": "SpaceTraders Auth"
}
},
"id": "0cf1dd61-766b-42f8-b39f-461ef96b1121"
},
{
"name": "Accept Negotiated",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
950,
640
],
"parameters": {
"method": "POST",
"url": "=https://api.spacetraders.io/v2/my/contracts/{{ $input.first().json.data.contract.id }}/accept",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "httpHeaderAuth",
"options": {},
"alwaysOutputData": true
},
"credentials": {
"httpHeaderAuth": {
"id": "56bs6PUHWdbliMlu",
"name": "SpaceTraders Auth"
}
},
"id": "064bc347-373e-4d3f-858e-0daec49151e6"
},
{
"name": "Notify Negotiated",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1180,
640
],
"parameters": {
"method": "POST",
"url": "http://localhost:5678/webhook/spaceship-notify",
"sendBody": true,
"contentType": "json",
"body": "={\"title\":\"New Contract Accepted\",\"message\":\"Negotiated + accepted new contract via HERMES-FLEET2-2. Trade: {{ $input.first().json.data.contract.terms.deliver[0].tradeSymbol }} x{{ $input.first().json.data.contract.terms.deliver[0].unitsRequired }}\",\"severity\":\"info\"}",
"options": {}
},
"id": "992af97c-318d-4424-bd84-b28a36426a8c"
}
],
"connections": {
"Every 5 min": {
"main": [
[
{
"node": "List Contracts",
"type": "main",
"index": 0
}
]
]
},
"List Contracts": {
"main": [
[
{
"node": "Categorize",
"type": "main",
"index": 0
}
]
]
},
"Categorize": {
"main": [
[
{
"node": "Changed?",
"type": "main",
"index": 0
},
{
"node": "Negotiate Check",
"type": "main",
"index": 0
}
]
]
},
"Extract Unaccepted": {
"main": [
[
{
"node": "Accept Contract",
"type": "main",
"index": 0
}
]
]
},
"Extract Fulfilled": {
"main": [
[
{
"node": "Fulfill Contract",
"type": "main",
"index": 0
}
]
]
},
"Changed?": {
"main": [
[
{
"node": "Extract Unaccepted",
"type": "main",
"index": 0
},
{
"node": "Extract Fulfilled",
"type": "main",
"index": 0
},
{
"node": "Notify Summary",
"type": "main",
"index": 0
}
]
]
},
"Negotiate Check": {
"main": [
[
{
"node": "Negotiate Contract",
"type": "main",
"index": 0
}
]
]
},
"Negotiate Contract": {
"main": [
[
{
"node": "Accept Negotiated",
"type": "main",
"index": 0
}
]
]
},
"Accept Negotiated": {
"main": [
[
{
"node": "Notify Negotiated",
"type": "main",
"index": 0
}
]
]
}
},
"authors": "Martin Castaneda",
"name": null,
"description": null,
"autosaved": false,
"workflowPublishHistory": [
{
"createdAt": "2026-05-27T19:35:46.540Z",
"id": 180,
"workflowId": "l4FhC5LIhNxLpeHJ",
"versionId": "488ecede-55e2-484b-8cf4-fc683ad01d24",
"event": "activated",
"userId": "57a0ed57-85ea-48e0-a5d9-21b1a9cc107c"
}
]
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
httpHeaderAuth
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
ST-02 Contract Manager. Uses httpRequest. Scheduled trigger; 13 nodes.
Source: https://github.com/mcastae813/SpaceShipIO/blob/32d58e71d200f0f3aeb77b4eec7f968fec27ca02/workflows/02-contracts.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.
Birthday Automation - Production (Fixed). Uses stopAndError, httpRequest, emailSend, bannerbear. Scheduled trigger; 86 nodes.
This template runs two scheduled workflows to govern Microsoft Entra ID (Azure AD) guest accounts by detecting stale users via Microsoft Graph, staging deletions in SharePoint with a 72-hour window, n
Jira-Allure-Auto-Qa. Uses httpRequest, jira. Scheduled trigger; 68 nodes.
Spotify-Sync-Surrealdb-V1. Uses httpRequest, n8n-nodes-surrealdb, spotify. Scheduled trigger; 62 nodes.
As n8n instances scale, teams often lose track of sub-workflows—who uses them, where they are referenced, and whether they can be safely updated. This leads to inefficiencies like unnecessary copies o