{
  "name": "Dynamic Airtable Extraction",
  "nodes": [
    {
      "id": "b8c9d0e1-8888-4000-8000-000000000001",
      "name": "Webhook (New Document)",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [-680, 300],
      "parameters": { "path": "extract-doc" },
      "webhookId": "wh-extract-001"
    },
    {
      "id": "b8c9d0e1-8888-4000-8000-000000000002",
      "name": "Set Input",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [-480, 300],
      "parameters": { "values": { "string": [
        { "name": "documentText", "value": "={{$json.body.text || $json.body.content}}" },
        { "name": "extractionType", "value": "={{$json.body.type || 'invoice'}}" }
      ]} }
    },
    {
      "id": "b8c9d0e1-8888-4000-8000-000000000003",
      "name": "Airtable (Read Schema)",
      "type": "n8n-nodes-base.airtable",
      "typeVersion": 2,
      "position": [-280, 300],
      "parameters": { "operation": "list", "resource": "records", "table": "Extraction Schemas" },
      "credentials": { "airtableApi": { "id": null, "name": "Airtable API" } }
    },
    {
      "id": "b8c9d0e1-8888-4000-8000-000000000004",
      "name": "Build Dynamic Prompt",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [-80, 300],
      "parameters": {
        "jsCode": "const input = $input.first().json;\nconst fields = input.fields || input;\nconst fieldNames = fields.FieldNames || 'total,date';\nconst docText = $node['Set Input'].json.documentText;\nreturn [{ json: { extractionPrompt: 'Extract: ' + fieldNames + ' from:\\n' + docText.substring(0, 8000) } }];"
      }
    },
    {
      "id": "b8c9d0e1-8888-4000-8000-000000000005",
      "name": "OpenAI Extraction",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "typeVersion": 1,
      "position": [120, 300],
      "parameters": {
        "options": { "model": "gpt-4o-mini", "temperature": 0.1, "maxTokens": 2000 },
        "messages": { "values": [{ "role": "user", "message": "={{$json.extractionPrompt}}" }] }
      },
      "credentials": { "openAiApi": { "id": null, "name": "OpenAI API" } }
    },
    {
      "id": "b8c9d0e1-8888-4000-8000-000000000006",
      "name": "Parse Extracted",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [320, 300],
      "parameters": {
        "jsCode": "const raw = $input.first().json;\nconst text = raw.output || raw.text || '{}';\nlet extracted;\ntry { extracted = JSON.parse(text); } catch (e) { extracted = { error: 'parse failed' }; }\nreturn [{ json: extracted }];"
      }
    },
    {
      "id": "b8c9d0e1-8888-4000-8000-000000000007",
      "name": "Airtable (Write Results)",
      "type": "n8n-nodes-base.airtable",
      "typeVersion": 2,
      "position": [520, 300],
      "parameters": { "operation": "create", "resource": "records", "table": "Extracted Data" },
      "credentials": { "airtableApi": { "id": null, "name": "Airtable API" } }
    },
    {
      "id": "b8c9d0e1-8888-4000-8000-000000000008",
      "name": "Webhook Response",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 2,
      "position": [720, 300],
      "parameters": { "respondWith": "json", "responseBody": "={{ { success: true } }}" }
    }
  ],
  "connections": {
    "Webhook (New Document)": { "main": [[{ "node": "Set Input", "type": "main", "index": 0 }]] },
    "Set Input": { "main": [[{ "node": "Airtable (Read Schema)", "type": "main", "index": 0 }]] },
    "Airtable (Read Schema)": { "main": [[{ "node": "Build Dynamic Prompt", "type": "main", "index": 0 }]] },
    "Build Dynamic Prompt": { "main": [[{ "node": "OpenAI Extraction", "type": "main", "index": 0 }]] },
    "OpenAI Extraction": { "main": [[{ "node": "Parse Extracted", "type": "main", "index": 0 }]] },
    "Parse Extracted": { "main": [[{ "node": "Airtable (Write Results)", "type": "main", "index": 0 }]] },
    "Airtable (Write Results)": { "main": [[{ "node": "Webhook Response", "type": "main", "index": 0 }]] }
  },
  "settings": { "executionOrder": "v1" },
  "staticData": null,
  "pinData": {},
  "triggerCount": 1,
  "meta": { "templateCredsSetupCompleted": true }
}
