{
  "slug": "fix-cors-error-tooljet",
  "title": "Fix CORS Errors in ToolJet REST API Calls",
  "metaDescription": "Fix ToolJet CORS errors on browser-side REST calls. RealComposer answers OPTIONS preflight at the edge and adds the headers ToolJet expects in under 10ms.",
  "headline": "ToolJet browser queries without CORS preflight failures",
  "category": "ecosystem",
  "categoryLabel": "Platforms & Frameworks",
  "urgency": 9,
  "clientPlatform": "ToolJet",
  "upstreamServices": [
    "REST API"
  ],
  "searchIntentQuery": "tooljet cors error calling external rest api",
  "directAnswerSummary": "ToolJet CORS errors appear when a RunJS query or browser-side fetch hits an API that does not return Access-Control-Allow-Origin for your ToolJet domain. Route the call through a RealComposer pipeline: it handles the OPTIONS preflight, adds the right headers, and injects any upstream auth from the vault.",
  "problem": {
    "title": "Why ToolJet browser queries hit CORS blocks",
    "explanation": "Many internal and vendor APIs were never configured for cross-origin browser calls. When ToolJet code fetches them directly, the browser rejects the response before your query can read it, even though the same request works in cURL.",
    "risks": [
      "Blocked responses on APIs without Access-Control-Allow-Origin",
      "Teams loosening CORS to * on internal APIs as a workaround",
      "Auth headers copied into RunJS to get around the block"
    ]
  },
  "solutionSteps": [
    {
      "stepNumber": 1,
      "title": "Store credentials in Secret Vault",
      "description": "Save UPSTREAM_API_TOKEN in RealComposer so the value never enters the ToolJet 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": "Point the ToolJet query at the edge URL",
      "description": "Call your workspace edge URL with a restricted rc_live_ client token.",
      "codeSnippet": "// ToolJet RunJS query\nconst res = await fetch('https://realcomposer.com/v1/workspace/fix-cors-error-tooljet', {\n  headers: { Authorization: 'Bearer rc_live_client_token' }\n});\nreturn await res.json();"
    }
  ],
  "pipelineConfig": {
    "name": "Fix CORS Errors in ToolJet REST API Calls",
    "method": "GET",
    "cacheTtlSeconds": 0,
    "authMode": "client_token",
    "steps": [
      {
        "stepKey": "upstream",
        "upstreamUrlTemplate": "https://{{secrets.UPSTREAM_API_HOST}}/v1/orders",
        "httpMethod": "GET",
        "headersTemplate": {
          "Authorization": "Bearer {{secrets.UPSTREAM_API_TOKEN}}"
        },
        "timeoutMs": 5000
      }
    ],
    "outputMapping": {
      "version": 1,
      "fields": [
        {
          "targetPath": "orders",
          "sourceStep": "upstream",
          "sourcePath": "data"
        },
        {
          "targetPath": "total",
          "sourceStep": "upstream",
          "sourcePath": "meta.total"
        }
      ]
    }
  },
  "sampleBloatedInput": {
    "data": [
      {
        "id": "ord_1",
        "status": "shipped",
        "_links": {
          "self": "/v1/1"
        }
      }
    ],
    "meta": {
      "total": 1,
      "page": 1,
      "request_id": "req_88"
    }
  },
  "sampleSlimmedOutput": {
    "orders": [
      {
        "id": "ord_1",
        "status": "shipped",
        "_links": {
          "self": "/v1/1"
        }
      }
    ],
    "total": 1
  },
  "curlSnippet": "curl -X GET \"https://realcomposer.com/v1/workspace/fix-cors-error-tooljet\" \\\n  -H \"Authorization: Bearer rc_live_client_token\"",
  "faqs": [
    {
      "question": "Does ToolJet have its own CORS workaround?",
      "answer": "Queries run through ToolJet data sources are executed by the ToolJet server, so they avoid browser CORS. RunJS fetches do not. RealComposer covers the browser case and also adds caching and slimming."
    },
    {
      "question": "Which origins should I allow?",
      "answer": "Add your ToolJet Cloud or self-hosted app domain to the pipeline allowed origins and leave every other origin blocked."
    }
  ],
  "relatedRecipeSlugs": [
    "fix-retool-cors-error",
    "fix-cors-error-flutterflow",
    "call-stripe-from-tooljet-securely"
  ],
  "links": {
    "page": "https://realcomposer.com/recipes/fix-cors-error-tooljet",
    "markdown": "https://realcomposer.com/recipes/fix-cors-error-tooljet.md",
    "json": "https://realcomposer.com/recipes/fix-cors-error-tooljet.json",
    "install": "https://realcomposer.com/dashboard/pipelines/new?recipe=fix-cors-error-tooljet&via=agent"
  }
}