{
  "id": "O9sxywKIlzPYJR9c",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Collect historical price data from Polymarket Up/Down markets into Supabase",
  "tags": [],
  "nodes": [
    {
      "id": "0d480251-1006-46eb-8526-5dd691b1b6e0",
      "name": "Form to include slug of the market",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        -80,
        1472
      ],
      "parameters": {
        "options": {},
        "formTitle": "Polymarket Slug",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Slug of the Polymarket Market you want to get data",
              "requiredField": true
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "2b3d83c3-3956-4058-80ff-6b6d148b36e7",
      "name": "Find the Event ID from the Slug",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        160,
        1472
      ],
      "parameters": {
        "url": "=https://gamma-api.polymarket.com/markets/slug/{{ $json['Slug of the Polymarket Market you want to get data'] }}",
        "options": {},
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {}
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "8cb89840-af67-448d-885b-b124a60d10aa",
      "name": "Find the Series ID from the slug",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        368,
        1472
      ],
      "parameters": {
        "url": "=https://gamma-api.polymarket.com/events/{{ $json.events[0].id }}",
        "options": {}
      },
      "typeVersion": 4.3
    },
    {
      "id": "a4aa1ae4-b11d-42dd-86ff-b910b35e55c4",
      "name": "Find All the Events for that Series ID",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        608,
        1472
      ],
      "parameters": {
        "url": "=https://gamma-api.polymarket.com/series/{{ $json.series[0].id }}",
        "options": {},
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {}
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "4a8f70a4-a5d6-4cbe-9bb5-70d76ffa3568",
      "name": "Split Events into Itens",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        816,
        1472
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "events"
      },
      "typeVersion": 1
    },
    {
      "id": "d39da386-6233-473f-b482-e2e99d5b3de3",
      "name": "Register Events in Table Polymarket_Btc_1h_Event_List_1",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        1024,
        1472
      ],
      "parameters": {
        "columns": {
          "value": {
            "Closed": "={{ $json.closed }}",
            "EventId": "={{ $json.id }}"
          },
          "schema": [
            {
              "id": "EventId",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "EventId",
              "defaultMatch": false
            },
            {
              "id": "Closed",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Closed",
              "defaultMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "U6fVhXeBCbBG54ka",
          "cachedResultUrl": "/projects/3gQB1X9fdM0qwXU7/datatables/U6fVhXeBCbBG54ka",
          "cachedResultName": "Polymarket_Btc_1h_Event_List_1"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "431fc60a-c04e-41a9-9660-8ff739c7c857",
      "name": "Start Getting Prices Data",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -80,
        1984
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "8ff754f3-336a-4283-bec6-6b8c1bfc2324",
      "name": "Fetch 100 unprocessed events",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        144,
        1984
      ],
      "parameters": {
        "limit": 100,
        "filters": {
          "conditions": [
            {
              "keyName": "Processed",
              "condition": "isEmpty"
            }
          ]
        },
        "operation": "get",
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "U6fVhXeBCbBG54ka",
          "cachedResultUrl": "/projects/3gQB1X9fdM0qwXU7/datatables/U6fVhXeBCbBG54ka",
          "cachedResultName": "Polymarket_Btc_1h_Event_List_1"
        }
      },
      "executeOnce": true,
      "typeVersion": 1
    },
    {
      "id": "310e269a-3a8e-43e8-81e6-9c1704dc5d57",
      "name": "Fetch UP/DOWN tokens and end time",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "position": [
        384,
        1984
      ],
      "parameters": {
        "url": "=https://gamma-api.polymarket.com/events/{{ $json.EventId }}",
        "options": {},
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {}
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "c1b27a89-0910-4b34-95c1-a13301ee90bb",
      "name": "Store UP/DOWN tokens and end time",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        592,
        1984
      ],
      "parameters": {
        "columns": {
          "value": {
            "EndTime": "={{ $json.markets[0].endDate }}",
            "TokenDw": "={{ JSON.parse($json.markets[0].clobTokenIds)[1] }}",
            "TokenUp": "={{ JSON.parse($json.markets[0].clobTokenIds)[0] }}",
            "MarketId": "={{ $json.markets[0].id }}"
          },
          "schema": [
            {
              "id": "EventId",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "EventId",
              "defaultMatch": false
            },
            {
              "id": "Closed",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Closed",
              "defaultMatch": false
            },
            {
              "id": "Processed",
              "type": "boolean",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Processed",
              "defaultMatch": false
            },
            {
              "id": "MarketId",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "MarketId",
              "defaultMatch": false
            },
            {
              "id": "EndTime",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "EndTime",
              "defaultMatch": false
            },
            {
              "id": "TokenUp",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "TokenUp",
              "defaultMatch": false
            },
            {
              "id": "TokenDw",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "TokenDw",
              "defaultMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "filters": {
          "conditions": [
            {
              "keyName": "EventId",
              "keyValue": "={{ $json.id }}"
            }
          ]
        },
        "options": {},
        "operation": "update",
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "U6fVhXeBCbBG54ka",
          "cachedResultUrl": "/projects/3gQB1X9fdM0qwXU7/datatables/U6fVhXeBCbBG54ka",
          "cachedResultName": "Polymarket_Btc_1h_Event_List_1"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "b5aa83a5-3b98-4d10-81fc-41df78730af5",
      "name": "Check if market has closed",
      "type": "n8n-nodes-base.if",
      "position": [
        784,
        1984
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "67b64283-43c3-43be-8ac6-4991dca99279",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json.Closed }}",
              "rightValue": "true"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "3346e316-6909-4297-944a-e61ca0310024",
      "name": "Mark open markets as processed",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        960,
        1808
      ],
      "parameters": {
        "columns": {
          "value": {
            "Processed": true
          },
          "schema": [
            {
              "id": "EventId",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "EventId",
              "defaultMatch": false
            },
            {
              "id": "Closed",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Closed",
              "defaultMatch": false
            },
            {
              "id": "Processed",
              "type": "boolean",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Processed",
              "defaultMatch": false
            },
            {
              "id": "MarketId",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "MarketId",
              "defaultMatch": false
            },
            {
              "id": "EndTime",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "EndTime",
              "defaultMatch": false
            },
            {
              "id": "TokenUp",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "TokenUp",
              "defaultMatch": false
            },
            {
              "id": "TokenDw",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "TokenDw",
              "defaultMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "filters": {
          "conditions": [
            {
              "keyName": "EventId",
              "keyValue": "={{ $json.EventId }}"
            }
          ]
        },
        "options": {},
        "operation": "update",
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "U6fVhXeBCbBG54ka",
          "cachedResultUrl": "/projects/3gQB1X9fdM0qwXU7/datatables/U6fVhXeBCbBG54ka",
          "cachedResultName": "Polymarket_Btc_1h_Event_List_1"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ccf9a57d-1359-41af-a709-996e64c1335b",
      "name": "Convert end time to Unix timestamp",
      "type": "n8n-nodes-base.dateTime",
      "position": [
        1072,
        2000
      ],
      "parameters": {
        "date": "={{ $json.EndTime }}",
        "format": "X",
        "options": {},
        "operation": "formatDate",
        "outputFieldName": "EndTimeUnix"
      },
      "typeVersion": 2
    },
    {
      "id": "1e18314a-0655-48e8-a953-eefe37f6781e",
      "name": "Convert end time to numeric and set start time",
      "type": "n8n-nodes-base.set",
      "position": [
        1280,
        2000
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "c0ee29b4-bf95-4dd2-9332-9522d6709806",
              "name": "EndTimeUnix",
              "type": "number",
              "value": "={{ $json.EndTimeUnix }}"
            },
            {
              "id": "d015f1ed-78dc-43cd-bc66-674b6844820a",
              "name": "StartTimeUnix",
              "type": "number",
              "value": "={{ $json.EndTimeUnix-3600 }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "42762ec5-8f83-4ef5-9a13-930bc84be4b2",
      "name": "Fetch price history",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "position": [
        1520,
        2000
      ],
      "parameters": {
        "url": "=https://clob.polymarket.com/prices-history",
        "options": {},
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "market",
              "value": "={{ $('Store UP/DOWN tokens and end time').item.json.TokenUp }}"
            },
            {
              "name": "startTs",
              "value": "={{ $json.StartTimeUnix }}"
            },
            {
              "name": "endTs",
              "value": "={{ $json.EndTimeUnix }}"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "40ffe602-3655-4129-8e82-0b62f9b5771a",
      "name": "Split prices and timestamps into arrays",
      "type": "n8n-nodes-base.set",
      "position": [
        1728,
        2000
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "05fc89bb-b328-44b9-9799-61ba8610bb84",
              "name": "t",
              "type": "array",
              "value": "={{  $json.history.map(i => i.t) }}"
            },
            {
              "id": "bd1d0f83-e234-49b5-958f-3834a1c10893",
              "name": "p",
              "type": "array",
              "value": "={{ $json.history.map(i => i.p) }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "5717d052-a3c8-4a7d-922a-9f807e8e9f90",
      "name": "Store in Supabase",
      "type": "n8n-nodes-base.supabase",
      "position": [
        1936,
        2000
      ],
      "parameters": {
        "tableId": "HYST_BTC_UP_DW_1H",
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "price",
              "fieldValue": "={{ $json.p }}"
            },
            {
              "fieldId": "time_of_price",
              "fieldValue": "={{ $json.p }}"
            },
            {
              "fieldId": "EventId",
              "fieldValue": "={{ $('Check if market has closed').item.json.EventId }}"
            }
          ]
        }
      },
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "18f6b48e-6c49-4335-8be7-72e47176aa24",
      "name": "Mark as processed",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        2144,
        2000
      ],
      "parameters": {
        "columns": {
          "value": {
            "Processado": true
          },
          "schema": [
            {
              "id": "Event_Id",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Event_Id",
              "defaultMatch": false
            },
            {
              "id": "Closed",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Closed",
              "defaultMatch": false
            },
            {
              "id": "Processado",
              "type": "boolean",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Processado",
              "defaultMatch": false
            },
            {
              "id": "Market_Id",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Market_Id",
              "defaultMatch": false
            },
            {
              "id": "End_Time",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "End_Time",
              "defaultMatch": false
            },
            {
              "id": "Token_Up",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": false,
              "required": false,
              "displayName": "Token_Up",
              "defaultMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "filters": {
          "conditions": [
            {
              "keyName": "Market_Id",
              "keyValue": "={{ $json.MarketId }}"
            }
          ]
        },
        "options": {},
        "operation": "update",
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "tbL43nTR6dOWKVey",
          "cachedResultUrl": "/projects/3gQB1X9fdM0qwXU7/datatables/tbL43nTR6dOWKVey",
          "cachedResultName": "Polymarket_Btc_1h_Event_List"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "fd90ddc5-5024-487d-a90b-61c2ce776abe",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -208,
        1776
      ],
      "parameters": {
        "color": 7,
        "width": 2544,
        "height": 448,
        "content": "## Extracts price data and stores it in Supabase in batches of 100."
      },
      "typeVersion": 1
    },
    {
      "id": "88b1b2ba-0c41-409a-9889-4620025d8ba8",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -208,
        1376
      ],
      "parameters": {
        "color": 7,
        "width": 1504,
        "height": 320,
        "content": "## Fetches and stores all event IDs in a series based on a user-provided event slug."
      },
      "typeVersion": 1
    },
    {
      "id": "960ff291-7985-41c6-8c39-abe14d9088e0",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -816,
        1056
      ],
      "parameters": {
        "width": 512,
        "height": 1232,
        "content": "## Tutorial\n**This n8n template retrieves historical prices from Polymarket serial markets such as Bitcoin Up or Down, S&P 500 Up or Down, and similar markets.**\n\nThe main use cases are data collection for easier analysis through SQL queries or more advanced pipelines using Python and other programming languages.\n\n**How it works**\n\n- Provide the slug of the serial market you want to analyze in the initial form. The workflow is designed for live Polymarket \u201cUp or Down\u201d markets; copy the slug from the current market and submit it.\n\n- From the slug, the workflow extracts the event ID and derives the corresponding series ID. All events in that series are retrieved, organized, and stored in an internal n8n table. This process runs only once per series to avoid duplicate data.\n\n- A second workflow reads the stored events, retrieves the Up and Down token IDs, records market closing times, and filters out open markets so only historical data is processed.\n\n- Market end times are converted to Unix timestamps, and start times are calculated. The workflow is structured for 1-hour markets, but the time-conversion node can be adjusted for other durations.\n\n- Historical price data is then fetched and stored in a Supabase table for later analysis.\n\n**How to use**\n\n- Copy the slug of the desired Up or Down market from Polymarket and submit it through the form.\n\n- After the first workflow finishes, run the second workflow to collect historical price data.\n\n- Events are processed in batches of 100 to avoid performance issues. If execution stops, simply rerun the workflow and it will continue from where it left off.\n\n**Requirements**\n\n- No Polymarket credentials are required, since all data is public.\n\n- Supabase credentials are required.\n\n- An internal n8n table must exist to store event metadata (event ID, market status, processing flag, end time, and token IDs).\n\n- The Supabase table for historical prices can be created by executing the following query in your supabase account:\n\nCREATE TABLE HYST_BTC_UP_DW_1H (\n    EventId TEXT NOT NULL,\n    price NUMERIC[] NOT NULL,\n    time_of_price TIMESTAMPTZ[] NOT NULL\n);\n\n**Need help with implementation or customization?**\n\nIf you require assistance setting up this workflow, adapting it to your infrastructure, or extending it for advanced analytics, feel free to reach out by email at caio@caravelsai.com\n."
      },
      "typeVersion": 1
    },
    {
      "id": "582b8319-904e-48c1-b350-267cba30357e",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -208,
        1056
      ],
      "parameters": {
        "width": 876,
        "height": 280,
        "content": "## Slug Example\n![](https://imgur.com/StX3juA.pngfull-width)"
      },
      "typeVersion": 1
    },
    {
      "id": "bab3e34d-59ac-4109-a1b2-a66aebf19599",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1248,
        1712
      ],
      "parameters": {
        "color": 3,
        "height": 512,
        "content": "## Adjust the StartTimeUnix to match the selected market\nIn this example, StartTimeUnix is set to 1 hour before EndTimeUnix, since the sample market used has a one-hour duration. If the market is longer or shorter, adjust this value to the appropriate time window."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "14d907e6-ec15-4ace-9671-437fec270e3f",
  "connections": {
    "Mark as processed": {
      "main": [
        [
          {
            "node": "Fetch 100 unprocessed events",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Store in Supabase": {
      "main": [
        [
          {
            "node": "Mark as processed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch price history": {
      "main": [
        [
          {
            "node": "Split prices and timestamps into arrays",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Events into Itens": {
      "main": [
        [
          {
            "node": "Register Events in Table Polymarket_Btc_1h_Event_List_1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Start Getting Prices Data": {
      "main": [
        [
          {
            "node": "Fetch 100 unprocessed events",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check if market has closed": {
      "main": [
        [
          {
            "node": "Mark open markets as processed",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Convert end time to Unix timestamp",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch 100 unprocessed events": {
      "main": [
        [
          {
            "node": "Fetch UP/DOWN tokens and end time",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Find the Event ID from the Slug": {
      "main": [
        [
          {
            "node": "Find the Series ID from the slug",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Find the Series ID from the slug": {
      "main": [
        [
          {
            "node": "Find All the Events for that Series ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch UP/DOWN tokens and end time": {
      "main": [
        [
          {
            "node": "Store UP/DOWN tokens and end time",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Store UP/DOWN tokens and end time": {
      "main": [
        [
          {
            "node": "Check if market has closed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert end time to Unix timestamp": {
      "main": [
        [
          {
            "node": "Convert end time to numeric and set start time",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Form to include slug of the market": {
      "main": [
        [
          {
            "node": "Find the Event ID from the Slug",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Find All the Events for that Series ID": {
      "main": [
        [
          {
            "node": "Split Events into Itens",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split prices and timestamps into arrays": {
      "main": [
        [
          {
            "node": "Store in Supabase",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert end time to numeric and set start time": {
      "main": [
        [
          {
            "node": "Fetch price history",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Register Events in Table Polymarket_Btc_1h_Event_List_1": {
      "main": [
        []
      ]
    }
  }
}