{
  "slug": "call-airtable-from-wix-velo-securely",
  "title": "Call Airtable API from Wix Velo Securely",
  "metaDescription": "Call Airtable from Wix Velo page code without exposing a token. RealComposer keeps the Airtable PAT in an edge vault and allows only your Wix domains.",
  "headline": "Airtable-backed Wix pages without tokens in page code",
  "category": "security",
  "categoryLabel": "Security & Secret Vault",
  "urgency": 9,
  "clientPlatform": "Wix Velo",
  "upstreamServices": [
    "Airtable"
  ],
  "searchIntentQuery": "call airtable api from wix velo without exposing token",
  "directAnswerSummary": "Wix Velo page code runs in the visitor browser, so an Airtable token used with wix-fetch there is public. Call a RealComposer pipeline from page code with a client token, or from backend code. The edge injects AIRTABLE_PAT, enforces your Wix origins, and returns only the columns your repeater shows.",
  "problem": {
    "title": "Why Airtable tokens leak from Wix page code",
    "explanation": "Wix repeaters are easy to fill with a wix-fetch call in page code, but that code is delivered to every visitor. An exposed personal access token lets anyone read or modify your Airtable base within the scopes you granted.",
    "risks": [
      "Airtable PAT visible in Wix page code and network traffic",
      "Visitors exhausting the five requests per second base limit",
      "Internal Airtable columns such as owners sent to every visitor"
    ]
  },
  "solutionSteps": [
    {
      "stepNumber": 1,
      "title": "Store credentials in Secret Vault",
      "description": "Save AIRTABLE_PAT and AIRTABLE_BASE_ID in RealComposer so the value never enters the Wix Velo project."
    },
    {
      "stepNumber": 2,
      "title": "Configure the edge pipeline",
      "description": "Add the upstream steps with vault header injection, set allowed origins, and map only the fields the screen binds."
    },
    {
      "stepNumber": 3,
      "title": "Fill a Wix repeater from page code",
      "description": "Call your workspace edge URL with a restricted rc_live_ client token.",
      "codeSnippet": "import { fetch } from 'wix-fetch';\n\n$w.onReady(async () => {\n  const res = await fetch('https://realcomposer.com/v1/workspace/call-airtable-from-wix-velo-securely?table=Events', {\n    headers: { Authorization: 'Bearer rc_live_client_token' },\n  });\n  const { items } = await res.json();\n  $w('#eventsRepeater').data = items.map((r) => ({ _id: r.id, ...r.fields }));\n});"
    }
  ],
  "pipelineConfig": {
    "name": "Call Airtable API from Wix Velo Securely",
    "method": "GET",
    "cacheTtlSeconds": 300,
    "authMode": "client_token",
    "steps": [
      {
        "stepKey": "airtable",
        "upstreamUrlTemplate": "https://api.airtable.com/v0/{{secrets.AIRTABLE_BASE_ID}}/{{query.table}}?pageSize=50&fields%5B%5D=Title&fields%5B%5D=Date",
        "httpMethod": "GET",
        "headersTemplate": {
          "Authorization": "Bearer {{secrets.AIRTABLE_PAT}}"
        },
        "timeoutMs": 3000
      }
    ],
    "outputMapping": {
      "version": 1,
      "fields": [
        {
          "targetPath": "items",
          "sourceStep": "airtable",
          "sourcePath": "records"
        }
      ]
    }
  },
  "sampleBloatedInput": {
    "records": [
      {
        "id": "recEv1",
        "createdTime": "2026-09-12T08:00:00.000Z",
        "fields": {
          "Title": "Open House",
          "Date": "2026-12-02",
          "Owner": "usr1"
        }
      }
    ],
    "offset": "itrB2/recEv1"
  },
  "sampleSlimmedOutput": {
    "items": [
      {
        "id": "recEv1",
        "createdTime": "2026-09-12T08:00:00.000Z",
        "fields": {
          "Title": "Open House",
          "Date": "2026-12-02"
        }
      }
    ]
  },
  "curlSnippet": "curl -X GET \"https://realcomposer.com/v1/workspace/call-airtable-from-wix-velo-securely\" \\\n  -H \"Authorization: Bearer rc_live_client_token\"",
  "faqs": [
    {
      "question": "Why not use the Wix Secrets Manager instead?",
      "answer": "The Secrets Manager works from backend web modules. RealComposer adds edge caching, payload slimming, and reuse across other sites and apps with the same pipeline."
    },
    {
      "question": "Why does the page code add an _id field?",
      "answer": "Wix repeaters require each item to have a unique _id, so the snippet copies the Airtable record id into that key before binding."
    }
  ],
  "relatedRecipeSlugs": [
    "call-private-api-from-webflow-securely",
    "cache-airtable-avoid-rate-limits",
    "cache-weather-api-wix-velo"
  ],
  "links": {
    "page": "https://realcomposer.com/recipes/call-airtable-from-wix-velo-securely",
    "markdown": "https://realcomposer.com/recipes/call-airtable-from-wix-velo-securely.md",
    "json": "https://realcomposer.com/recipes/call-airtable-from-wix-velo-securely.json",
    "install": "https://realcomposer.com/dashboard/pipelines/new?recipe=call-airtable-from-wix-velo-securely&via=agent"
  }
}