# Source setup guides

> Shopify, Square, Google Analytics, Meta Ads, Google Sheets, Notion and GitHub: setup, caveats and tables.

Source: https://duckhouse.co/docs/sources

How to connect each source, what it needs on your side, and the tables it creates. For how syncing works in general (schedules, where data lands, how to query it) see [Connections](https://duckhouse.co/docs/connections.md).

> Every table has three extra columns
>
> `_raw` holds the complete record exactly as the source sent it, as JSON, so a field without a column of its own is still one `_raw->>'$.field'` away. `_deleted` is true once the record is gone at the source; the row is kept so history is not lost. `_synced_at` is when DuckHouse last wrote the row.

## Shopify

Orders with their line items, refunds, customers and products, for revenue and retention reporting.

### Set it up

1.  In your Shopify admin, open Settings → Apps → Develop apps → Build apps in Dev Dashboard, and create an app.
2.  In the app's Access section enter the scopes read\_orders, read\_customers and read\_products, then click Release. Add read\_all\_orders as well if you want orders older than 60 days.
3.  In the app's Installs section, click Install app and choose your store.
4.  Open the app's Settings, then copy the Client ID and Client secret into the form below.

### Good to know

-   Shopify stopped letting merchants create apps inside the store admin in January 2026. New stores create the app in Shopify's Dev Dashboard and give DuckHouse its **Client ID and Client secret**. If you have an older app with a token starting `shpat_`, paste that instead.
-   Shopify only returns the last 60 days of orders unless the app also has the `read_all_orders` scope.
-   The first load of a large store is slow by design: Shopify limits how fast any app may read, to roughly a thousand orders every few minutes. It continues in the background until it has caught up.
-   Line items and product variants are kept as JSON inside each order and product row.
-   Customers and products deleted in Shopify stay in the table: Shopify does not report deletions.
-   Syncs as often as every 15 minutes.

Show Hide 4 tables and their columns

orders

id varchar, name varchar, order\_number bigint, email varchar, phone varchar, financial\_status varchar, fulfillment\_status varchar, currency varchar, presentment\_currency varchar, subtotal\_price double, total\_price double, total\_tax double, total\_discounts double, total\_shipping double, total\_refunded double, customer\_id varchar, tags json, source\_name varchar, test boolean, note varchar, cancel\_reason varchar, created\_at timestamptz, updated\_at timestamptz, processed\_at timestamptz, cancelled\_at timestamptz, closed\_at timestamptz, line\_items json

refunds

id varchar, order\_id varchar, amount double, currency varchar, note varchar, created\_at timestamptz, updated\_at timestamptz

customers

id varchar, email varchar, phone varchar, first\_name varchar, last\_name varchar, display\_name varchar, state varchar, email\_marketing\_state varchar, verified\_email boolean, tax\_exempt boolean, orders\_count bigint, total\_spent double, currency varchar, city varchar, province\_code varchar, country\_code varchar, zip varchar, tags json, note varchar, locale varchar, created\_at timestamptz, updated\_at timestamptz

products

id varchar, title varchar, handle varchar, vendor varchar, product\_type varchar, status varchar, tags json, total\_inventory bigint, online\_store\_url varchar, created\_at timestamptz, updated\_at timestamptz, published\_at timestamptz, variants json

## Square

Payments, refunds, orders, customers, payouts, locations, team members, timecards, the item catalog and inventory from your Square account.

### Set it up

1.  Sign in to the Square Developer Console at developer.squareup.com/apps with the account that owns the business. If it lists no application, create one; any name will do.
2.  Open the application, choose Credentials in the left menu, and switch to Production at the top.
3.  Copy the Production access token and paste it below. It covers every location of the account.
4.  That token can do anything in the account, so treat it like a password. DuckHouse stores it encrypted and only ever reads.

### Good to know

-   Money is stored in the currency's smallest unit (cents), in `*_amount` columns with a `currency` beside them.
-   All of your locations are included, and a location added later is picked up automatically.
-   A personal access token can do anything in your Square account, not just read. Treat it like a password; DuckHouse stores it encrypted and only ever reads.
-   Payouts change status for days after they are created, so the last 30 days are re-read on every sync.
-   Sales are credited to staff through `team_member_id` on payments and refunds, which joins to `team_members`. Square only fills it in when staff sign in on the point of sale.
-   Timecards can be edited after the shift, so the last five weeks are re-read on every sync, and a timecard deleted in Square in that time is removed.
-   Order line items stay as JSON in `orders.line_items`; their `catalog_object_id` joins to `catalog_item_variations`, as does `inventory_counts`.
-   Syncs as often as every 15 minutes.

Show Hide 17 tables and their columns

locations

id varchar, name varchar, business\_name varchar, status varchar, type varchar, merchant\_id varchar, country varchar, currency varchar, language\_code varchar, timezone varchar, phone\_number varchar, business\_email varchar, website\_url varchar, description varchar, mcc varchar, address json, coordinates json, capabilities json, created\_at timestamptz

payments

id varchar, created\_at timestamptz, updated\_at timestamptz, status varchar, source\_type varchar, location\_id varchar, order\_id varchar, customer\_id varchar, reference\_id varchar, amount bigint, currency varchar, tip\_amount bigint, total\_amount bigint, approved\_amount bigint, refunded\_amount bigint, app\_fee\_amount bigint, processing\_fee json, card\_brand varchar, card\_last\_4 varchar, entry\_method varchar, refund\_ids json, team\_member\_id varchar, note varchar, receipt\_number varchar, receipt\_url varchar

refunds

id varchar, created\_at timestamptz, updated\_at timestamptz, status varchar, location\_id varchar, payment\_id varchar, order\_id varchar, reason varchar, amount bigint, currency varchar, app\_fee\_amount bigint, processing\_fee json, destination\_type varchar, unlinked boolean, team\_member\_id varchar

orders

id varchar, location\_id varchar, state varchar, created\_at timestamptz, updated\_at timestamptz, closed\_at timestamptz, customer\_id varchar, reference\_id varchar, source\_name varchar, ticket\_name varchar, total\_amount bigint, currency varchar, total\_tax\_amount bigint, total\_discount\_amount bigint, total\_tip\_amount bigint, total\_service\_charge\_amount bigint, net\_amount\_due bigint, line\_items json, discounts json, taxes json, service\_charges json, fulfillments json, tenders json, refunds json, returns json, version bigint

customers

id varchar, created\_at timestamptz, updated\_at timestamptz, given\_name varchar, family\_name varchar, company\_name varchar, nickname varchar, email\_address varchar, phone\_number varchar, address json, birthday varchar, reference\_id varchar, note varchar, creation\_source varchar, email\_unsubscribed boolean, group\_ids json, segment\_ids json, version bigint

payouts

id varchar, status varchar, type varchar, location\_id varchar, created\_at timestamptz, updated\_at timestamptz, arrival\_date date, amount bigint, currency varchar, payout\_fee json, destination\_type varchar, destination\_id varchar, end\_to\_end\_id varchar, version bigint

team\_members

id varchar, given\_name varchar, family\_name varchar, email\_address varchar, phone\_number varchar, status varchar, is\_owner boolean, reference\_id varchar, location\_assignment varchar, location\_ids json, job\_assignments json, is\_overtime\_exempt boolean, created\_at timestamptz, updated\_at timestamptz

jobs

id varchar, title varchar, is\_tip\_eligible boolean, created\_at timestamptz, updated\_at timestamptz, version bigint

timecards

id varchar, team\_member\_id varchar, location\_id varchar, status varchar, start\_at timestamptz, end\_at timestamptz, timezone varchar, job\_id varchar, job\_title varchar, hourly\_rate\_amount bigint, currency varchar, tip\_eligible boolean, declared\_cash\_tip\_amount bigint, breaks json, created\_at timestamptz, updated\_at timestamptz, version bigint

catalog\_items

id varchar, name varchar, description varchar, product\_type varchar, reporting\_category\_id varchar, categories json, is\_taxable boolean, tax\_ids json, modifier\_list\_info json, is\_archived boolean, is\_alcoholic boolean, abbreviation varchar, channels json, updated\_at timestamptz, version bigint, present\_at\_all\_locations boolean, present\_at\_location\_ids json, absent\_at\_location\_ids json

catalog\_item\_variations

id varchar, item\_id varchar, name varchar, sku varchar, upc varchar, ordinal bigint, pricing\_type varchar, price\_amount bigint, currency varchar, location\_overrides json, track\_inventory boolean, inventory\_alert\_type varchar, inventory\_alert\_threshold bigint, sellable boolean, stockable boolean, measurement\_unit\_id varchar, item\_option\_values json, team\_member\_ids json, updated\_at timestamptz, version bigint, present\_at\_all\_locations boolean, present\_at\_location\_ids json, absent\_at\_location\_ids json

catalog\_categories

id varchar, name varchar, category\_type varchar, parent\_category\_id varchar, is\_top\_level boolean, root\_category varchar, online\_visibility boolean, updated\_at timestamptz, version bigint, present\_at\_all\_locations boolean, present\_at\_location\_ids json, absent\_at\_location\_ids json

catalog\_modifier\_lists

id varchar, name varchar, selection\_type varchar, modifier\_type varchar, ordinal bigint, min\_selected\_modifiers bigint, max\_selected\_modifiers bigint, updated\_at timestamptz, version bigint, present\_at\_all\_locations boolean, present\_at\_location\_ids json, absent\_at\_location\_ids json

catalog\_modifiers

id varchar, modifier\_list\_id varchar, name varchar, price\_amount bigint, currency varchar, on\_by\_default boolean, ordinal bigint, location\_overrides json, updated\_at timestamptz, version bigint, present\_at\_all\_locations boolean, present\_at\_location\_ids json, absent\_at\_location\_ids json

catalog\_taxes

id varchar, name varchar, calculation\_phase varchar, inclusion\_type varchar, percentage double, applies\_to\_custom\_amounts boolean, enabled boolean, updated\_at timestamptz, version bigint, present\_at\_all\_locations boolean, present\_at\_location\_ids json, absent\_at\_location\_ids json

catalog\_discounts

id varchar, name varchar, discount\_type varchar, percentage double, amount bigint, maximum\_amount bigint, currency varchar, pin\_required boolean, modify\_tax\_basis varchar, updated\_at timestamptz, version bigint, present\_at\_all\_locations boolean, present\_at\_location\_ids json, absent\_at\_location\_ids json

inventory\_counts

id varchar, catalog\_object\_id varchar, catalog\_object\_type varchar, location\_id varchar, state varchar, quantity double, calculated\_at timestamptz, is\_estimated boolean

## QuickBooks Online

Invoices, bills, payments, journal entries and the chart of accounts, for finance reporting next to the rest of your data.

### Set it up

1.  Click Connect to QuickBooks below.
2.  Sign in to Intuit as an admin of the company. Only an admin can grant access.
3.  Choose the company to sync and approve. DuckHouse only reads; it never writes to your books.

### Good to know

-   There is nothing to paste: you sign in to Intuit as an admin of the company and approve. One Connection reads one company; add another Connection for each additional company.
-   DuckHouse only reads. It cannot create, change or delete anything in your books.
-   Transactions deleted in QuickBooks are marked `_deleted` on the next hourly check. QuickBooks keeps that history for 30 days, so a Connection paused for longer keeps deleted rows until the table is reloaded.
-   Customers, vendors, items and accounts are made inactive in QuickBooks rather than deleted, and are kept with their `active` flag.
-   Line items stay as JSON inside each invoice, bill and journal entry row.
-   Syncs as often as once an hour.

Show Hide 14 tables and their columns

company\_info

id varchar, company\_name varchar, legal\_name varchar, country varchar, email varchar, fiscal\_year\_start\_month varchar, company\_start\_date date, default\_time\_zone varchar, company\_addr json, name\_value json, created\_at timestamptz, updated\_at timestamptz

accounts

id varchar, name varchar, fully\_qualified\_name varchar, acct\_num varchar, classification varchar, account\_type varchar, account\_sub\_type varchar, description varchar, active boolean, sub\_account boolean, parent\_id varchar, current\_balance double, current\_balance\_with\_sub\_accounts double, currency varchar, created\_at timestamptz, updated\_at timestamptz

customers

id varchar, display\_name varchar, company\_name varchar, given\_name varchar, family\_name varchar, email varchar, phone varchar, active boolean, balance double, currency varchar, bill\_addr json, fully\_qualified\_name varchar, job boolean, parent\_id varchar, balance\_with\_jobs double, taxable boolean, sales\_term\_id varchar, sales\_term\_name varchar, ship\_addr json, created\_at timestamptz, updated\_at timestamptz

vendors

id varchar, display\_name varchar, company\_name varchar, given\_name varchar, family\_name varchar, email varchar, phone varchar, active boolean, balance double, currency varchar, bill\_addr json, acct\_num varchar, vendor\_1099 boolean, term\_id varchar, term\_name varchar, created\_at timestamptz, updated\_at timestamptz

items

id varchar, name varchar, fully\_qualified\_name varchar, sku varchar, type varchar, description varchar, active boolean, taxable boolean, unit\_price double, purchase\_cost double, track\_qty\_on\_hand boolean, qty\_on\_hand double, income\_account\_id varchar, income\_account\_name varchar, expense\_account\_id varchar, expense\_account\_name varchar, asset\_account\_id varchar, asset\_account\_name varchar, created\_at timestamptz, updated\_at timestamptz

invoices

id varchar, doc\_number varchar, txn\_date date, customer\_id varchar, customer\_name varchar, due\_date date, balance double, sales\_term\_id varchar, sales\_term\_name varchar, total\_tax double, email\_status varchar, bill\_email varchar, linked\_txn json, total\_amt double, currency varchar, exchange\_rate double, private\_note varchar, line json, created\_at timestamptz, updated\_at timestamptz

bills

id varchar, doc\_number varchar, txn\_date date, vendor\_id varchar, vendor\_name varchar, due\_date date, balance double, ap\_account\_id varchar, ap\_account\_name varchar, linked\_txn json, total\_amt double, currency varchar, exchange\_rate double, private\_note varchar, line json, created\_at timestamptz, updated\_at timestamptz

payments

id varchar, doc\_number varchar, txn\_date date, customer\_id varchar, customer\_name varchar, payment\_ref\_num varchar, unapplied\_amt double, payment\_method\_id varchar, payment\_method\_name varchar, deposit\_to\_account\_id varchar, deposit\_to\_account\_name varchar, total\_amt double, currency varchar, exchange\_rate double, private\_note varchar, line json, created\_at timestamptz, updated\_at timestamptz

bill\_payments

id varchar, doc\_number varchar, txn\_date date, vendor\_id varchar, vendor\_name varchar, pay\_type varchar, check\_payment json, credit\_card\_payment json, total\_amt double, currency varchar, exchange\_rate double, private\_note varchar, line json, created\_at timestamptz, updated\_at timestamptz

purchases

id varchar, doc\_number varchar, txn\_date date, payment\_type varchar, credit boolean, account\_id varchar, account\_name varchar, entity\_id varchar, entity\_name varchar, entity\_type varchar, total\_amt double, currency varchar, exchange\_rate double, private\_note varchar, line json, created\_at timestamptz, updated\_at timestamptz

deposits

id varchar, doc\_number varchar, txn\_date date, deposit\_to\_account\_id varchar, deposit\_to\_account\_name varchar, total\_amt double, currency varchar, exchange\_rate double, private\_note varchar, line json, created\_at timestamptz, updated\_at timestamptz

journal\_entries

id varchar, doc\_number varchar, txn\_date date, adjustment boolean, total\_amt double, currency varchar, exchange\_rate double, private\_note varchar, line json, created\_at timestamptz, updated\_at timestamptz

credit\_memos

id varchar, doc\_number varchar, txn\_date date, customer\_id varchar, customer\_name varchar, balance double, remaining\_credit double, total\_tax double, email\_status varchar, bill\_email varchar, linked\_txn json, total\_amt double, currency varchar, exchange\_rate double, private\_note varchar, line json, created\_at timestamptz, updated\_at timestamptz

estimates

id varchar, doc\_number varchar, txn\_date date, customer\_id varchar, customer\_name varchar, txn\_status varchar, expiration\_date date, accepted\_date date, total\_tax double, email\_status varchar, bill\_email varchar, linked\_txn json, total\_amt double, currency varchar, exchange\_rate double, private\_note varchar, line json, created\_at timestamptz, updated\_at timestamptz

## Google Analytics

Daily GA4 reports: traffic by channel and source, pages, events, devices and geography.

### Set it up

1.  In Google Analytics, open Admin → Property access management and add DuckHouse's service account with the Viewer role.
2.  Copy the numeric property ID from Admin → Property details and paste it below.
3.  There is no password or key to share. Removing that user in Google Analytics ends our access.

### Good to know

-   There is no sign-in: you add DuckHouse's Google account to your property as a Viewer, and enter the numeric property ID (not the `G-` measurement ID).
-   Each table is a daily report. The last three days are re-read on every sync, because Google keeps revising recent days.
-   `active_users` is the “Users” figure you see in Google Analytics; `total_users` reads slightly higher.
-   Google may withhold rows to protect visitor privacy, and may fold rare values into `(other)`. DuckHouse loads exactly what Google returns.
-   Syncs as often as once an hour.

Show Hide 5 tables and their columns

traffic\_daily

id varchar, date date, session\_default\_channel\_group varchar, session\_source\_medium varchar, sessions bigint, engaged\_sessions bigint, active\_users bigint, total\_users bigint, new\_users bigint, key\_events double, total\_revenue double

pages\_daily

id varchar, date date, page\_path varchar, screen\_page\_views bigint, sessions bigint, active\_users bigint, user\_engagement\_duration double

events\_daily

id varchar, date date, event\_name varchar, event\_count bigint, active\_users bigint, total\_users bigint

devices\_daily

id varchar, date date, device\_category varchar, operating\_system varchar, browser varchar, sessions bigint, active\_users bigint, total\_users bigint

geo\_daily

id varchar, date date, country varchar, region varchar, sessions bigint, active\_users bigint, total\_users bigint

## SFTP / FTP

CSV files dropped in a folder on your server, syncd into one table periodically.

### Set it up

1.  Create a user on the server that can read the folder the files land in. Read access is enough; DuckHouse never changes or deletes files.
2.  Allow connections from the internet. SFTP is best; plain FTP sends the password unencrypted, so use it only if nothing else is possible.
3.  Choose the column that identifies a row, such as id or order\_number. Each sync imports new or changed files, oldest first: a row with an identifier already in the table replaces it, and new ones are added.
4.  Files need a header row. Column types are detected from the first file and kept after that.

### Good to know

-   Works with SFTP, FTPS and plain FTP. Plain FTP sends the password unencrypted; use it only when the server offers nothing else.
-   Each sync imports files in the folder that match the pattern and are new or have changed (by size and modification time), oldest first. Files on the server are never changed or deleted.
-   Rows are matched on the identifier column: a row whose identifier is already in the table replaces it, new ones are added, and nothing is deleted. `_file` records which file a row last came from.
-   Files need a header row. Column types are detected from the whole of the first file and kept after that; a later value that does not fit (text in a number column) stops the sync with an error naming the column. New columns in later files are added.
-   A file with a blank or repeated identifier is refused rather than guessed at. If rows are only unique together with another column, list both as the identifier.
-   For SFTP, the server's host key seen on the first sync is remembered, and a different key later is refused. You can pin it up front instead.
-   Files up to 1 GB each; `.csv.gz` works too.
-   Syncs as often as every 5 minutes.

## Umami

Every pageview and custom event from Umami, plus sessions and its daily visitor numbers, on Umami Cloud or self-hosted.

### Set it up

1.  In Umami, open Settings → API keys and create a key. On Umami Cloud that is the only way in.
2.  Self-hosted without API keys (older than Umami 3)? Leave the key empty and enter a username and password instead; a read-only view-only user is enough.
3.  For a self-hosted install, enter its address. It must be reachable over HTTPS from the public internet.
4.  Every website the key can see is synced, including team websites. To sync only some, list their IDs.

### Good to know

-   Works with Umami Cloud and self-hosted Umami. A self-hosted install must be reachable over HTTPS from the public internet.
-   `events` holds every pageview (`event_type` 1) and custom event (`event_type` 2), with the visitor's browser, device and location. Join `sessions` on `session_id` for region, language and screen.
-   `stats_daily` is Umami's own visitors, visits, bounces and time on site per day, in the time zone you choose. These need Umami's visit ids, so they cannot be rebuilt from `events`.
-   Custom event properties (Umami's event data) are not synced yet; `has_data` marks the events that carry them.
-   Syncs as often as every 15 minutes.

Show Hide 4 tables and their columns

websites

id varchar, name varchar, domain varchar, team\_id varchar, user\_id varchar, share\_id varchar, created\_at timestamptz, updated\_at timestamptz, reset\_at timestamptz

events

id varchar, website\_id varchar, session\_id varchar, created\_at timestamptz, event\_type bigint, event\_name varchar, hostname varchar, url\_path varchar, url\_query varchar, page\_title varchar, referrer\_domain varchar, referrer\_path varchar, referrer\_query varchar, distinct\_id varchar, country varchar, city varchar, device varchar, os varchar, browser varchar, has\_data boolean

sessions

id varchar, website\_id varchar, distinct\_id varchar, hostname varchar, browser varchar, os varchar, device varchar, screen varchar, language varchar, country varchar, region varchar, city varchar

stats\_daily

id varchar, website\_id varchar, date date, pageviews bigint, visitors bigint, visits bigint, bounces bigint, totaltime bigint

## Meta Ads

Facebook and Instagram campaigns, ad sets and ads, with daily results for every ad: spend, impressions, clicks and conversions.

### Set it up

1.  In Meta Business settings, open Users → System users and add a system user. The Employee role is enough.
2.  Select it, choose Assign assets, pick your ad account and turn on View performance.
3.  Choose Generate token, pick one of your business's apps, tick the ads\_read permission, and paste the token below. A token set to never expire saves replacing it every 60 days.
4.  The ad account id is the number after act= in the Ads Manager address bar. It is also listed under Accounts → Ad accounts in Business settings.

### Good to know

-   Covers Facebook and Instagram ads. You create a system user in Meta Business settings and paste its token; the token needs only `ads_read`.
-   Archived and deleted ads are included in the daily figures. Meta leaves them out by default, which is the usual reason exported spend does not match Ads Manager.
-   `actions` and `action_values` are JSON, because Meta reports a list of action types that differs per account.
-   Results are attributed for up to 7 days after a click, so the last 7 days are re-read on every sync. Meta provides at most 37 months of history.
-   Syncs as often as once an hour.

Show Hide 4 tables and their columns

campaigns

id varchar, account\_id varchar, name varchar, status varchar, effective\_status varchar, objective varchar, buying\_type varchar, bid\_strategy varchar, daily\_budget bigint, lifetime\_budget bigint, budget\_remaining bigint, spend\_cap bigint, special\_ad\_categories json, start\_time timestamptz, stop\_time timestamptz, created\_time timestamptz, updated\_time timestamptz

ad\_sets

id varchar, account\_id varchar, campaign\_id varchar, name varchar, status varchar, effective\_status varchar, optimization\_goal varchar, billing\_event varchar, bid\_strategy varchar, bid\_amount bigint, daily\_budget bigint, lifetime\_budget bigint, budget\_remaining bigint, destination\_type varchar, attribution\_spec json, start\_time timestamptz, end\_time timestamptz, created\_time timestamptz, updated\_time timestamptz

ads

id varchar, account\_id varchar, campaign\_id varchar, adset\_id varchar, name varchar, status varchar, effective\_status varchar, creative\_id varchar, conversion\_domain varchar, created\_time timestamptz, updated\_time timestamptz

ad\_insights\_daily

id varchar, date date, account\_id varchar, account\_name varchar, account\_currency varchar, campaign\_id varchar, campaign\_name varchar, adset\_id varchar, adset\_name varchar, ad\_id varchar, ad\_name varchar, impressions bigint, clicks bigint, spend double, reach bigint, frequency double, cpm double, cpc double, ctr double, inline\_link\_clicks bigint, actions json, action\_values json

## Google Sheets

Every tab of a spreadsheet as a table, for the budgets, targets and lookups that only live in a sheet.

### Set it up

1.  Open the spreadsheet, click Share, and add the DuckHouse service account as a Viewer.
2.  Copy the link from your browser's address bar and paste it below.
3.  Each tab becomes a table, with column names taken from its header row. Every value arrives as text; cast it in SQL.

### Good to know

-   There is no sign-in: you share the spreadsheet with DuckHouse's Google account as a Viewer, then paste its link.
-   Every tab becomes a table named after the tab, and the header row gives the column names. A column headed `ID` becomes `id_2`, because `id` is reserved for the row number.
-   Every column is text. A spreadsheet column has no type, and one stray note in a number column would otherwise fail the whole load. Cast in SQL: `amount::DOUBLE`.
-   The whole sheet is re-read each time, so edits and deleted rows are reflected.
-   One Connection reads one spreadsheet. Add another Connection for each additional spreadsheet.
-   If your Google Workspace blocks sharing outside the organization, an admin has to allow it first.
-   Syncs as often as every 15 minutes.

## Notion

Pages and database rows with their properties, plus data sources and users. Page bodies (the text inside a page) are not synced yet.

### Set it up

1.  In Notion's Developer portal (app.notion.com/developers/connections), open Internal connections and create a new connection for your workspace. Notion used to call these integrations.
2.  On its Configuration tab, keep Read content on, turn on Read user information if you want the users table, then copy the installation access token and paste it below.
3.  Share what you want synced: on the connection's Content access tab choose Edit access, or on any page open the ••• menu → Connections and add it. Sub-pages and database rows come along with their parent.
4.  The connection sees nothing until something is shared with it, and newly shared pages can take a few minutes to appear.

### Good to know

-   Notion now calls integrations “internal connections”. A connection sees nothing until you share pages or databases with it, from the page's ••• menu → Connections.
-   Database rows arrive in `pages`, with their properties as JSON and the title pulled out into its own column.
-   Page bodies (the text inside a page) are not synced; only pages, databases and their properties.
-   Pages moved to the trash are flagged. Pages deleted permanently, or un-shared from the connection, stay in the table.
-   Syncs as often as every 15 minutes.

Show Hide 3 tables and their columns

users

id varchar, type varchar, name varchar, email varchar, avatar\_url varchar, bot json

data\_sources

id varchar, title varchar, description varchar, database\_id varchar, database\_parent\_type varchar, database\_parent\_id varchar, properties json, created\_time timestamptz, last\_edited\_time timestamptz, created\_by\_id varchar, last\_edited\_by\_id varchar, in\_trash boolean

pages

id varchar, title varchar, parent\_type varchar, parent\_id varchar, data\_source\_id varchar, database\_id varchar, properties json, created\_time timestamptz, last\_edited\_time timestamptz, created\_by\_id varchar, last\_edited\_by\_id varchar, in\_trash boolean, url varchar, public\_url varchar

## GitHub

Repositories, issues, pull requests, commits and releases, for engineering metrics next to your business data.

### Set it up

1.  In GitHub, open Settings → Developer settings → Personal access tokens → Fine-grained tokens.
2.  Choose the organization as the resource owner, and the repositories to include.
3.  Grant read-only access to Contents, Issues, Pull requests and Metadata, then paste the token below.

### Good to know

-   Use a fine-grained token with read-only access to Contents, Issues, Pull requests and Metadata.
-   Archived repositories are skipped unless you name them.
-   Issues and pull requests are separate tables; GitHub's own API mixes them together.
-   Syncs as often as every 15 minutes.

Show Hide 5 tables and their columns

repositories

id varchar, name varchar, full\_name varchar, owner varchar, private boolean, archived boolean, fork boolean, description varchar, language varchar, default\_branch varchar, stargazers\_count bigint, forks\_count bigint, open\_issues\_count bigint, size bigint, topics json, created\_at timestamptz, updated\_at timestamptz, pushed\_at timestamptz, html\_url varchar

issues

id varchar, repository varchar, number bigint, title varchar, state varchar, state\_reason varchar, author varchar, assignee varchar, labels json, milestone varchar, comments bigint, created\_at timestamptz, updated\_at timestamptz, closed\_at timestamptz, html\_url varchar

pull\_requests

id varchar, repository varchar, number bigint, title varchar, state varchar, draft boolean, author varchar, base\_ref varchar, head\_ref varchar, labels json, requested\_reviewers json, created\_at timestamptz, updated\_at timestamptz, closed\_at timestamptz, merged\_at timestamptz, merge\_commit\_sha varchar, html\_url varchar

commits

id varchar, repository varchar, sha varchar, message varchar, author\_name varchar, author\_email varchar, author\_login varchar, authored\_at timestamptz, committed\_at timestamptz, verified boolean, html\_url varchar

releases

id varchar, repository varchar, tag\_name varchar, name varchar, draft boolean, prerelease boolean, author varchar, created\_at timestamptz, published\_at timestamptz, html\_url varchar

## Stripe, PostgreSQL, MySQL and DuckDB

These are covered on the [Connections](https://duckhouse.co/docs/connections.md#postgresql-and-mysql) page, along with how database tables are kept current. DuckDB has [its own section](https://duckhouse.co/docs/connections.md#duckdb) there.
