Integrations
Rank Pilot AI SEO follows a bring-your-own-key (BYOK) model for most third-party data providers: rather than the platform metering usage against a single shared account, each user supplies their own API credentials for the services they want connected, and those credentials are stored per-user and used only on that user's behalf. Billing, transactional email/SMS and OAuth-based Google connections are the exceptions — those run through platform-level credentials because they either involve payment processing or a standard OAuth consent flow rather than a static API key.
How BYOK keys are stored and used
User-supplied keys live in the user_api_keys table: one row per (user_id, service) pair, holding an encrypted_key column plus an optional label. Keys are never written to this table in plaintext from the client — the encryption/decryption boundary sits in Postgres/edge functions, not in browser code, so a compromised client session cannot exfiltrate raw key material from the table directly.
Reads happen through two narrow, purpose-built RPCs rather than ad-hoc SELECTs against the table:
get_user_api_key(_service)— callable by the signed-in owner, returns their own decrypted key for a single service. Used by edge functions that act on behalf of the current request's user (e.g. the Ahrefs functions, called with the user's bearer token).admin_list_user_api_keys(_services)— a service-role-only RPC used by scheduled/cron edge functions (Google Ads reporting, scheduled rank checks) that need to iterate over every user who has configured a given service, without ever exposing the raw table to anything other than the service role.
Row Level Security on user_api_keys restricts direct table access to auth.uid() = user_id for the owner's own rows, so even without the RPC layer a user could never read another user's key. Users manage their keys from account/integration settings screens, which add, replace or remove a row per service; removing a key immediately stops that integration from being used for that account.
Google Search Console
Connected via a standard Google OAuth flow (gsc-auth edge function and the gsc-callback route), not a manually entered API key. A successful connection is recorded in gsc_connections, scoped to a specific websites row. Unlocks: verified-property rank/impression/click data (gsc-overview), scheduled nightly syncing of Search Console keyword performance into keyword_rankings/rank_history (gscNightlySync.server.ts, gscKeywords.functions.ts), and ownership verification used elsewhere in the product (gscVerification.functions.ts) to confirm a user actually controls a domain before other automated actions are allowed against it.
Google Analytics 4 (GA4)
Layered on top of the same Google OAuth connection used for Search Console, GA4 access unlocks traffic and conversion context alongside search performance — used in reporting and funnel-style analysis features so that ranking movements can be read against actual site traffic rather than in isolation.
Google Ads
A BYOK integration: users provide a Google Ads customer ID and developer token, stored as two separate user_api_keys rows (google_ads_customer_id, google_ads_developer_token) alongside the OAuth refresh token already held from the Search Console connection. The shared helper in supabase/functions/_shared/google-ads.ts loads these via admin_list_user_api_keys for scheduled reporting jobs. Unlocks: paid-search spend, conversions and ROAS metrics (google-ads-metrics) surfaced next to organic performance, and ad-copy generation features that use live account context.
Ahrefs
A BYOK integration: users paste their own Ahrefs API key, stored under the ahrefs service. Edge functions (ahrefs-keywords, ahrefs-backlinks, ahrefs-metrics) read the key with get_user_api_key("ahrefs") scoped to the calling user's session, then call the Ahrefs API directly. Unlocks: keyword-difficulty and volume data, backlink discovery/monitoring, and domain/URL metrics used throughout the rank-tracking and backlink-building features. Without a configured key, those specific data points are unavailable to that user but the rest of the platform continues to function.
Apify / SERP data
Used for supplementary scraping-backed data such as SERP feature detection and third-party review/citation scans (fetch-serp-rankings, serp-check, openwebninja-scan). Depending on the specific data source, this runs either against a shared scraping backend or a user-supplied key, following the same user_api_keys storage pattern where a per-user key is required.
Stripe
Platform-level, not BYOK — Stripe is how Rank Pilot AI SEO itself charges for subscriptions, so the platform's own Stripe secret key is held as a server-side/edge-function secret, never a per-user credential. Edge functions handle checkout session creation for subscriptions, the AEO pass, the lifetime-deal offer and managed services (create-subscription-checkout, create-aeo-pass-checkout, create-ltd-checkout, create-managed-checkout), customer portal sessions (create-portal-session), and inbound webhook processing (stripe-payment-webhook) that reconciles subscription state into subscriptions/user_subscriptions. Unlocks: plan enforcement, invoice/billing history (surfaced through billing.functions.ts/billing.server.ts), and discount code redemption.
Twilio
Platform-level. Used for SMS delivery — one-time passcodes and transactional SMS notifications — via shared helpers in supabase/functions/_shared/sms.ts and sms-templates.ts. Credentials are held as edge function secrets rather than per-user keys, since SMS sending is done on the platform's behalf, not the end user's.
Mailchimp
Platform-level. Used for marketing and lifecycle email: syncing subscriber plan/tag state (mailchimpPlanSync.server.ts, mailchimpPlanTags.server.ts), blog campaign distribution (mailchimpBlogCampaign.server.ts), and general list management (mailchimp.server.ts, _shared/mailchimp.ts). Sync progress is tracked in mailchimp_sync_state. The platform's own Mailchimp API key/audience configuration is stored as a secret, not something individual users configure.
CMS connectors (WordPress, Shopify, and others)
Part of the Autopilot system, which pushes automated on-page/SEO fixes directly into a customer's site. Each connector is BYOK in spirit — the user authorises or supplies credentials for their own site/store — recorded in autopilot_connections per website, and consumed by dedicated edge functions:
autopilot-wordpress/aeo-wordpress-push— pushes content and AEO (answer-engine optimisation) changes to a connected WordPress site, typically via the WordPress REST API using an application password or similar site-specific credential.autopilot-shopify— applies storefront-level SEO changes to a connected Shopify store via the Shopify Admin API, using a per-store access token.autopilot-cms— a more generic connector path for CMS platforms that don't have a dedicated function, andautopilot-browser-actioncovers cases requiring a scripted browser action rather than a direct API call.
Whatever fixes are queued or applied through these connectors are tracked in autopilot_queue and autopilot_activity/autopilot_fix_history, giving each website an auditable history of automated changes independent of the credential used to make them.
Summary of the trust boundary
BYOK services (Ahrefs, Google Ads, CMS connectors, and similar) put the user in control of both the credential and its usage limits — the platform never bills against or is liable for that provider's usage. Platform-level services (Stripe, Twilio, Mailchimp, and the Google OAuth issuer itself) are operated centrally because they're part of how Rank Pilot AI SEO runs its own business (billing, notifications, marketing, authentication) rather than data the user is fetching about their own site.