Generated banner for Setting Up A Data Warehouse Source
Generated logo for Setting Up A Data Warehouse Source

Setting Up A Data Warehouse Source

PostHogOfficialPublished by PostHog

  • Skill
  • Workflow
  • Data and AI
  • MIT
  • No issues found

From the author

Guide the user through connecting a new data warehouse source, including databases, SaaS tools, and bucket files. Use when the user wants to "connect Stripe", "import data from Postgres", "import files from a bucket", "upload a file", "add a new data source", or pick sync methods for each table. This skill covers source-type discovery, credential validation, table discovery, per-table sync_type selection, and the final create call. Also covers picking a good prefix, what to do right after creation, and sending a source's tables to the user's own warehouse (Snowflake, BigQuery, Postgres, S3 and other destinations).
— the description by PostHog

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides a structured workflow for integrating external databases, SaaS platforms, and cloud storage buckets into the PostHog data warehouse. It covers the entire lifecycle from source discovery and secure credential handling to table selection, sync-type configuration, and final creation. The skill emphasizes best practices for choosing sync methods—such as full refresh, incremental, or CDC—to optimize performance and cost, while also handling advanced requirements like webhook registration and destination mapping.

What it does

  • Guides users through source-type discovery and credential validation.
  • Facilitates secure credential collection using browser-based OAuth or connection links.
  • Automates table discovery and applies sensible default sync configurations.
  • Supports advanced manual configuration for specific tables and sync types.
  • Handles webhook registration for real-time data ingestion from supported sources.
  • Assists in routing data to external destinations like Snowflake, BigQuery, or S3.

When to use it

  • When connecting a new data source like Stripe, Postgres, or cloud storage buckets.
  • When you need to import data but are unsure which sync method is appropriate.
  • When you have credentials but need help structuring the source configuration.
  • When you need to set up near-real-time replication via CDC or webhooks.

Advantages

  • Prevents common setup failures through pre-flight credential validation.
  • Ensures security by avoiding the collection of raw secrets in chat.
  • Simplifies complex configurations with a recommended one-step setup flow.
  • Provides clear guidance on selecting cost-effective sync strategies per table.

Usage examples

“Connect my Postgres database to the data warehouse.”
The agent will guide you through validating your database credentials, discovering available tables, and configuring the sync settings for each.
“I need to import files from an S3 bucket.”
The agent will help you select the correct S3 source type and configure the full refresh sync needed for bucket files.
“How do I sync my Stripe data in real-time?”
The agent will configure the Stripe source, set the sync type to webhook, and register the necessary webhook endpoints.

Install

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/posthog/setting-up-a-data-warehouse-source/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip setting-up-a-data-warehouse-source.zip -d .agents/skills

Documentation by PostHog

Setting up a data warehouse source

Use this skill when the user wants to connect an external data source to PostHog's data warehouse for the first time.

Use AmazonS3 for Amazon S3, GoogleCloudStorage for Google Cloud Storage, AzureBlob for Azure Blob, and CloudflareR2 for Cloudflare R2. For a local file, direct the user to upload it in the PostHog app. That flow creates a FileUpload source. No MCP tool uploads files.

Bucket sources use full_refresh by default.

Default to the one-step flow: data-warehouse-source-setup validates credentials, discovers every table, enables them with sensible sync defaults (incremental where possible), and creates the source in a single call — no schemas array to assemble. For credentials, hand the user a secure browser link with data-warehouse-source-connect-link instead of collecting secrets in chat. Only drop to the manual wizard → db-schema → create flow when the user wants to hand-pick which tables sync or set non-default sync types per table.

When to use this skill

  • The user wants to connect a new source: "connect Stripe", "import my Postgres orders table", "sync Hubspot contacts"

  • The user wants to import bucket files or upload a local file

  • The user isn't sure what source types PostHog supports

  • The user has credentials but doesn't know how to structure the schemas payload

  • The user wants guidance on which sync method to pick per table

Available tools

