---
title: "Health-probe the seeded Host Snowflake connection under the caller's own rights."
method: POST
path: "/v1/connections/host/test"
tags: ["connections"]
---

# Health-probe the seeded Host Snowflake connection under the caller's own rights.

`POST /v1/connections/host/test`

## Request

- Base URL: `http://localhost:8080`
- URL: `http://localhost:8080/v1/connections/host/test`
- Auth: one of:
  - API key in cookie `dvt_session`
  - HTTP bearer

Snowflake mode only. Unlike `POST /v1/connections/{id}/test` — admin-gated, runs
under the stored service credential, and has nothing to test for the secretless
`spcs_token` host connection — this runs four read-only checks under the
REQUESTING USER's own Snowflake rights (caller's-rights, DVT-1385), never a
service identity: `session` (does the caller's token resolve to a live Snowflake
session), `warehouse` (does the session have a usable warehouse — the caller's
own default, or the app's consumer-bound fallback warehouse, DVT-2192), `databases`
(can the caller see any database at all — the most common "why is my dashboard
empty" cause under caller's-rights grants, DVT-1767), and `cortex` (DVT-2193:
`SHOW PARAMETERS LIKE 'CORTEX_CODE_%'` — has an admin silently zeroed the Cortex
Code daily credit limit, killing the in-app AI helper with no actionable error
anywhere else; this check fails ONLY on an explicit 0-credit limit and
neutral-passes when that can't be determined on this account). Any authenticated
member may call it; it is not admin-scoped. Stamps `lastTestedAt` (and, on
failure, `lastTestError`) onto the host connection, exactly like the admin test
endpoint — EXCEPT `cortex` is advisory-only and never contributes to that
persisted failure stamp (a 0-credit Cortex Code limit says nothing about
whether the connection can serve queries, so it must not false-alarm
`/admin/health`'s "needs attention" surface); a `cortex`-only failure still
flips this response's own `ok` to `false`, but leaves `lastTestError` unset.

`writeback` (DVT-2905 slice B, ADR-0077 r3) is a SEPARATE, additive
best-effort field, snowflake mode only: whether the org's `dvt_writeback`
database is provisioned (an admin has run the two-statement grant from the
Sheets setup panel) and the Snowflake APPLICATION database name, for templating
`GRANT ... TO APPLICATION "<name>"` in the admin panel. It runs under APP
IDENTITY (never the caller's own token), so it is independent of the four
caller's-rights checks above and is present even when `session` fails.
Present only when the org has a live boot-provisioned Host Snowflake
Writeback connection to probe; omitted everywhere else (gallery/enterprise,
or a snowflake deployment where writeback hasn't provisioned yet) — never
contributes to this response's `ok` or the persisted `lastTestError` stamp.

A per-check failure is a normal `200` — the check ran and answered "no", which is
the useful signal. Off snowflake mode, this route does not exist (`404`,
leak-safe). A genuine engine/infra fault (unreachable, at-capacity) aborts the
whole probe with a non-`200` rather than a misleading partial result.

## Response `200`

The probe outcome — four itemized checks plus the overall ok.

- object
  - `data` HostConnectionTestResult, required: Response body for POST /v1/connections/host/test (DVT-1777) — a caller's-rights health probe for the seeded Host Snowflake connection. checks always holds exactly four entries, ids "session", "warehouse", "databases", "cortex", in that order; ok is the conjunction of every check's own ok. writeback (DVT-2905 slice B) is a separate, additive field — see its own schema doc.
    - `ok` boolean, required
    - `testedAt` string, date-time, required
    - `checks` HostConnectionCheck[], required
      - `id` 'session' | 'warehouse' | 'databases' | 'cortex', required
      - `label` string, required: Human-readable check name, e.g. "Session", "Warehouse", "Databases", "Cortex Code".
      - `ok` boolean, required
      - `detail` string, required: Human-readable outcome, e.g. "Connected to Snowflake as `ALICE`".
      - `suggestion` string: Actionable remediation, present only when ok is false.
    - `writeback` WritebackReadiness: SPCS writeback-readiness surface (DVT-2905 slice B, ADR-0077 r3; fresh semantics added in the r3 review round, HIGH-1), snowflake mode only — present on HostConnectionTestResult's writeback field (POST /v1/connections/host/test) and on GET /v1/connections/host/writeback-readiness's own writeback field, only when the org's boot-provisioned Host Snowflake Writeback connection resolves; omitted everywhere else (gallery/enterprise, or a snowflake deployment where writeback hasn't provisioned yet). Backed by a DESCRIBE-based probe run under app identity (never the caller's own token). POST /connections/host/test (the explicit "Verify setup" click) always requests a LIVE probe; GET /connections/host/writeback-readiness (a page-mount/background read) honors the engine's per-process provisioned-cache memo instead — a cache hit reports provisioned:true with an empty appDatabase (no connection was opened). Writeback needs TWO independent things from the consumer, and `provisioned` covers only the first. The warehouse* fields (DVT-2924) carry the second: whether the APPLICATION's own identity has compute. Binding the app's consumer_warehouse reference is necessary but NOT sufficient — it names a warehouse without granting the application usage of it, and the app-identity session holds no warehouse privilege of its own. A cache hit on the GET route reports these from a short-TTL memo (warehouse state, unlike provisioning, is not monotonic), so unlike appDatabase they are still populated there.
      - `provisioned` boolean, required: Whether the org's dvt_writeback database exists and is visible to the application's own identity. NOT a check that the app can CREATE SCHEMA or CREATE TABLE there: errno 3001 (visible but under-privileged) also reports true (DVT-5275); a missing CREATE SCHEMA grant surfaces later, at the first flush.
      - `appDatabase` string, required: The Snowflake APPLICATION database name for this deployment, for templating GRANT ... TO APPLICATION "<name>" statements in the admin panel. May be empty when a GET /connections/host/writeback-readiness cache hit skipped opening a connection — callers fall back to a placeholder in that case (see WritebackSetupPanel).
      - `writebackDatabase` string, required: This install's resolved Snowflake writeback database (DVT-5156) - the name the admin panel templates its GRANT statements against. Frozen once at API startup from WRITEBACK_SNOWFLAKE_DATABASE; always populated, including on a cache-hit GET.
      - `warehouseBound` boolean: Whether a warehouse NAME resolved into the application's own connection — i.e. the app's consumer_warehouse reference is bound (DVT-2924). False means the remediation is to bind the reference on the app's Privileges/Security page in Snowsight. OMITTED when the engine could not resolve the signal at all; an absent field means "unknown" and MUST NOT be read as false — telling an admin to bind a reference they already bound is the failure this field exists to prevent.
      - `warehouseUsable` boolean: Whether the application's OWN session actually has that warehouse active (CURRENT_WAREHOUSE() is non-null). warehouseBound:true with warehouseUsable:false means the reference is bound but the application was never granted usage of the warehouse, and the remediation is `GRANT USAGE ON WAREHOUSE <name> TO APPLICATION "<app>"` — NOT re-binding. Both states produce the identical user-visible symptom (Snowflake errno 606 on every writeback DML, with rows queueing silently), which is why they are reported separately. Omitted under the same conditions as warehouseBound, with the same absent-means-unknown rule.
      - `warehouseName` string: The warehouse identifier to template the GRANT statement against — the effective (session) name when usable, else the requested one. OMITTED (not empty-string) when no warehouse is bound, and also when the name failed the identifier allowlist — callers fall back to a placeholder in both cases. Engine-side validated against the same allowlist as appDatabase before being returned; unlike appDatabase, a rejection degrades this field to omitted rather than failing the whole probe, so warehouseBound/warehouseUsable still report.
      - `flushHold` WritebackFlushHold: Present on WritebackReadiness ONLY while the stranded-sheet flush hold (DVT-5166) is in force: the install's writeback database was switched after one or more sheets were pinned to a previous database, so this process flushes nothing (new rows keep queueing in the WAL) until the install is switched back and restarted, or an admin acknowledges it (POST /v1/orgs/{orgId}/writeback/flush-hold/acknowledge, which releases it without a restart). Computed at boot from the sheets' own pinned targets; strandedSheets is refreshed by each acknowledge attempt. Held until the process restarts without a covering acknowledgement, or an admin acknowledges it. Attached only when the engine readiness probe succeeded: a failed probe omits the whole writeback field (it is not "not provisioned", DVT-2924).
        - `cause` 'writeback-switch-stranded', required
        - `strandedSheets` integer, required: Count of pinned Snowflake sheets still naming a writeback database other than the install's current one. 0 when the count could not be computed - see strandedCountUnknown.
        - `strandedCountUnknown` boolean: True when the stranded count itself could not be computed (the hold is then taken fail-closed), so strandedSheets is 0 only as a placeholder. Omitted when the count is known.

## Other responses

- `401`: Missing, invalid, or expired session.
- `403`: The caller's role does not permit this action.
- `404`: Resource does not exist.
- `429`: Two causes, distinguished by the Problem `type` (DVT-3464 split this from a single shared `errors/rate-limited`, which made an engine-capacity shed indistinguishable from an actual rate limit): - `https://docs.dvt.dev/errors/rate-limited` — a rate or concurrency limiter for this operation rejected the request before it reached the engine. See `components/responses/RateLimited` for the general per-actor SEC-2 tier; some operations stack an additional operation-specific limiter (the query submit rate limit, the per-org running-job cap, or the trial query ceiling). - `https://docs.dvt.dev/errors/engine-at-capacity` — the engine's own admission control (ADR-0053) shed the request before it reached the warehouse — a dvt engine limit, not a warehouse or rate problem (DVT-765). `suggestion` names the actual wait in seconds and, when the engine reports a scope, whether the per-org or global engine concurrency cap was hit. Both carry `Retry-After` (seconds); back off for at least that long before retrying.
- `500`: An unexpected internal error occurred (e.g. resolving or recording the connection test).
- `502`: The analytics engine could not be reached or returned an unexpected error.

---

[API](https://skmtc.dev/dvt/apis/dvt-rest-api.md) · [All operations](https://skmtc.dev/dvt/apis/dvt-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/dvt/apis/dvt-rest-api/revisions/00016f504165?raw)
