> ## Documentation Index
> Fetch the complete documentation index at: https://support.configview.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Coda setup

## Part 1: Coda Data Ingestion

Set up a Coda API token so ConfigView can pull your Coda docs, pages, tables, sharing, workspace members, installed Packs, and per-doc usage analytics into the dashboard.

***

### Step 1: Create a Coda API Token

1. Go to: [https://coda.io/account](https://coda.io/account)
2. Scroll to the **API Settings** section
3. Click **Generate API token**
4. **Name:** `ConfigView`
5. Click **Generate**
6. Copy the token — you will only see it once

> The token inherits the permissions of the user that created it. Create it under an account that can see every doc you want ConfigView to audit (typically a workspace admin).

***

### Step 2: Add the Token to ConfigView

1. Go to your ConfigView dashboard: `https://{companyname}.configview.com/admin/secret/`
2. Click **Add Secret**
3. **Secret name:** `CODA_API_TOKEN`
4. **Secret value:** Paste the token from Step 1
5. Click **Save**

***

### Step 3: (Recommended) Set Internal Domains

By default, ConfigView treats the **doc owner's email domain** as "internal" and flags any share outside that domain as external. That fallback is fine for single-domain orgs where you always own your own docs, but it misclassifies three real cases:

* **Multi-domain orgs.** If your company uses `@acme.com` and `@acme.io`, a doc owned by someone at `acme.io` will flag every `acme.com` colleague as external.
* **External-owned docs.** A contractor creates a doc in your Coda workspace. The fallback treats the contractor's domain as internal, so your own employees show up as external shares.
* **Personal-email owners.** A doc owned from `@gmail.com` makes everyone else external noise.

Setting `CODA_INTERNAL_DOMAINS` replaces the per-doc heuristic with one authoritative list applied uniformly.

1. Go to: `https://{companyname}.configview.com/admin/secret/`
2. Click **Add Secret**
3. **Secret name:** `CODA_INTERNAL_DOMAINS`
4. **Secret value:** comma-separated list of your internal domains, e.g. `acme.com,acme.io`
5. Click **Save**

> **Optional — `CODA_WORKSPACE_ID`.** The **Workspaces**, **Workspace Members**, and **Users** scripts resolve your workspace automatically from `/whoami`. If your token belongs to more than one workspace and you want to pin a specific one, add a `CODA_WORKSPACE_ID` secret (looks like `ws-xxxxxxxxxx`, visible in any Coda doc URL or via `/whoami`).

***

### Step 4: Enable the Coda App in ConfigView

1. Go to: `https://{companyname}.configview.com/admin/cron/`
2. You should see **Coda** in the list of available apps
3. Select the scripts you want to run:
   * **Docs** — All docs visible to the API token, with owner info and external-share details
   * **Pages** — Every page across all docs (name, hidden flag, parent, created/updated)
   * **Tables** — Tables and views per doc, with row counts and parent page
   * **Permissions** — Normalized doc ACL: one row per doc × principal grant, with an `is_external` flag
   * **Workspaces** — Your workspace identity (id + name), from `/whoami`
   * **Workspace Members** — Members and their roles *(needs a workspace-admin token on a Team/Enterprise plan)*
   * **Users** — Distinct person directory derived from workspace membership *(same plan requirement as Workspace Members)*
   * **Packs** — Installed Packs (third-party / custom integrations) available to the workspace
   * **Doc Analytics** — Per-doc usage summary for stale-doc detection *(requires a Pro/Team/Enterprise workspace and a maker/admin token)*
4. Click **Save**

> **Plan note:** **Docs, Pages, Tables, Permissions, Workspaces,** and **Packs** work with any standard API token. **Workspace Members, Users,** and **Doc Analytics** call admin/analytics endpoints that Coda gates behind Team/Enterprise plans and workspace-admin tokens. When they aren't available, those scripts record an empty snapshot with an explanatory note instead of failing — so it's safe to enable them on any plan.

***

### Step 5: Verify

1. Go to: `https://{companyname}.configview.com/admin/status/`
2. Run the **Coda** health check
3. The core checks should pass:

   * Secret Manager access (`CODA_API_TOKEN`)
   * Coda API auth (`/whoami`)
   * `/docs` endpoint reachable

   The optional capability checks — **Workspace members**, **Packs**, and **Doc analytics** — report **ok** when reachable, or **skip** with a plan/scope note when your token or plan doesn't grant them. A skip is expected on non-Enterprise plans and does not fail the overall health check.

If a check fails, verify:

* The `CODA_API_TOKEN` secret is saved correctly (no extra spaces)
* The token was generated by an account that can see the docs
* The token has not been revoked in [https://coda.io/account](https://coda.io/account)

***

### Data Tables

Each enabled script creates and populates one table:

| Table                  | Script            | Key Columns                                                                                                              |
| ---------------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `coda_docs`            | Docs              | doc\_id, doc\_name, doc\_url, owner\_email, owner\_name, coda\_created\_at, external\_shares (JSON), notes               |
| `coda_pages`           | Pages             | page\_id, doc\_id, doc\_name, page\_name, content\_type, is\_hidden, parent\_page\_id, created\_at, updated\_at          |
| `coda_tables`          | Tables            | table\_id, doc\_id, doc\_name, table\_name, table\_type, row\_count, display\_column, browser\_link                      |
| `coda_permissions`     | Permissions       | permission\_id, doc\_id, doc\_name, principal\_type, principal\_email, principal\_domain, access, is\_external           |
| `coda_workspaces`      | Workspaces        | workspace\_id, workspace\_name                                                                                           |
| `coda_workspace_users` | Workspace Members | workspace\_id, email, name, role, owned\_docs                                                                            |
| `coda_users`           | Users             | email, name, status                                                                                                      |
| `coda_packs`           | Packs             | pack\_id, pack\_name, short\_description, category, certified, workspace\_id                                             |
| `coda_doc_analytics`   | Doc Analytics     | doc\_id, doc\_name, period\_start, period\_end, total\_users, total\_page\_views, total\_sessions, metrics (JSON), notes |

On `coda_docs`, `external_shares` is a JSON array of Coda ACL permission objects (principal + access level). The **Permissions** script normalizes the same ACL data into `coda_permissions` — one row per grant — so sharing can be queried with plain SQL (e.g. every doc shared to `anyone`, or every external collaborator).

Docs whose ACL/pages/tables cannot be read with the current token are skipped, and the run summary email reports how many were unreadable (usually docs the token user is not a member of).

`coda_doc_analytics.metrics` stores the raw Coda analytics payload so the data survives field renames; `total_users` / `total_page_views` / `total_sessions` are best-effort typed extractions. Docs whose analytics are gated by plan are still recorded with a `notes` explanation.

**Snapshot vs. upsert.** `coda_docs` is upserted on `doc_id` (one row per doc, updated in place). Every other table is a **per-run snapshot** stamped with `run_at` — query the latest with `WHERE run_at = (SELECT MAX(run_at) FROM <table>)`. This is the same convention the bundled curated queries (`apps.coda_workspace_members`, `identity.find_user_by_email`, `coverage.coda_users_not_in_google`) already use.

***

### External-Share Classification

A permission is counted as external when:

| Principal type | External when                                             |
| -------------- | --------------------------------------------------------- |
| `anyone`       | Always — this is a public or "anyone with the link" share |
| `email`        | The email's domain is not in your internal-domain set     |
| `domain`       | The domain itself is not in your internal-domain set      |

The internal-domain set comes from `CODA_INTERNAL_DOMAINS` if set; otherwise the doc owner's email domain is used per-doc (see Step 3).

***

### Troubleshooting

| Issue                                                 | Fix                                                                                                                                                               |
| ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Health check fails on "Coda API auth"                 | Verify `CODA_API_TOKEN` secret is correct; regenerate the token at [https://coda.io/account](https://coda.io/account) if needed                                   |
| `coda_docs` is empty after a run                      | The token's account has no docs it can see. Regenerate under a workspace admin account                                                                            |
| Many rows with `permissions unreadable`               | Expected for docs the token user is not a member of; grant the account access or regenerate the token under a broader account                                     |
| Own employees showing up as external                  | Set `CODA_INTERNAL_DOMAINS` with your full internal domain list (Step 3)                                                                                          |
| Public shares not flagged                             | Public shares appear as `principal.type = anyone` in the raw payload — verify the permission exists in Coda under **Share → Anyone with the link**                |
| `coda_workspace_users` / `coda_users` empty           | The token is not a workspace admin, or the workspace is on a plan without the members API. Regenerate the token under a workspace admin on a Team/Enterprise plan |
| `coda_doc_analytics` all show `analytics unavailable` | The workspace plan or token scope does not grant analytics. Use a maker/admin token on a Pro/Team/Enterprise workspace                                            |
| `owned_docs` is empty in `coda_workspace_users`       | It is derived from the latest `coda_docs` snapshot — enable and run **Docs** before (or alongside) **Workspace Members**                                          |