ToolPurpose
data-warehouse-source-connect-linkPreferred for credentials — get a secure browser/OAuth link so the user authenticates without pasting secrets in chat
data-warehouse-source-setupPreferred to create — one call: validate creds, discover tables, apply sync defaults, create the source
external-data-sources-wizardDiscover which source types exist and what fields each needs (advanced flow)
external-data-sources-db-schemaValidate credentials and list tables with available sync methods per table (advanced flow)
external-data-sources-createAdvanced create — requires a schemas array built from the db-schema response
external-data-sources-check-cdc-prerequisites-createPostgres CDC pre-flight check (optional, only for Postgres CDC)
external-data-sources-webhook-info-retrieveCheck if a source supports webhooks and whether one has been registered
external-data-sources-create-webhook-createRegister a webhook with the external service after source creation
external-data-sources-update-webhook-inputs-createSupply the signing secret manually when auto-registration failed
external-data-sources-listAfter creation, confirm the source is listed and see its initial status
external-data-schemas-listSee per-table sync status once the source is created
external-data-destinations-listSee existing destinations, including the PostHog warehouse
external-data-destinations-connect-linkSecure browser link where the user enters a destination's credentials; returns nothing secret
external-data-destinations-connect-link-statusPoll with the link's connect_token to get the integration the user saved
external-data-destinations-createCreate a destination from the integration the connect page saved
external-data-destinations-add-sourcesAttach existing sources to a destination
external-data-sources-destinations-updateSet a source's full destination list, for example to keep the PostHog warehouse before attaching
external-data-destinations-test-connectionDiagnose a destination that is failing or paused (does not resume it)

Pre-flight: credential gotchas that cause most failures

Surface these before collecting credentials — they're the top reasons setup fails on the first try. Validating against them up front avoids burning credential prompts on retries.

  • The host must be reachable from PostHog's network. localhost, 127.0.0.1, and private/RFC-1918 hosts (10.x, 192.168.x, 172.16–31.x) are rejected — PostHog runs the connection from its own infrastructure, not the user's machine. Serverless/managed Postgres (Neon, Supabase, RDS behind strict rules) often also needs PostHog's egress IPs allowlisted first. If the DB isn't publicly reachable, route to the browser deep-link (data-warehouse-source-connect-link) or an SSH tunnel rather than collecting credentials that can't validate.

  • Supabase is Postgres — don't collect it twice. Use the Session pooler connection, not the direct host (the direct host is IPv6-only). The pooler host looks like aws-0-<region>.pooler.supabase.com, the username must be postgres.<project-ref>, and the port is 6543 (not 5432). The password is the database password (Settings → Database), which is distinct from the anon/service_role JWT keys and from the Supabase account password. If SUPABASE_URL is in the project env, derive the project ref from db.<ref>.supabase.co to pre-fill these instead of asking the user to guess.

  • Many SaaS sources need a specific key type or plan — get the right one before the create call fails:

    • Stripe — a restricted key (rk_live_…), not the standard secret key (sk_live_…).

    • RevenueCat — a v2 secret key (sk_…) with the read scopes enabled.

    • Sentry — an internal-integration token, not a DSN and not a personal auth token.

    • Convex — requires the Professional plan.

    • Twilio — API Key SID + Secret, not the account auth token.

    • Mailchimp — the key carries its datacenter suffix (key-usX).

    • For send-only services (Resend, Mailgun), the key already in the project env is often restricted; the warehouse import needs a full/read-access key.

  • Never pass an unresolved secret reference. If a credential field is still a {"secretRef": ...} object, PostHog can't resolve it — the create/db-schema/setup calls reject it with a clear error. Resolve it to the real value first, or collect credentials via data-warehouse-source-connect-link and pass the resulting credential_id.

