Integrations setup
Configure search, analytics, publishing, email, and abuse-prevention integrations.
Every integration is site-owned: credentials live only in your installation's environment and Vault. Nothing is registered with any QueryLayer-operated service.
#Where integration secrets live
Integration secrets are environment variables consumed by the installation's edge functions. Two places matter:
- The installation
.env(<install-dir>/.env). The setup wizard and installer create it; you add integration values under the existing keys. - The database Vault — OAuth refresh tokens are stored there automatically by the connectors. You never handle them.
After changing .env, apply it:
cd <install-dir>
docker compose up -d functions auth # recreate what consumes the values
Find the publishable key and service key in
<install-dir>/secrets/install-secrets.json when a step below needs one.
#Google Search Console
What it gives you: exact property identifiers, resumable daily backfills (up to 16 months), per-dimension search facts, URL inspection intelligence, and the query-ownership diagnostics behind Search intelligence and the topical map.
Create the OAuth client in Google Cloud Console:
Enable the Search Console API.
Create an OAuth consent screen (external or internal, your choice).
Create credentials → OAuth client ID → Web application.
Add the authorized redirect URI — use your own installation:
https://your-site.example/api/functions/v1/gsc-connector?action=callback
Set the env values in the installation
.env:GOOGLE_SEARCH_CONSOLE_CLIENT_ID=<from Google> GOOGLE_SEARCH_CONSOLE_CLIENT_SECRET=<from Google> GSC_OAUTH_REDIRECT_URI=https://your-site.example/api/functions/v1/gsc-connector?action=callbackRecreate functions (
docker compose up -d functions), then in the admin workspace open Integrations → Google Search Console → Connect. Google redirects back to your installation; the refresh token goes straight into Vault. Select the property, then let the initial backfill run — it is resumable and idempotent.
Requested scope: webmasters.readonly plus basic OpenID email identity.
Only properties returned by Google's own sites.list response are offered.
#Google Analytics 4
Enable the Google Analytics API in the same Google Cloud project and add the authorized redirect URI:
https://your-site.example/api/functions/v1/ga4-connector?action=callback.env:GOOGLE_ANALYTICS_CLIENT_ID=<from Google> GOOGLE_ANALYTICS_CLIENT_SECRET=<from Google> GA4_OAUTH_REDIRECT_URI=https://your-site.example/api/functions/v1/ga4-connector?action=callback(If unset, the connector falls back to the GSC client pair.)
Recreate functions, then Integrations → GA4 → Connect. Scope is
analytics.readonlywith offline access. Landing-page ingestion feeds the Analytics tab in Search intelligence.
#Bing Webmaster Tools and IndexNow
Register an OAuth application at Bing Webmaster Tools and register the redirect URI:
https://your-site.example/api/functions/v1/search-delivery?action=bing-callback.env:BING_WEBMASTER_CLIENT_ID=<from Bing> BING_WEBMASTER_CLIENT_SECRET=<from Bing> BING_OAUTH_REDIRECT_URI=https://your-site.example/api/functions/v1/search-delivery?action=bing-callbackRecreate functions, then Integrations → Bing Webmaster Tools → Connect. Bing daily totals and weekly page/query details flow into the same reporting contracts.
IndexNow is configured per site from the Integrations view: QueryLayer generates a host key, stores it in Vault, and gives you the verification file location to publish at your site root. Deliveries are durable and idempotent; attempts are recorded as immutable receipts.
#Form notifications (Resend)
What it gives you: email notification for accepted inbox submissions, with a durable delivery ledger and bounded retries.
Verify your sending domain in Resend (SPF/DKIM).
.env:RESEND_API_KEY=<sending-only key>Recreate functions. Connect the sending identity in the admin workspace (Integrations), then test by submitting the contact form on your site and watching Inbox → Delivery activity.
Visitor content in notifications is redacted automatically when its retained submission expires.
#Turnstile (contact-form spam defense)
Create a Turnstile widget for your site domain.
The site key goes into your public site build (
PUBLIC_TURNSTILE_SITE_KEY); the secret and expected hostname go into the installation.env:TURNSTILE_SECRET=<widget secret> TURNSTILE_EXPECTED_HOSTNAME=your-site.exampleRecreate functions. Server-side verification is fail-closed: if the secret is set, a failed or missing challenge rejects the submission (recorded without keeping the payload).
#Static-site delivery (Vercel)
QueryLayer's publishing always completes internally. Delivery — the static rebuild of your public site — is pluggable. Today's provider is a Vercel Deploy Hook:
In Vercel, create a Deploy Hook for your site project.
.env(the hook URL is a secret; a server-side value only):BGG_DEPLOY_HOOK_URL=https://api.vercel.com/v1/integrations/deploy/<hook-id> VERCEL_DEPLOYMENT_WEBHOOK_SECRET=<secret for inbound webhooks>Recreate functions. In the admin workspace, Integrations → Vercel connection: save the project handoff metadata (project, production branch, repository, preview URL). Activation happens server-side once the credential is installed.
Register the inbound webhook so deployment outcomes reconcile: point Vercel's deployment events at
https://your-site.example/api/functions/v1/vercel-deployment-webhook. Every event is HMAC-verified and stored as an immutable receipt before QueryLayer declares delivery complete.
Without any provider, publishes still complete; Publishing shows delivery as pending with the reason. A local rebuild provider (publish → build the Astro site on the same host → the gateway serves it) is on the roadmap for fully self-contained installs.
#Checking your work
docker compose logs functionsin the installation directory shows edge function activity.- The Integrations view shows per-connection status pills.
- OAuth callbacks must land on your installation's own domain — every redirect URI above is installation-local by design.