Appearance
SQL Procedures API
Paid edition only. The compound procedures described below are available with the paid edition of Geo Data Connector. They are not included in the free edition.
Geo Data Connector provides four compound procedures that expose all application functionality directly from SQL. Use these to automate workflows, integrate with AI coding assistants, or manage data ingestion without launching the interactive application.
All compound procedures share the same signature:
sql
CALL SETUP.<procedure>('<action>', <params>);where <action> identifies the operation and <params> is a VARIANT (JSON object) containing action-specific parameters. Pass NULL when no parameters are needed.
Every call returns a JSON string with a consistent structure:
json
{"ok": true, "action": "list", "data": {...}, "error": null}Use PARSE_JSON() to extract fields from the result.
Database Context
Before calling any procedure, set the active database to the Geo Data Connector application database. This is the database that was created when you installed the Connector — its name matches the name you chose during installation (visible in Snowsight under Catalog → Apps).
sql
USE DATABASE GEO_DATA_CONNECTOR;Replace GEO_DATA_CONNECTOR with your application database name. If you are unsure of the name, list your installed applications:
sql
SHOW APPLICATIONS;The name column shows the application database name to use.
Without setting the database context, calls to SETUP.<procedure> will fail because Snowflake cannot resolve the schema.
Output Formats
All procedures support two output formats:
| Format | Signature | Returns | Best for |
|---|---|---|---|
| JSON (default) | CALL SETUP.<proc>('<action>', <params>) | JSON string | AI coding assistants, scripts, programmatic consumers |
| Tabular | CALL SETUP.<proc>('<action>', <params>, 'table') | Result set | Snowsight SQL worksheets, interactive use |
The tabular format renders data as native columns in Snowsight:
sql
-- JSON output (default)
CALL SETUP.GDC_TASK('list', NULL);
-- Tabular output (renders as a table in Snowsight)
CALL SETUP.GDC_TASK('list', NULL, 'table');
-- Tabular search results
CALL SETUP.GDC_DISCOVER('search', PARSE_JSON('{"q": "buildings Finland", "limit": 5}'), 'table');The tabular format uses CALL syntax. The SELECT * FROM TABLE(...) syntax is not supported because tabular procedures use dynamic columns that vary by action.
Error Handling
When a call fails, ok is false and the error object contains a code and message:
json
{"ok": false, "action": "get_setting", "data": null, "error": {"code": "INVALID_PARAMETER", "message": "..."}}| Error Code | Meaning |
|---|---|
UNKNOWN_ACTION | The action name is not recognized |
MISSING_PARAMETER | A required parameter was not provided |
INVALID_PARAMETER | A parameter value is not valid |
NOT_FOUND | The requested resource does not exist |
CONFIG_MISSING | A required configuration setting has not been set |
INVALID_SCHEDULE | The schedule value is not one of On-demand, Daily, Weekly, or Monthly |
NO_SCHEDULE | A schedule is required but was not provided |
DISCOVERY_ERROR | The Connector could not reach the external data source |
SEARCH_ERROR | The search request failed |
INTERNAL_ERROR | An unexpected error occurred |
Where an action takes a task name, use a name returned by the list action of GDC_TASK.
Configuration (GDC_CONFIG)
Available to the APP_ADMIN role. Manages application settings and checks infrastructure status.
Actions
list_settings
Returns all user-facing configuration settings.
Parameters: None. Pass NULL.
Response: Array of {KEY, VALUE} objects.
sql
CALL SETUP.GDC_CONFIG('list_settings', NULL);get_setting
Returns a single setting by key.
| Parameter | Required | Type | Description |
|---|---|---|---|
key | Yes | string | The setting key to retrieve |
Allowed keys: ingestion-database, notification-email, notify-task-success, notify-task-failure, notify-idle-warning, notify-auto-suspend, notify-idle-hours, auto-suspend-enabled, auto-suspend-timeout, app-edition, app-version, instance-id.
Returns INVALID_PARAMETER if the key is not in the allowed list. Returns null data if the key exists in the allowed list but has not been set.
sql
CALL SETUP.GDC_CONFIG('get_setting', PARSE_JSON('{"key": "ingestion-database"}'));set_setting
Creates or updates a setting.
| Parameter | Required | Type | Description |
|---|---|---|---|
key | Yes | string | The setting key to set |
value | Yes | string | The value to assign |
Writable keys: ingestion-database, notification-email, notify-task-success, notify-task-failure, notify-idle-warning, notify-auto-suspend, notify-idle-hours, auto-suspend-enabled, auto-suspend-timeout.
The keys app-edition, app-version, and instance-id are read-only and cannot be changed. Setting ingestion-database to a non-empty value also creates the database if it does not already exist.
Response: {OK: true, ERROR: null} on success.
sql
-- Set the ingestion database
CALL SETUP.GDC_CONFIG('set_setting', PARSE_JSON('{"key": "ingestion-database", "value": "MY_GDC_DATA"}'));
-- Enable email notifications on task failure
CALL SETUP.GDC_CONFIG('set_setting', PARSE_JSON('{"key": "notify-task-failure", "value": "true"}'));get_warehouse_status
Checks whether the compute warehouse is available.
Parameters: None. Pass NULL.
Response: {available: true|false}.
sql
SELECT PARSE_JSON(SETUP.GDC_CONFIG('get_warehouse_status', NULL)):data:available::BOOLEAN;get_eai_status
Checks whether External Access Integration is configured (required for discovery and ingestion).
Parameters: None. Pass NULL.
Response: {configured: true|false}.
sql
SELECT PARSE_JSON(SETUP.GDC_CONFIG('get_eai_status', NULL)):data:configured::BOOLEAN;get_auto_suspend_status
Returns the current auto-suspend configuration.
Parameters: None. Pass NULL.
Response: {enabled: true|false, timeout_minutes: integer, timeout_seconds: integer}.
sql
CALL SETUP.GDC_CONFIG('get_auto_suspend_status', NULL);Connections (GDC_CONNECTION)
Available to the APP_USER role. Manages saved data source connections.
Actions
count
Returns the number of saved connections.
Parameters: None. Pass NULL.
Response: {count: integer}.
sql
SELECT PARSE_JSON(SETUP.GDC_CONNECTION('count', NULL)):data:count::INT;list
Returns saved connections with pagination.
| Parameter | Required | Type | Default | Description |
|---|---|---|---|---|
page | No | integer | 1 | Page number (1-indexed) |
length | No | integer | 10 | Rows per page |
sortkey | No | string | NAME | Column to sort by |
sortorder | No | string | asc | Sort direction: asc or desc |
Sort keys: URI, TYPE, NAME_SERVICE, NAME, DATASET_COUNT, ACCESSED, CREATED, MODIFIED.
A page or length that is not a number, a sortorder that is not text, or a sortkey that is not one of the valid sort columns returns INVALID_PARAMETER.
Response: Array of connection objects with fields: URI, TYPE, NAME_SERVICE, DESCRIPTION, DATASET_COUNT, AUTH_METHOD, ACCESSED, CREATED, MODIFIED.
sql
CALL SETUP.GDC_CONNECTION('list', PARSE_JSON('{"page": 1, "length": 10}'));upsert
Creates a new connection or updates an existing one. Connections are identified by their URI.
| Parameter | Required | Type | Description |
|---|---|---|---|
uri | Yes | string | The data source URL |
type | Yes | string | Service type (e.g., WFS, WMS, WCS, WMTS, CSW) |
name_service | No | string | Service name (as reported by the data source) |
description | No | string | User-provided description |
dataset_count | No | integer | Number of datasets in the service |
auth_method | No | string | Authentication method: none (default) or basic |
auth_username | No | string | Username or API key (write-only, stored encrypted) |
auth_password | No | string | Password (write-only, stored encrypted, optional) |
When auth_method is basic, auth_username is required for new connections. On updates, omitting auth_username or auth_password preserves the existing encrypted value. Credentials are never returned by list or any other read action.
Response: {rows_inserted: integer, rows_updated: integer}.
sql
-- Connection without authentication
CALL SETUP.GDC_CONNECTION('upsert', PARSE_JSON('{
"uri": "https://inspire-wfs.maanmittauslaitos.fi/inspire-wfs/simple",
"type": "WFS",
"name_service": "NLS Finland INSPIRE WFS"
}'));
-- Connection with API key authentication
CALL SETUP.GDC_CONNECTION('upsert', PARSE_JSON('{
"uri": "https://avoin-paikkatieto.maanmittauslaitos.fi/tiedostopalvelu/ogcapi/v1",
"type": "OGC API Features",
"name_service": "NLS Finland File Service",
"auth_method": "basic",
"auth_username": "your-api-key"
}'));delete
Deletes a saved connection by URI.
| Parameter | Required | Type | Description |
|---|---|---|---|
uri | Yes | string | The connection URI to delete |
Response: {rows_deleted: integer}.
sql
CALL SETUP.GDC_CONNECTION('delete', PARSE_JSON('{"uri": "https://inspire-wfs.maanmittauslaitos.fi/inspire-wfs/simple"}'));Tasks (GDC_TASK)
Available to the APP_USER role. Requires External Access Integration (connectivity to external data sources). Manages the full lifecycle of ingestion tasks — create, delete, suspend, resume, schedule — and provides read-only access to task details, run history, and table information.
Schedule Values
Schedule parameters accept one of four values (case-insensitive):
| Value | Frequency |
|---|---|
On-demand | Runs once immediately on creation; no recurring schedule. Re-run using execute. NEXT_RUN is always N/A. |
Daily | Once per day |
Weekly | Once per week |
Monthly | Once per month |
On-demand is the default. Omitting the schedule parameter is equivalent to passing "schedule": "On-demand" — the task is enabled immediately and its first ingestion run starts on creation. For recurring schedules, the Connector converts the value to a Snowflake CRON expression automatically.
Actions — Task Lifecycle
create
Creates an ingestion task for a data source. If a task already exists for the same source, it is recreated with a fresh state.
| Parameter | Required | Type | Description |
|---|---|---|---|
url | Yes | string | The data source URL |
type | Yes | string | Service type (e.g., WFS, WMS, WCS, WMTS) |
dataset | Yes | string | The dataset name within the service |
schedule | No | string | On-demand, Daily, Weekly, or Monthly. Defaults to On-demand if omitted. |
scope | No | object | Limits the ingestion to a smaller geographic area and/or a coarser resolution — see Scoped Ingestion Tasks below. Omit for a regular, full-dataset task. |
rescope_origin | No | string | Only valid together with scope. The name of an existing enabled ingestion task to replace — see Re-scoping below. |
Response: {name: string, enabled: boolean}. The name is a deterministic identifier derived from the source parameters. The enabled field is true when registration succeeds (which it does whenever the Connector completes the task setup). create always returns the task's final outcome directly — it does not return a temporary or in-progress state, so there is no need to poll or re-check after create returns. An On-demand task runs immediately on creation; use execute to run it again. A scoped create additionally returns scope_hash (string) and effective_estimate (integer, the size estimate frozen when the task was created); a re-scoping create (with rescope_origin) additionally returns rescope_pause_status ("paused" or "failed" — see Re-scoping).
Tasks that show
PROVISIONING: ingestion tasks can also be created directly from the Geo Data Connector application, not only viacreate. A task created that way may briefly show statusPROVISIONINGonlist/getwhile it's being set up, and can end up asCREATE_FAILEDorCREATE_REJECTEDif setup did not succeed — seelistbelow. Acreatecall returns its final outcome directly (no need to poll); while it is still running, another session listing tasks may see the task asPROVISIONING. If acreatecould not finish cleanly, the task stays in that state for up to about an hour (itsSTATUS_NOTEsays so) and is then marked as failed (CREATE_FAILED); you can then delete it and create it again. Ifcreateis called for a task that is currently being set up, it is rejected immediately with{"ok": false, "error": {"code": "TASK_PROVISIONING", "message": "This ingestion task is still being set up — try again shortly."}}rather than starting a second, conflicting setup — try again once the existing setup finishes. If the task could not finish setting up cleanly, the message instead says it will be marked as failed within about an hour and that you can then delete it and create it again.
A task for this dataset already exists: the Connector does not create a second ingestion task for a dataset that already has one, even when the service address is written a little differently (for example with or without extra text at the end of the address). If a task for the same data source, type and dataset already exists,
createis rejected immediately with{"ok": false, "error": {"code": "TASK_ALREADY_EXISTS", "message": "An ingestion task already exists for this dataset (task INGESTION_...). No new task was created — use the existing task, or delete it first to re-create it."}}; nothing is created and no run starts. The message names the existing task: use thatname, ordeleteit first and create it again. For a task limited to an area (scope) the message says "for this dataset and area", and only a task for the same area counts. Creating the same task again with exactly the same address you used before is not affected. If the Connector cannot check for an existing task at that moment,createis rejected with the codeINTERNAL_ERRORand a message asking you to try again; no task is created, and it is safe to retry.
Prerequisite: The ingestion-database setting must be configured via GDC_CONFIG('set_setting', ...) before creating tasks. Returns CONFIG_MISSING if not set.
sql
-- Bare create (no schedule) — defaults to On-demand, runs immediately
CALL SETUP.GDC_TASK('create', PARSE_JSON('{
"url": "https://inspire-wfs.maanmittauslaitos.fi/inspire-wfs/bu_mtk_polygon",
"type": "WFS",
"dataset": "bu-core2d:Building"
}'));
-- Explicit On-demand (same as bare create)
CALL SETUP.GDC_TASK('create', PARSE_JSON('{
"url": "https://inspire-wfs.maanmittauslaitos.fi/inspire-wfs/bu_mtk_polygon",
"type": "WFS",
"dataset": "bu-core2d:Building",
"schedule": "On-demand"
}'));
-- Create a daily WFS ingestion task
CALL SETUP.GDC_TASK('create', PARSE_JSON('{
"url": "https://inspire-wfs.maanmittauslaitos.fi/inspire-wfs/bu_mtk_polygon",
"type": "WFS",
"dataset": "bu-core2d:Building",
"schedule": "Daily"
}'));
-- Create a scoped ingestion task limited to a geographic area
CALL SETUP.GDC_TASK('create', PARSE_JSON('{
"url": "https://inspire-wfs.maanmittauslaitos.fi/inspire-wfs/bu_mtk_polygon",
"type": "WFS",
"dataset": "bu-core2d:Building",
"schedule": "On-demand",
"scope": {"bbox": {"west": 24.8, "south": 60.1, "east": 25.1, "north": 60.3}}
}'));Scoped Ingestion Tasks
For datasets too large to ingest in full, create accepts an optional scope parameter that limits the ingestion to a smaller geographic area and/or a coarser resolution instead of the entire dataset. scope is an object with a geographic area (bbox: west/south/east/north boundaries in WGS 84 longitude/latitude) and, for some data source types, a resolution setting.
Scoped ingestion is currently available for coverage-type (WCS, OGC API Coverages), image-type (WMS, OGC API Maps), tile (OGC API Tiles vector tiles; WMTS and OGC API Tiles map tiles on geographic latitude/longitude tile grids), and vector-type (WFS, OGC API Features) data sources. Other data source types, and some source types' tile grids, do not support scoping — create rejects the scope with an explanatory message in that case.
The size of the scoped subset is checked when the task is created — if the selected area or resolution is invalid, unsupported for the data source's type, or does not sufficiently reduce the dataset, create is rejected with an explanatory message. A scoped ingestion task is immutable once created — its area and resolution cannot be changed afterward; create a new scoped task (optionally with rescope_origin, below) to adjust the scope. Data already ingested by the original task is preserved. (The SQL Procedures API is available on the paid edition only; the Free edition's row-limit and per-dataset scoped-task limits — see Editions — apply to the Connector's user interface, not to this API.)
If a scoped task's selected area turns out to contain no data (for example, it covers only cells the dataset has no values for), the run completes as skipped, not as a failure, and the task stays enabled — see the SKIPPED run status below.
Scoped tasks appear in list/get results alongside regular tasks, identified by their scoped dataset name, and carry the additive SCOPE/SCOPE_HASH/EFFECTIVE_ESTIMATE fields described under list below.
Re-scoping
To replace an existing enabled task with a re-scoped one in a single step, pass rescope_origin (the existing task's name) together with scope on create: the new task is created and the previous task is automatically suspended. The response then includes rescope_pause_status: "paused" when the previous task was suspended successfully, or "failed" when it could not be — in that case, suspend the previous task manually (see suspend below). The new task is never affected if pausing the previous one fails. rescope_origin is valid only together with scope, and must name an existing enabled ingestion task.
sql
-- Re-scope: create a new scoped task and suspend the previous one
CALL SETUP.GDC_TASK('create', PARSE_JSON('{
"url": "https://inspire-wfs.maanmittauslaitos.fi/inspire-wfs/bu_mtk_polygon",
"type": "WFS",
"dataset": "bu-core2d:Building",
"schedule": "On-demand",
"scope": {"bbox": {"west": 24.6, "south": 60.0, "east": 25.3, "north": 60.4}},
"rescope_origin": "INGESTION_927d79958453454b267925f28d4f4675_SA1B2C3D4E5F6"
}'));delete
Deletes a task, removes all associated Snowflake task objects, and deregisters the data source. Provide either the task name or the source identifiers.
| Parameter | Required | Type | Description |
|---|---|---|---|
name | Either name or all three source params | string | The task name |
url | string | The data source URL | |
type | string | Service type | |
dataset | string | The dataset name |
Response: {rows_deleted: integer}.
If the data service cannot be reached or does not accept the removal, the call returns {"ok": false, "error": {"code": "EXTERNAL_SERVICE_ERROR", "message": "..."}} and nothing is deleted — the task and its run history are kept (the task is normally suspended meanwhile — check it with get), so you can call delete again in a moment.
sql
-- Delete by name
CALL SETUP.GDC_TASK('delete', PARSE_JSON('{"name": "INGESTION_927d79958453454b267925f28d4f4675"}'));
-- Delete by source identifiers
CALL SETUP.GDC_TASK('delete', PARSE_JSON('{
"url": "https://inspire-wfs.maanmittauslaitos.fi/inspire-wfs/bu_mtk_polygon",
"type": "WFS",
"dataset": "bu-core2d:Building"
}'));suspend
Suspends a scheduled task and disables automatic ingestion.
| Parameter | Required | Type | Description |
|---|---|---|---|
name | Yes | string | The task name |
Response: null. The task is disabled. If the task was not already in a terminal state, its status changes to INACTIVE. If the data service could not be reached or did not accept the change, the task is still suspended and the response also includes an error — try suspend again in a moment.
sql
CALL SETUP.GDC_TASK('suspend', PARSE_JSON('{"name": "INGESTION_927d79958453454b267925f28d4f4675"}'));resume
Resumes a suspended task. Uses the task's existing schedule unless overridden.
| Parameter | Required | Type | Description |
|---|---|---|---|
name | Yes | string | The task name |
schedule | No | string | On-demand, Daily, Weekly, or Monthly. If omitted, uses the task's existing schedule. Returns NO_SCHEDULE ("This ingestion task has no schedule, so it cannot be resumed.") if the task has no schedule and none is provided. |
Response: {enabled: boolean}.
sql
-- Resume with existing schedule
CALL SETUP.GDC_TASK('resume', PARSE_JSON('{"name": "INGESTION_927d79958453454b267925f28d4f4675"}'));
-- Resume with a new schedule
CALL SETUP.GDC_TASK('resume', PARSE_JSON('{"name": "INGESTION_927d79958453454b267925f28d4f4675", "schedule": "Weekly"}'));set_schedule
Changes the schedule of an existing task. The task is briefly suspended and resumed with the new schedule.
| Parameter | Required | Type | Description |
|---|---|---|---|
name | Yes | string | The task name |
schedule | Yes | string | On-demand, Daily, Weekly, or Monthly |
Response: {schedule: string, enabled: boolean}. When switching to On-demand, the task has no recurring schedule; NEXT_RUN will be N/A.
sql
CALL SETUP.GDC_TASK('set_schedule', PARSE_JSON('{
"name": "INGESTION_927d79958453454b267925f28d4f4675",
"schedule": "Monthly"
}'));unset_schedule
Removes the schedule from a task. The task is suspended and will only run when executed manually.
| Parameter | Required | Type | Description |
|---|---|---|---|
name | Yes | string | The task name |
Response: null.
sql
CALL SETUP.GDC_TASK('unset_schedule', PARSE_JSON('{"name": "INGESTION_927d79958453454b267925f28d4f4675"}'));execute
Runs a task immediately, regardless of its schedule. The task's status changes to IN PROGRESS. Running a task that is suspended runs it once and leaves it suspended: its schedule is not turned back on (use resume for that). If the run cannot be started, the task keeps (or, if its schedule could not be restored, shows) its true state and the call returns an error.
| Parameter | Required | Type | Description |
|---|---|---|---|
name | Yes | string | The task name |
Response: {name: string}.
sql
CALL SETUP.GDC_TASK('execute', PARSE_JSON('{"name": "INGESTION_927d79958453454b267925f28d4f4675"}'));Actions — Task Information
count
Returns the number of ingestion tasks.
Parameters: None. Pass NULL.
Response: {count: integer}.
sql
SELECT PARSE_JSON(SETUP.GDC_TASK('count', NULL)):data:count::INT AS task_count;list
Returns ingestion tasks with pagination.
| Parameter | Required | Type | Default | Description |
|---|---|---|---|---|
page | No | integer | 1 | Page number (1-indexed) |
length | No | integer | 10 | Rows per page |
sortkey | No | string | TASK_NAME | Column to sort by (see below) |
sortorder | No | string | asc | Sort direction: asc or desc |
filter | No | string | — | Filter tasks by exact name (case-insensitive) |
status | No | string | — | Filter tasks by status: SUCCESS, FAILED, RETRYING, IN PROGRESS, SKIPPED, INACTIVE, PROVISIONING, CREATE_FAILED, or CREATE_REJECTED (case-insensitive; PROVISIONING, CREATE_FAILED and CREATE_REJECTED can also be seen for a task created with create — see below) |
enabled | No | string | — | Filter tasks by enabled state: true or false |
Sort keys: TASK_NAME, SOURCE_TYPE, DATA_SOURCE, DATASET, TARGET_TABLE, STATUS, NEXT_RUN, ENABLED, SCHEDULE, CREATED, LAST_RUN.
A page or length that is not a number, a sortorder that is not text, or a sortkey that is not one of the valid sort columns returns INVALID_PARAMETER.
Response: Array of task objects with fields: TASK_NAME, SOURCE_TYPE, DATA_SOURCE, DATASET, TARGET_TABLE, STATUS, STATUS_NOTE, NEXT_RUN, LAST_RUN, CREATED, ENABLED, SCHEDULE — plus, on scoped tasks only, the additive fields SCOPE, SCOPE_HASH, and EFFECTIVE_ESTIMATE (omitted entirely on regular, unscoped tasks).
The DATA_SOURCE field contains the title of the data source. Falls back to the URL if no title is available. The STATUS field contains one of: SUCCESS, FAILED, RETRYING, IN PROGRESS, SKIPPED, INACTIVE, PROVISIONING, CREATE_FAILED, or CREATE_REJECTED. STATUS_NOTE provides context for the current status: while ingestion is running, it shows the current execution phase (e.g., "3/6 Retrieving") — or, if the data source is temporarily unavailable, a message indicating the Connector is waiting for it to become available; when the task has failed, it contains the failure description including the phase where it occurred (a task can also reach FAILED after the data source stays unavailable through repeated automatic retries, not only from a processing failure); when retrying, it shows "Retrying shortly" for a quick retry within minutes, or the retry count for a retry on a later day, followed by the error (e.g., "Retrying shortly — timeout" or "Retry 1/2 — timeout"); when the most recent run was skipped, it shows the reason (the Free edition daily limit; for a scoped task, that the selected area contained no data; or that the Connector received a response it could not use while preparing to load the run's data, in which case the task stays enabled and tries again at its next run); when the task is PROVISIONING, CREATE_FAILED, or CREATE_REJECTED, it explains what happened (or is happening) with the task's setup; when an INACTIVE task was switched off because it is no longer set up, it says so and what to do (resume the task, or delete it and create it again). NEXT_RUN shows the next scheduled trigger time with a relative time suffix (e.g., "2026-04-08 06:00:00 (in 12 hours)"), or "N/A" for on-demand or disabled tasks. TARGET_TABLE is the fully qualified Snowflake table name (e.g., MY_DB.SCHEMA.TABLE). ENABLED shows "Enabled" or "Disabled".
PROVISIONING and CREATE_FAILED appear for a task created through the Geo Data Connector user interface, and can also be seen for a task created with create (see above); CREATE_REJECTED appears for a task created through the Connector's user interface, and for a task you re-created with create after it failed when another task for the same dataset already exists (STATUS_NOTE names it). PROVISIONING means the task is still being set up; it is temporary and moves to another status once setup finishes (if a create could not finish cleanly it stays in this state for up to about an hour, its STATUS_NOTE says so, and it is then marked CREATE_FAILED). CREATE_FAILED means the task could not be fully set up — delete it and try again. CREATE_REJECTED means the requested configuration could not be applied (for example, an invalid geographic area or resolution) — create a new task with an adjusted configuration; or, when STATUS_NOTE says another task for the dataset already exists, use that task instead (creating it again is refused). While a task is PROVISIONING, CREATE_FAILED, or CREATE_REJECTED, suspend, resume, set_schedule, unset_schedule, and execute are not available (they return an explanatory error); delete is available except while still PROVISIONING.
SCOPE is the geographic area and/or resolution the task is limited to (the object passed to create). SCOPE_HASH identifies the scope; the ingested table name carries a matching suffix so that multiple scoped tasks for the same dataset land in distinct tables. EFFECTIVE_ESTIMATE is the size estimate that was frozen when the task was created.
sql
-- List first 5 tasks sorted by name
CALL SETUP.GDC_TASK('list', PARSE_JSON('{"page": 1, "length": 5, "sortkey": "TASK_NAME"}'));
-- List tasks sorted by most recent run (newest first)
CALL SETUP.GDC_TASK('list', PARSE_JSON('{"sortkey": "LAST_RUN", "sortorder": "desc"}'));
-- List only enabled tasks
CALL SETUP.GDC_TASK('list', PARSE_JSON('{"enabled": "true"}'));
-- List failed tasks
CALL SETUP.GDC_TASK('list', PARSE_JSON('{"status": "FAILED"}'));
-- Tabular output
CALL SETUP.GDC_TASK('list', NULL, 'table');get
Returns a single task. Provide either the task name or the source identifiers.
| Parameter | Required | Type | Description |
|---|---|---|---|
name | Either name or all three source params | string | The task name (e.g., INGESTION_927D79958453454B267925F28D4F4675) |
url | string | The data source URL | |
type | string | Service type (e.g., WFS, WMS) | |
dataset | string | The dataset name within the service |
Response: Same columns as list — a single task object. Returns null if the task does not exist.
sql
-- Get by name
CALL SETUP.GDC_TASK('get', PARSE_JSON('{"name": "INGESTION_927D79958453454B267925F28D4F4675"}'));
-- Get by source identifiers
CALL SETUP.GDC_TASK('get', PARSE_JSON('{
"url": "https://inspire-wfs.maanmittauslaitos.fi/inspire-wfs/bu_mtk_polygon",
"type": "WFS",
"dataset": "bu-core2d:Building"
}'));A lookup by url, type and dataset also finds a task that was created with the same address written with or without its trailing parameters. The result shows the address the task was created with; use the returned name for any further action; an action given an address uses it exactly as written.
runs
Returns the ingestion run history for a task, sorted newest first.
| Parameter | Required | Type | Description |
|---|---|---|---|
name | Yes | string | The task name |
Response: Array of run objects with fields: NAME, START_TIME, END_TIME, STATUS, STATUS_NOTE, ERROR_MESSAGE, DURATION, TRIGGER, ROWS_LOADED, DATA_UPDATED. STATUS is one of PENDING, RUNNING, SUCCEEDED, FAILED, SKIPPED, CANCELLED, or POSTPONED. PENDING means the run has been started and is waiting for its first status update; right after a run is started you may see one PENDING line with STATUS_NOTE "Starting" and an empty NAME, which is replaced by the run's own line within a minute. While a run is active, STATUS_NOTE shows the current execution phase (null for completed runs). SKIPPED means the run completed without ingesting data — because the Free edition daily run limit was reached, because a scoped task's selected area contained no data, or because the Connector received a response it could not use while preparing to load the run's data — in that case the task stays enabled and tries again at its next run (STATUS_NOTE gives the reason). A skipped run still counts toward the Free edition daily run limit. CANCELLED means the task was suspended while the run was in progress. POSTPONED means the data source was temporarily unavailable when the run started. ERROR_MESSAGE provides a failure description for failed runs (null for succeeded runs). DURATION is a formatted duration string (e.g., "2m 30s"). TRIGGER indicates how the run was started (e.g., "SCHEDULED", "MANUAL"). DATA_UPDATED is when the data itself was last produced, which is not always the same as when the run finished: if you re-run a task shortly after a previous successful run, the new run may reuse that run's results rather than fetching again, so START_TIME and END_TIME advance while DATA_UPDATED stays at the earlier time. Use it to tell "the task ran again" from "the data actually changed". It is N/A for runs that did not complete successfully, since those produced no data.
sql
CALL SETUP.GDC_TASK('runs', PARSE_JSON('{"name": "INGESTION_927D79958453454B267925F28D4F4675"}'));table_info
Describes the ingested data table — its columns, row count, and a sample of rows.
| Parameter | Required | Type | Description |
|---|---|---|---|
name | Yes | string | The task name |
Response: {table: string, column_count: integer, row_count: integer, columns: [{name, type}, ...], sample: [{...}, ...]}. The sample contains up to 10 rows with column values truncated to 200 characters.
Returns NOT_FOUND if the task or its target table does not exist.
sql
CALL SETUP.GDC_TASK('table_info', PARSE_JSON('{"name": "INGESTION_927D79958453454B267925F28D4F4675"}'));metadata
Returns raster metadata for image-based source types.
| Parameter | Required | Type | Description |
|---|---|---|---|
name | Yes | string | The task name |
Applicable source types: WMS, WMTS, WCS, OGC API Maps, OGC API Coverages. Returns empty metadata for other source types.
Response: {exists: boolean, table: string|null, metadata: {...}}. The metadata object contains source-specific fields such as coordinate reference system, pixel dimensions, and geographic extent.
sql
CALL SETUP.GDC_TASK('metadata', PARSE_JSON('{"name": "INGESTION_927D79958453454B267925F28D4F4675"}'));stage_file_info
Returns information about the staged image file for a raster ingestion task.
| Parameter | Required | Type | Description |
|---|---|---|---|
name | Yes | string | The task name |
Applicable source types: WMS, WMTS. Returns empty data for other source types.
Response: {exists: boolean, file_location: string|null, file_size: integer, file_name: string|null}.
sql
CALL SETUP.GDC_TASK('stage_file_info', PARSE_JSON('{"name": "INGESTION_927D79958453454B267925F28D4F4675"}'));Discovery (GDC_DISCOVER)
Available to the APP_USER role. Requires External Access Integration. Browse and search geospatial data sources.
Note: Discovery and search calls retrieve data directly from external services and indexes. Response times depend on the external service. Only fields visible in the Connector's user interface are included in responses.
Actions
navigate
Browses an OGC service by URL. Use this to discover available datasets, list them, and inspect dataset details.
| Parameter | Required | Type | Default | Description |
|---|---|---|---|---|
url | Yes | string | — | The OGC service URL to browse |
page | No | integer | 1 | Page number for paginated results (10 items per page) |
node_id | No | string | — | Navigate to a specific dataset within the service |
number | No | integer | — | Select a source by its row number (as shown in the overview) |
item_number | No | integer | — | Drill into a specific item within the selected source |
q | No | string | — | Filter results within the service (minimum 2 characters) |
Note: Do not include authentication credentials (such as API keys or passwords) in the
urlparameter. URLs containing query parameters such asapikey,token, orpasswordwill be rejected. To access authenticated services, first save the connection usingGDC_CONNECTION('upsert', ...)with theauth_method,auth_username, andauth_passwordparameters. See Connections (GDC_CONNECTION) for details.
Response: The navigate action may return data directly or a processing ticket, depending on whether the result is immediately available:
- Immediate response — Returns an object describing the current navigation level (see below).
- Deferred response — Returns
{type: "ticket", ticket_id: "...", status: "processing"}. Use thestatusaction to poll until the result is ready (typically 5–30 seconds). See thestatusaction below.
When discovery data is returned (either immediately or after polling), the response structure depends on the navigation depth:
- Service overview (
{url}) —{source: {...}, items: [...], source_count, service_health, ...}— the data source summary plus its first-level items. - Service list (
{url}returning multiple sources) —{sources: [...], source_count}— each entry is a separate data source to choose from withnumber. - Items within the selected source (
{url, number}) —{source, items, ...}— the chosen source with its items listed. - Item detail (
{url, number, item_number}) — either{source, ...}(for a catalog record, where the Connector drills through the record to the underlying data source) or{item, columns, ...}(for a dataset within a service, where the dataset is returned with its column schema). See Two item kinds below.
Each item in the items array carries a 1-based number field indicating its position in the list — use this value as item_number to drill into that item.
Table format — listing datasets or catalog records. In the 'table' format, calling navigate with only a url returns a single row describing the data source (title, type, url, dataset counts). It does not list the datasets or catalog records as rows. To get those as rows, add "number": 1 (or the row number of the source you want to expand when the URL returned multiple sources):
sql
-- Table format: just the service summary (one row)
CALL SETUP.GDC_DISCOVER('navigate', PARSE_JSON('{
"url": "https://kart.hi.no/mareano/mareano_kjemi/perylen/ows?service=WFS"
}'), 'table');
-- Table format: list the service's datasets (or records) as rows
CALL SETUP.GDC_DISCOVER('navigate', PARSE_JSON('{
"url": "https://kart.hi.no/mareano/mareano_kjemi/perylen/ows?service=WFS",
"number": 1
}'), 'table');This is the standard pattern for listing datasets in table format, and the only way to see individual datasets/records as rows. In the 'json' format, the same {url} call already returns both the source summary and the items list together, so number is only needed when the URL exposes multiple sources and you want to select one.
Service detail fields. The source object (returned at the service overview level, or as the result of drilling through a catalog record to an underlying service) includes the following fields:
| Field | Description |
|---|---|
title | Data source title |
description | Data source description |
type | Service type (e.g., WFS, WMS, CSW) |
url | Service URL |
service_provider | Organization operating the service |
dataset_count | Number of datasets the service exposes |
data_source_count | Number of nested data sources (catalog services only) |
status_note | null when fully loaded; a message such as "Couldn't load - try again" when the service could not be fully loaded |
keywords | List of descriptive terms from the service metadata, or null |
crs_epsg_code | Default coordinate reference system (e.g., "EPSG:4326"), or null |
other_crs | List of all coordinate reference systems the service supports, or null |
data_formats | List of output formats the service supports, or null |
fees | Fee information as reported in the service metadata, or null. This text is provided by the data source owner — you are responsible for reviewing any applicable conditions. |
access_restrictions | Usage terms as reported in the service metadata, or null. You are responsible for reviewing and complying with any restrictions. |
Two item kinds. Items can be either nested data sources (when browsing a catalog such as CSW or OGC API Records, whose entries are themselves data sources) or datasets (when browsing a dataset-providing service such as WFS, WMS, WCS, WMTS, or OGC API Features). The fields present on each item reflect what the Connector's Discovery page shows for that kind:
| Item kind | Typical services | Item fields | item_number result |
|---|---|---|---|
| Nested data source | CSW, OGC API Records | number, title, description, type, url, service_provider, data_source_count, dataset_count, status_note | The Connector drills through the record to the underlying data source and returns it as {source, ...} (or {sources: [...]} if the record points at multiple services) — typically a fully populated WFS/WMS service with its own url, ready to navigate further. |
| Dataset | WFS, WMS, WCS, WMTS, OGC API Features/Maps/Tiles/Coverages | number, name, title, description, type, source_type, url, bbox_wgs84, crs_epsg_code, crs_name, column_count, row_count, is_ingestible, ingestibility_note, column_schema_note | The selected dataset plus a columns list describing its column schema (name, type, description). |
The response includes only the fields with meaningful values. Metadata fields such as service_health, search_active, total_matched, and search_capabilities are omitted when they have no content.
Dataset items include is_ingestible (true/false). When false, ingestibility_note provides a human-readable explanation (e.g., unsupported dataset type, invalid coordinate reference system, pixel count exceeding the limit, feature count exceeding the limit, file size exceeding the limit, or a temporarily unreachable ingestion URL). Dataset items may also include column_schema_note when the column schema could not be resolved during discovery — an informational message; ingestion may still be possible.
Nested data source items include a status_note field. When null, the source loaded normally. When non-null (for example, "Couldn't load - try again"), the Connector detected the data source but was unable to fully load it during this discovery request. In that case, data_source_count and dataset_count will be 0. Retrying discovery for the same URL will often resolve the issue.
A discovery response normally includes a service_health object. When it is left out, the health of the service could not be determined this time; that does not mean the service is down. When present, it has the following fields:
| Field | Description |
|---|---|
status | HEALTHY, DEGRADED, DOWN, HALF_OPEN, or UNKNOWN |
last_probe | ISO 8601 timestamp of the last health check (null if never checked) |
response_time_ms | Response time of the most recent health check in milliseconds (null if never checked) |
uptime_pct_7d | 7-day uptime percentage (null if insufficient data) |
uptime_pct_30d | 30-day uptime percentage (null if insufficient data) |
avg_response_ms_7d | 7-day average response time in milliseconds (null if insufficient data) |
availability | available, temporarily_unavailable, or permanently_unavailable (null if never checked) |
sql
-- Browse a WFS service
CALL SETUP.GDC_DISCOVER('navigate', PARSE_JSON('{
"url": "https://inspire-wfs.maanmittauslaitos.fi/inspire-wfs/simple",
"page": 1
}'));
-- Drill into a specific dataset
CALL SETUP.GDC_DISCOVER('navigate', PARSE_JSON('{
"url": "https://inspire-wfs.maanmittauslaitos.fi/inspire-wfs/simple",
"node_id": "au:AdministrativeBoundary"
}'));
-- Filter datasets within a service
CALL SETUP.GDC_DISCOVER('navigate', PARSE_JSON('{
"url": "https://inspire-wfs.maanmittauslaitos.fi/inspire-wfs/simple",
"q": "building"
}'));
-- Tabular output (one row per source — overview)
CALL SETUP.GDC_DISCOVER('navigate', PARSE_JSON('{
"url": "https://inspire-wfs.maanmittauslaitos.fi/inspire-wfs/simple"
}'), 'table');
-- Tabular output with drill-down (show items within source 1)
CALL SETUP.GDC_DISCOVER('navigate', PARSE_JSON('{
"url": "https://inspire-wfs.maanmittauslaitos.fi/inspire-wfs/simple",
"number": 1
}'), 'table');
-- Drill into a specific dataset (item 3 within source 1) — shows column schema as rows
CALL SETUP.GDC_DISCOVER('navigate', PARSE_JSON('{
"url": "https://inspire-wfs.maanmittauslaitos.fi/inspire-wfs/simple",
"number": 1,
"item_number": 3
}'), 'table');
-- Drill into a catalog record (item 3 within a CSW catalog) — the Connector drills
-- through the record and returns the underlying data source (e.g. the WFS service)
-- as a single row, ready to navigate further.
CALL SETUP.GDC_DISCOVER('navigate', PARSE_JSON('{
"url": "https://www.geonorge.no/geonetwork/srv/nor/csw?service=CSW&request=GetCapabilities",
"number": 1,
"item_number": 3
}'), 'table');status
Polls for the result of an asynchronous discovery request. Use this when navigate returns a ticket instead of immediate results.
| Parameter | Required | Type | Description |
|---|---|---|---|
ticket_id | Yes | string | The ticket ID returned by navigate or a previous status call |
Response: The response includes a status field:
processing— Discovery is still in progress. Wait 2–4 seconds and poll again with the sameticket_id.completed— Discovery data is ready and included in the response (same structure as an immediatenavigateresponse).failed— Discovery failed. Check theerrorfield for details.
sql
-- Poll for discovery results
CALL SETUP.GDC_DISCOVER('status', PARSE_JSON('{"ticket_id": "abc-123-def-456"}'));Empty responses
When navigate or status returns completed but the response contains no source, sources, or items, it means the Connector reached the URL but found no geospatial data sources. The response normally includes a service_health object indicating the health status of the service (when it is absent, the health could not be determined this time).
Common reasons for an empty response:
- Incorrect URL — The URL does not point to a valid OGC service. Verify the URL includes the correct service endpoint.
- Decommissioned service — The service was previously available but has been taken offline or moved to a different URL.
- Unsupported service version — The service uses an OGC protocol version that the Connector does not support.
- Network or access restrictions — The service is behind a firewall, requires authentication, or blocks external access.
In tabular output, an empty response shows a single row with STATUS and any available SERVICE_HEALTH_* columns.
Check the service_health.status field: HEALTHY or DEGRADED indicates the service was reachable but returned no datasets; DOWN suggests the service is unreachable; UNKNOWN means the service has not been checked yet, which is not a failure.
search
Searches the Connector's dataset index by keyword. Returns matching datasets ranked by relevance.
| Parameter | Required | Type | Default | Description |
|---|---|---|---|---|
q | Yes | string | — | Search query (minimum 2 characters) |
limit | No | integer | 20 | Maximum results to return |
offset | No | integer | 0 | Number of results to skip (for pagination) |
bbox | No | object | — | Geographic area filter: {"west": number, "south": number, "east": number, "north": number} in WGS 84 coordinates |
filters | No | object | — | Filter results by country or service type: {"country": "FI", "type": "WFS"}. Both fields are optional. |
Response: {results: [...], total: integer, query_info: {...}}. Each result includes a relevance score, service type, source name, a discovered field showing when the dataset was indexed (e.g., "2 days ago"), and a verified field showing when the dataset's information was last checked against the source (e.g., "3 days ago", or - if it has not yet been checked). Results also include a country field with the ISO 3166-1 alpha-2 country code of the data source, when known (omitted otherwise). The total field indicates the total number of matches (may exceed limit). The query_info object includes query (the original search query) and execution_time_ms (query duration in milliseconds). When the query mentions a geographic region, the Connector automatically uses spatial context to improve relevance.
sql
-- Search for elevation data in Finland
CALL SETUP.GDC_DISCOVER('search', PARSE_JSON('{"q": "elevation data finland", "limit": 10}'));
-- Search with geographic area filter (Helsinki region)
CALL SETUP.GDC_DISCOVER('search', PARSE_JSON('{
"q": "buildings",
"bbox": {"west": 24.5, "south": 60.1, "east": 25.2, "north": 60.4},
"limit": 10
}'));
-- Filter by country and service type
CALL SETUP.GDC_DISCOVER('search', PARSE_JSON('{
"q": "geology",
"filters": {"country": "FI", "type": "WFS"},
"limit": 10
}'));
-- Tabular output (one row per result with TOTAL column)
CALL SETUP.GDC_DISCOVER('search', PARSE_JSON('{"q": "protected areas", "limit": 5}'), 'table');URLs with query parameters
Some OGC service URLs contain & characters (e.g., ?service=CSW&request=GetCapabilities). These work without any special handling in Snowsight worksheets:
sql
-- Works in Snowsight — no escaping needed
CALL SETUP.GDC_DISCOVER('navigate', PARSE_JSON('{
"url": "https://www.geonorge.no/geonetwork/srv/nor/csw?service=CSW&request=GetCapabilities",
"page": 1
}'));
-- Tabular output — overview (1 service row)
CALL SETUP.GDC_DISCOVER('navigate', PARSE_JSON('{
"url": "https://www.geonorge.no/geonetwork/srv/nor/csw?service=CSW&request=GetCapabilities"
}'), 'table');
-- Tabular output — drill into source 1 (show items as rows)
CALL SETUP.GDC_DISCOVER('navigate', PARSE_JSON('{
"url": "https://www.geonorge.no/geonetwork/srv/nor/csw?service=CSW&request=GetCapabilities",
"number": 1
}'), 'table');
-- Tabular output — drill into catalog record 3 within source 1. Because the
-- underlying service is a CSW catalog, the Connector drills through the record
-- and returns the underlying data source (e.g. a WFS service) as a single row.
CALL SETUP.GDC_DISCOVER('navigate', PARSE_JSON('{
"url": "https://www.geonorge.no/geonetwork/srv/nor/csw?service=CSW&request=GetCapabilities",
"number": 1,
"item_number": 3
}'), 'table');If your SQL client interprets & as a variable substitution marker, use && to escape it:
sql
-- Double && escapes the ampersand in clients that use & for variable substitution
CALL SETUP.GDC_DISCOVER('navigate', PARSE_JSON('{
"url": "https://www.geonorge.no/geonetwork/srv/nor/csw?service=CSW&&request=GetCapabilities",
"page": 1
}'));Troubleshooting
SQL template rendering error with URLs
When using the Snowflake CLI (snow sql), URLs containing & characters may cause:
SQL template rendering error: 'request' is undefinedThis is a client-side variable substitution feature in the Snowflake CLI. Disable it with --enable-templating NONE:
bash
snow sql --enable-templating NONE --query "CALL SETUP.GDC_DISCOVER('navigate', PARSE_JSON('{\"url\": \"https://example.com/csw?service=CSW&request=GetCapabilities\"}'));"This does not affect Snowsight worksheets or Cortex Analyst.
See also: AI Assistant Integration — use these procedures with Snowflake CoCo or Claude Code.