Most setups should use this path — it avoids the most common failures (skipping db-schema, malformed schemas, missing required fields).

  1. Discover the source type and its fields (optional): external-data-sources-wizard lists every source type and the credential fields each needs. Use it to know what to ask the user for; skip it if the source type is obvious.

  2. Collect credentials securely: call data-warehouse-source-connect-link({source_type}). It returns a connect_url to a minimal connect page rendering the source's full connection form — the user authorizes via OAuth or enters credentials there, whichever the source offers (the response's auth_method tells you which to expect). The page validates the details against a live connection and stashes them encrypted in a temporary store — it does NOT create the source. After the user confirms they're done, find the stored credential id via data-warehouse-stored-credentials-list (filter by source_type, newest first; the page also shows the id to the user) and pass {"credential_id": <id>} to setup. Stored credentials are single-use — deleted as soon as setup consumes them — and expire after 24 hours.

    Never ask the user to paste raw database passwords, API keys, or OAuth tokens into the chat.

  3. Create in one call: data-warehouse-source-setup({source_type, payload, prefix}). The server validates credentials, discovers all tables, enables them with sync defaults (incremental where a tracking column exists, else append, else full_refresh — never CDC), sets created_via=mcp, and creates the source. The payload carries a credential reference ({"credential_id": ...} or the OAuth integration id key) — or inline credentials for headless automation; no schemas array is needed. On success you get the new source id; call external-data-schemas-list to show the user what was enabled and how each table will sync.

Notes specific to this path:

  • All discovered tables are enabled. That's intended (incremental defaults keep ongoing cost low), but flag row counts for very large tables and offer the advanced flow if the user wants to sync only a subset.

  • Webhooks are auto-registered for sources that support them (currently Stripe). Check the webhook key in the setup response: on success, webhook-capable tables sync in real time and webhook-only tables (e.g. Stripe Discount) are enabled too; on failure (e.g. the API key can't create webhooks), tables keep the polling defaults and webhook-only tables stay disabled — relay the webhook.error to the user and offer Step 6 to register manually. If webhook.pending_inputs is non-empty, collect those values and submit via external-data-sources-update-webhook-inputs-create. CDC is never chosen automatically; use the advanced flow + CDC steps for near-real-time Postgres.

  • Inline credentials in payload still work for headless/automation, but prefer the connect-link handoff above.

Advanced: hand-pick tables (three-step flow)

Use this when the user wants to choose exactly which tables sync or set non-default sync types. Don't try to shortcut to external-data-sources-create — you need the db-schema response to build a valid schemas payload.

         ┌────────────────────┐
         │ 1. wizard          │  What source types exist? What fields does each need?
         └────────┬───────────┘
                  ▼
         ┌────────────────────┐
         │ 2. db-schema       │  Validate creds. List tables + available sync methods per table.
         └────────┬───────────┘
                  ▼
         ┌────────────────────┐
         │ 3. create          │  Send source_type + credentials + schemas[] to actually create.
         └────────────────────┘

Workflow

Step 1 — Discover the source type

Call external-data-sources-wizard with source_type set to the kind(s) you need (comma-separated, e.g. Postgres,Stripe). The unfiltered response describes every supported source and is hundreds of KB — large enough to blow your context budget. Only omit source_type when you genuinely need to enumerate every available type, and when you do, pass fields: ['*.name', '*.caption'] so the response carries just the names instead of every source's config field definitions. The response is a dict keyed by source type. Each entry describes:

  • name — the canonical source_type string you'll pass to later calls (e.g. "Postgres", "Stripe", "Hubspot").

  • caption — human-readable description.

  • fields — the config fields needed (host, port, database, api_key, client_id/secret, ...). Each has name, type (input, password, switch, select, file-upload), and required.

  • featured, unreleasedSource — use to gauge readiness. Skip sources marked unreleasedSource: true unless the user explicitly asked for a preview.

Match the user's request to a source. If they said "Postgres", look up Postgres. If they said something ambiguous like "database", present the top relevant matches (Postgres, MySQL, MongoDB, BigQuery, Snowflake, Redshift) and let them pick.

For bucket files, use the canonical source_type: AmazonS3, GoogleCloudStorage, AzureBlob, or CloudflareR2. For a local file, use the app's upload flow. It creates a FileUpload source after the user uploads the file.

For OAuth-based sources (Hubspot, Salesforce, Google Ads), the wizard entry hints at an OAuth flow. These typically need the user to authorize in the PostHog UI rather than pasting credentials — explain this and direct them to the source setup page rather than trying to collect tokens in chat. OAuth is about authentication, not about how data flows; OAuth sources still use polling bulk sync, not webhooks.

Gather the required credentials from the user. Never ask for more fields than the wizard entry says are required — asking for an unnecessary port when the source doesn't need one confuses users.

Step 2 — Validate credentials and discover tables

Call external-data-sources-db-schema with source_type plus all credential fields. This does two things at once:

  1. Validates the credentials against the live source. Returns 400 with a message if anything is wrong (bad host, wrong password, permission denied). Show the error verbatim — it's often actionable ("password authentication failed for user 'x'").

  2. If valid, returns an array of table entries. Each entry:

{
  "table": "orders",
  "should_sync": false,
  "rows": 1_250_000,
  "incremental_available": true,   # can do sync_type=incremental
  "append_available": true,        # can do sync_type=append
  "cdc_available": true,           # can do sync_type=cdc  (null = not enabled for team)
  "supports_webhooks": false,      # can do sync_type=webhook for real-time push
  "incremental_fields": [          # candidates: usually updated_at, created_at, id
    {"field": "updated_at", "type": "datetime", "label": "updated_at", ...},
    {"field": "created_at", "type": "datetime", ...},
    {"field": "id", "type": "integer", ...}
  ],
  "detected_primary_keys": ["id"],
  "available_columns": [{"field": "id", "type": "integer", "nullable": false}, ...],
  "description": "..."
}

Present this to the user. Don't dump the raw JSON — summarize: which tables were found, row counts, and the default sync method recommendation per table (see sync-type decision guide).

Step 3 — Confirm per-table sync configuration

For each table the user wants to sync, pick a sync_type. See the sync-type decision guide for detailed rules, but the short version is:

  • Small / dimension tables (<50k rows, no natural ordering column): full_refresh — simple and always correct.

  • Large tables with an updated_at / modified_at: incremental — much cheaper per sync.

  • Append-only immutable tables (logs, events): append if available — preserves history.

  • Postgres with CDC enabled and you need near-real-time: cdc — requires primary keys and Postgres prerequisites.

  • Sources that support webhooks (currently Stripe): for near-real-time ingestion set sync_type: "webhook" on the tables where supports_webhooks: true, then register the webhook as a post-create step (see step 6 below). Tables that don't support webhooks on the same source still need a bulk sync_type.

For each schema that will use incremental/append/cdc, you also need:

  • incremental_field — which column to track for high-water-mark ordering. Pick from the incremental_fields list returned by db-schema. Prefer updated_at over created_at (updated_at catches late-arriving updates; created_at misses them). For integer-only tables, use the monotonically increasing primary key.

  • incremental_field_type — must match the chosen field's type (datetime, timestamp, date, integer, numeric, objectid).

  • primary_key_columns — required for CDC. Use detected_primary_keys from db-schema.

Step 4 — Pick a good prefix

The source's prefix is prepended to table names in HogQL. Tables end up as {prefix}_{table_name}.

  • Default to the source type lowercased if there's only one source of that type: stripe, postgres.

  • If the user already has a Postgres source, pick something distinguishing: postgres_prod, postgres_analytics.

  • Use lowercase, underscore-separated. The prefix becomes part of every HogQL query the user writes.

Confirm the prefix with the user before creating — changing it later is possible but renames every table.

Step 5 — Create the source

Call external-data-sources-create with:

{
  "source_type": "Postgres",
  "prefix": "postgres_prod",
  "payload": {
    "host": "...",
    "port": "5432",
    "dbname": "...",
    "user": "...",
    "password": "...",
    "schema": "public",
    "schemas": [
      {
        "name": "orders",
        "should_sync": true,
        "sync_type": "incremental",
        "incremental_field": "updated_at",
        "incremental_field_type": "datetime",
        "primary_key_columns": ["id"]
      },
      {
        "name": "users",
        "should_sync": true,
        "sync_type": "full_refresh"
      },
      {
        "name": "audit_log",
        "should_sync": false
      }
    ]
  }
}

Rules for the schemas array:

  • Every table returned by db-schema should be included, even ones the user doesn't want (set should_sync: false). Tables the user didn't mention default to should_sync: false.

  • sync_type is required only when should_sync: true.

  • incremental_field / incremental_field_type must be present when sync_type is incremental or append.

  • primary_key_columns must be present when sync_type is cdc.

On success you'll get back a source with a new id. The first sync is triggered automatically.

Step 6 — Register a webhook (only when any schema is sync_type: "webhook")

Webhook-type schemas don't start receiving data just by existing — the external service needs to know where to POST events, and PostHog needs to know how to verify them. This is a second call after source creation, not part of the external-data-sources-create payload. Do this before telling the user the setup is complete, otherwise they hear "syncs are running" while the push channel is still unregistered.

Only needed when at least one schema on the source has sync_type: "webhook" and should_sync: true. Currently only Stripe implements this flow; for everything else skip this step.

Before calling create-webhook, check external-data-sources-webhook-info-retrieve({id}). If it already returns exists: true, do NOT call create-webhook again — each successful call registers a new external endpoint and would result in duplicate deliveries.

  1. Call external-data-sources-create-webhook-create({id}). PostHog:

    • creates the HogFunction that will receive webhook POSTs,

    • builds a schema_mapping from external event types to PostHog schema ids,

    • calls the source's API (e.g. Stripe) to register the webhook URL and subscribe to the relevant events,

    • on Stripe, auto-captures the signing_secret and stores it securely.

    Returns {success, webhook_url, error}. On success report the webhook_url to the user for their records — but they don't need to paste it anywhere; registration is already done.

  2. If success: false with a permissions error like "API key doesn't have permission to create webhooks":

    • The HogFunction is still created, just disabled.

    • Ask the user to create the webhook manually in the source's dashboard using the returned webhook_url.

    • Have them copy the signing secret from the source's webhook settings.

    • Call external-data-sources-update-webhook-inputs-create({id}, {inputs: {signing_secret: "whsec_..."}}) to store it. The HogFunction picks it up and verifies incoming payloads.

  3. Verify with external-data-sources-webhook-info-retrieve({id}). A healthy webhook has exists: true, external_status.status: "enabled", and no error.

Webhooks are supplementary to bulk sync. The first load of a webhook-enabled schema is still done via polling (initial_sync_complete flips to true when done); after that, the webhook becomes the primary ingestion path. A webhook schema will still have a sync_frequency that schedules a periodic bulk refresh as a safety net. This is expected — not something to "fix".

Step 7 — Confirm and explain what happens next

After creation (and, for webhook schemas, after Step 6):

  • Call external-data-schemas-list to show the user the initial state.

  • Explain: every enabled schema enters Running, then moves to Completed when the first sync finishes. First syncs can take anywhere from seconds to hours depending on row count — a multi-million-row table is fine, just slow.

  • Tell them how to query: SELECT * FROM {prefix}_{table_name} LIMIT 10 in HogQL.

  • Offer to check back in a few minutes to confirm the initial syncs succeeded.

CDC setup for Postgres (optional, when requested)

If the user wants near-real-time replication from Postgres:

  1. Before calling db-schema, run external-data-sources-check-cdc-prerequisites-create with their Postgres creds. It returns {valid, errors[]} listing anything missing (wal_level, replication slot, publication, permissions).

  2. If valid: false, present the errors and ask the user to fix on the Postgres side. Don't try to create a CDC source that will immediately fail.

  3. Once prerequisites pass, proceed to db-schema and create. Set sync_type: "cdc" on the tables that need it, and include primary_key_columns for each (CDC requires them).

Sending a source to the user's own warehouse (optional, when requested)

Only do this when the user asks for their data in their own Snowflake, BigQuery, Postgres, Redshift, Databricks, S3 or Azure Blob storage. These tools exist only when the feature is on for the project.

  1. Call external-data-destinations-list first. If a destination for that target already exists, reuse it, but only when its status is healthy. A failing or paused one needs fixing first (see the end of this section).

  2. Call external-data-destinations-connect-link with the destination_type (for S3-compatible storage such as R2 or MinIO, also pass integration_kind: "s3-compatible"). Share connect_url. The user must open it while logged in to PostHog as the same user this session acts as. The page saves an integration.

  3. Call external-data-destinations-connect-link-status with the returned connect_token every few seconds until status is connected or expired. When it is connected, confirm display_name with the user and use integration_id. When it is expired, get a new link. If the user saved the connection as another PostHog user, the page shows the integration id instead: ask the user for it.

  4. Ask the user for the target (database and schema, dataset, bucket and prefix, and so on), then call external-data-destinations-create with type, name, integration and config. Creation tests the connection for every type except Redshift, and a 400 names the field to fix. A wrong Redshift target only shows up when the first sync fails. The target cannot change later, so confirm it before creating.

  5. Before you attach a source, check two things and tell the user what you find:

    • Call external-data-sources-destinations-retrieve. When destination_ids holds only the PostHog warehouse destination (is_posthog_warehouse in external-data-destinations-list), the source may write there by default, and attaching would stop its PostHog tables updating. If the user wants to keep them, call external-data-sources-destinations-update with that same list before step 6: it makes the warehouse an explicit link. Skip that call while any destination in external-data-destinations-list is paused, because it would delete a hidden link to that destination. Tell the user instead. When destination_ids is empty, tell the user the PostHog tables stop updating.

    • Tables with their own destination override keep it and ignore the new source link. Call external-data-schemas-destinations-retrieve for the source's tables. Those with inherits_from_source: false will not reach the new destination.

  6. Call external-data-destinations-add-sources with the source ids. A source that has already synced sends only new rows to the destination. Offer resync: true to copy the history, and say that a resync re-reads every row (including overridden tables that do not reach the new destination) and bills every destination the source writes to.

If a destination shows status: "failing" or "paused", run external-data-destinations-test-connection and relay the message of the first failed step. Redshift has no test: relay latest_error from external-data-destinations-retrieve instead. The test only reports. A paused destination stays paused until the user fixes the problem and saves it on the warehouse destinations page.

Important notes

  • Always validate creds with db-schema before create. The create endpoint will accept invalid creds and then fail asynchronously — the source appears in the list with status Error and no tables. Skipping the validation step just pushes the failure into the background.

  • Present the table list before creating. Large databases may have hundreds of tables. Don't auto-select them all — row counts and relevance matter for billing. Let the user opt in explicitly.

  • Don't invent schemas. Every entry in the schemas array must correspond to a real table from the db-schema response. You can't "also add an orders table" unless db-schema found one.

  • A new source syncs to the PostHog warehouse. That is the default and it needs no setup: a source nobody configured destinations for writes here and nowhere else. Some projects can also send a source's tables to their own database (external-data-sources-destinations-retrieve shows where a source writes, when the feature is on for the project). Setting that up is a separate step (see "Sending a source to the user's own warehouse") and never something to do as part of creating a source — adding a destination to a source that has already synced leaves it holding none of the history until the tables are resynced, and a resync bills every destination the source writes to.

  • Prefix is load-bearing. It's part of every HogQL query the user will ever write against these tables. Pick something short, descriptive, and not already taken.

  • Prefer the secure connect-link for any credentials. Use data-warehouse-source-connect-link so the user authenticates in their browser — the connect page renders the source's full connection form (OAuth and credential options alike) and stores the result without creating the source. Don't collect OAuth tokens or database passwords in chat; pass the credential_id reference to setup — source creation always happens through setup, not the UI. (An already-connected OAuth integration can also be passed directly via its id key, e.g. {"hubspot_integration_id": 123}.)

  • Webhooks are a separate step after create. Setting sync_type: "webhook" on a schema doesn't register the webhook — the create-webhook call does. Always follow create → create-webhook → webhook-info for webhook-type schemas, and never leave a webhook schema dangling without registration (it just won't receive events).

  • Webhook support is source-specific and sparse. Currently only Stripe implements WebhookSource. Don't promise webhooks for Hubspot, Salesforce, or Postgres — they'll use polling sync.

  • Row counts drive billing. Warehouse syncing is metered by rows synced. A chatty 500M-row events table synced hourly is very different from a 10k-row dimension table synced daily. Flag large tables and offer longer sync frequencies (sync_frequency: "24hour") as the default.

Files

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Needs an API key

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Published by
PostHog
Publisher
PostHog (Official)
Source
PostHog/skills · skills/omnibus/setting-up-a-data-warehouse-source · commit a5d30e7
Licence
MIT License (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by PostHog.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download setting-up-a-data-warehouse-source.zip