S
supero.docs
Documentation/Connectors/Connectors Overview

Connectors Overview

Connect an external database, warehouse, file store, REST API, or webhook to a Supero project. Choose whether Supero copies the data in or reads it live at query time — your app talks to it through the exact same CRUD and query API either way.

The four-step connector wizard: Source, Discover, Review, Save
Every connector is created the same way, whatever the source: Source, Discover, Review, Save.

What Is a Connector?

A connector is a governed link from an external source into a Supero project. It knows how to reach a source (credentials, host, query), which tables or streams to expose, and how those tables map onto Supero schemas. Once a connector is set up, the data it exposes shows up as ordinary schema-backed records — your app code, the CRUD API, and the Python SDK do not need to know a record came from a connector at all.
There are exactly four connector plugins. Everything else — including every warehouse — is one of these four with a different configuration.
source.pluginConnects toHow data arrives
databasePostgreSQL (including Supabase), MySQL, SQL Server, Oracle, MongoDB, and all six analytical warehousesSynced into Supero on a trigger, or read live from the source at query time
http_apiAny REST endpoint, with pagination, retry, and six auth modesPolled into Supero on a trigger, or read live per request
csv_fileCSV, TSV, JSON, JSONL, Parquet, or Excel files on S3, SFTP, or a plain URLFetched and parsed into records on a trigger
webhookInbound pushed events, signature- or secret-verifiedWritten the moment a verified delivery arrives

ℹ️ Warehouses are not a fifth plugin

Snowflake, Databricks, ClickHouse, BigQuery, Redshift, and Microsoft Fabric all use plugin: "database" with an analytical db_type. There is no plugin: "bigquery" or plugin: "snowflake" — sending one is rejected, because plugin only accepts http_api, database, csv_file, or webhook.

ℹ️ Managed catalog first

If the third-party service you need is a supported SaaS integration (payments, email, analytics, and similar), check the services catalog (GET /api/v1/services/catalog) first — it is the primary, zero-config path for those. See API Integrations. Connectors are for your own data stores and for external HTTP, file, and warehouse sources the catalog does not model as a managed service.

Supported Sources

This is the single table to check before you plan an integration. "In console" means the source appears in a picker in the admin console today; the ones marked otherwise are fully accepted over the API and over MCP, they are just not offered as a click-to-pick tile. "Verified end to end" is how far the source has been exercised against a real remote system rather than in isolation — it is a maturity signal, not a support statement.
Sourcedb_typeIn consolesynclive_readlive_readwriteVerified end to end
PostgreSQLpostgresqlYesYesYesYesYes — the most exercised path, and the only source with a proven live_readwrite write-through
SupabasesupabaseYesYesYesYesYes — sync, live, and mixed-mode
MySQLmysqlYesYesYesYesPartly — discovery and live_read verified against a real MySQL; sync runs have not yet landed rows in a verification build, and live write-through has not been verified end to end
SQL ServermssqlYesYesYesNo — writes return 501Partly — discovery verified against a real SQL Server; sync runs have not yet landed rows in a verification build
OracleoracleNo — API and MCP onlyYesNoNoNo — never exercised against a live Oracle instance
MongoDBmongodbNo — API and MCP onlyYesNoNoNo
SnowflakesnowflakeYes (warehouse tile)Not availableYesNoYes — live warehouse reads verified against a real Snowflake account
DatabricksdatabricksYes (warehouse tile)Not availableYesNoYes — live warehouse reads verified against a real workspace
ClickHouseclickhouseNo — API and MCP onlyNot availableYesNoNo — the driver is exercised in isolation, not against a live warehouse
BigQuerybigqueryNo — API and MCP onlyNot availableYesNoNo — the driver is exercised in isolation, not against a live warehouse
RedshiftredshiftNo — API and MCP onlyNot availableYesNoNo — the driver is exercised in isolation, not against a live warehouse
Microsoft FabricfabricNo — API and MCP onlyNot availableYesNoNo — the least exercised of the six warehouses
REST API(plugin http_api)YesYesYesNoYes — sync and live reads both verified at volume
File — plain URL(plugin csv_file)YesYesNoNoYes — discovery and full sync verified against a real public file
File — Amazon S3(plugin csv_file)YesYesNoNoNo — exercised in isolation only
File — SFTP(plugin csv_file)YesYesNoNoNo — exercised in isolation only
Webhook(plugin webhook)YesYesNoNoPartly — configuration and signature verification are verified; see the caveat on inbound delivery below
db_type accepts twelve values. Six of them — oracle, mongodb, clickhouse, bigquery, redshift, and fabric — are not offered in the console picker today while they finish testing. They are not disabled: the API and the MCP tools still accept all twelve, an existing connector on one of those types keeps working, and its own type stays visible on its detail page so editing a password cannot silently retype it as something else.

⚠️ Google Cloud Storage is not a supported file source

Google Cloud Storage is not supported as a file source today. Use s3, sftp, or url. The console currently still shows a Google Cloud Storage tile in the file-source picker — do not use it; a connector created on it will fail every run.

⚠️ Inbound webhook delivery is not published on api.supero.dev today

You can create and configure a webhook connector, and its signature verification is real. The inbound receive endpoint itself is not currently published on api.supero.dev, and the console does not display the webhook URL anywhere. Contact support before you point a provider at a webhook connector, so you get a URL that actually receives.

Data Modes: Sync vs. Live Read

Every table or stream exposed by a connector picks a delivery mode independently — mode lives on target.tables[].mode, per table, not once for the whole connector. A single database connector can sync some tables into Supero while reading others live. The console asks you once, up front, and then lets you override any individual table.
ModeStorageReadsWrites
sync (default)Copied into Supero on a schedule, webhook, or manual triggerServed from the local copyFull CRUD against the local copy
live_readNone — no copy is kept in SuperoReal time, straight from the source, on every requestBlocked (writes return 403)
live_readwriteNone — no copy is kept in SuperoReal time, straight from the sourcePassed through to the source in real time
Live reads are supported for PostgreSQL (including Supabase), MySQL, and SQL Server database sources. Live write-through is narrower: it works on PostgreSQL and MySQL, while a write to a SQL Server live table is refused with 501. Warehouse sources are always live_read and never sync. An http_api source supports live_read as well — reads are proxied to the REST endpoint per request with no local copy — but not live_readwrite, since there is no generic write-back for an arbitrary REST endpoint. File and webhook sources are sync-only. Oracle and MongoDB are sync-only in practice: there is no live read path for either.

Access modes

Alongside the per-table mode, Supero stamps a connector-level access_mode on the response — an advisory summary your app can use to decide whether to show write controls for that data, and the one reliable signal that a read really came from your source. It is derived from the table modes and the source type; when a connector mixes modes across tables, the most permissive one wins.
access_modeWhat it meansSet when
syncFull CRUD against Supero’s own copy of the dataAny table is in sync mode (the default)
live-roRead-only, live from the source; writes are rejectedA non-warehouse table is set to live_read
live-rwRead and write, live, straight through to the sourceA table is set to live_readwrite
warehouseRead-only analytical queries against a warehouseA warehouse-type source is set to live_read

⚠️ Warehouses are read-only

Snowflake, Databricks, ClickHouse, BigQuery, Redshift, and Fabric connectors are analytical sources — they only ever expose live_read. Leaving mode unset on a warehouse table auto-promotes it to live_read; setting sync or live_readwrite explicitly is rejected with a 400 naming the offending table. There is no write-back path for warehouse connectors. See Warehouse Connectors.

Creating a Connector in the Admin Console

Connectors are a top-level surface in the admin console, not something buried inside a project. In the sidebar, under BUILD, open Connectors. That lands you on the connector gallery for the currently selected project. The nav entry and the page both require the schema:manage permission, so a role without it will not see the link at all.
From the gallery, Add Source opens the four-step wizard at Connect External Source. The same wizard is reachable from the connector strip on a project dashboard and from the Connectors tab on the Schemas page.
  1. 1

    Step 1 — Source

    Pick one of four source tiles: REST API, Database, CSV / File, or Webhook. Give the connector a display name, then fill in the per-source config. For a database that means database type, host, port, database, username, password, an optional schema, and a data source choice of Table or Custom SQL Query. This step also carries the Connector Mode choice — Sync (full), Sync (incremental), Live In (Read), or Live In (Read/Write) — which becomes the default mode for every table. For a warehouse there is no choice to make: the panel states that analytics warehouses are read-only and locks the connector to live read.

  2. 2

    Step 2 — Discover

    Supero inspects the source and proposes object types for the tables or streams it finds, sampling rows to infer field names and types. It runs as a job with a progress bar, and finishes by handing back a list of proposed schemas plus a suggested namespace. Nothing is created yet. If you named tables on Step 1, only those come back pre-ticked; if you left the table list empty, everything found is ticked.

  3. 3

    Step 3 — Review

    The left rail lists the discovered schemas with checkboxes; the right pane has three tabs. Fields lets you rename each column’s target field inline. Identity lets you pick which attributes derive a record’s name, and with which separator — this is what gives a live table a stable primary key. JSON is a read-only preview of exactly what will be saved. Each table also carries its own Data mode control here, so you can override the connector-level choice per table. You must select at least one schema to continue.

  4. 4

    Step 4 — Save

    Confirm the auto-generated connector ID (it warns you if it collides with an existing one), the display name, an optional description, and the schema namespace — lower-case, 2 to 24 characters, starting with a letter. Expand Tenant Routing if the source serves more than one of your tenants, and Sync Schedule to pick a cron preset or write your own five-field cron. A summary of endpoint, connector ID, target schema, namespace, schema count, and trigger sits at the bottom. Save creates the connector and its schemas together.

The connection test, and how the table list is populated

Every source type except Webhook must pass a connection test before Step 1 will let you continue. You rarely click Test yourself: the wizard re-tests automatically about a second after you stop typing in any credential field. A successful test does two things — it unblocks the step, and it returns the list of tables and views on the source, with a row estimate for each, which is what fills the Tables picker. Until the test passes, the picker shows a placeholder telling you so. Some sources report that they cannot enumerate tables up front; in that case the test still passes and the picker says the tables will be found during discovery.
If the test fails, a Skip test and proceed link appears under the footer. It lets you continue past a failing test — useful when the source is temporarily down but you know the config is right, and a genuine escape hatch when a network path is only open at run time.

⚠️ Skipping the test also skips the table expansion

The field hint says you can leave Tables empty to discover everything, and when the connection test has succeeded the wizard makes that true by expanding "empty" into the full list of tables the test returned. If you skipped the test, there is no list to expand, and a database connector saved with query_type "table" and no table_names fails at connect time on every run — it saves cleanly, discovery binds the schemas, and then each run reads zero rows. If you skip the test, name your tables explicitly.
Two connection tests: the pre-save test against the config you typed, the post-save test against stored credentials, and the lighter list indicator that can disagree with both
Trust the detail page for connectivity, and a stamped read for correctness.

⚠️ A successful wizard is provisional

If the connector service is briefly unreachable the wizard can complete and report success without having reached your source. Treat a successful wizard as provisional: before you build on a new connector, confirm with a real read that comes back with the expected access mode stamped on it. The status indicator in the connector list can also disagree with the connector’s own detail page — trust the detail page for connectivity, and a stamped read for correctness.

Limits worth knowing before you click

  • •Selecting more than 100 tables for discovery is rejected with too_many_tables_for_sampled_discovery. Select fewer, or run discovery over the API with infer_from set to "schema", which skips row sampling and scales further.
  • •Warehouse discovery samples at most 50 tables in one pass and reports that it capped in the run stats. The console does not surface that number, so on a wide warehouse, name the tables you want.
  • •A live table needs an identity. If you set a table to live_read or live_readwrite and no identity fields are chosen, Save refuses and takes you back to the Review step with that table’s Identity tab open. The five HTTP-based warehouses are exempt, because the read planner supplies its own deterministic ordering; Fabric is not exempt.
  • •A tenant-routing refusal from the backend is shown as a red list of the exact table and column pairs that caused it, with the single-tenant attestation checkbox directly underneath as the remedy.
  • •The schedule panel is hidden when a connector copies nothing — a database connector whose every table is live has nothing to schedule. Flip one table back to sync and it returns.

Source Configuration Reference

SourceConnects toDelivery modes
DatabasePostgreSQL (including Supabase), MySQL, SQL Server, Oracle, MongoDBsync everywhere; live_read for PostgreSQL, Supabase, MySQL, and SQL Server; live_readwrite for PostgreSQL, Supabase, and MySQL
WarehouseSnowflake, Databricks, ClickHouse, BigQuery, Redshift, Microsoft Fabriclive_read only
FilesCSV, TSV, JSON, JSONL, Parquet, or Excel from S3, SFTP, or a plain URLsync
HTTP APIAny REST API, with pagination and auth handlingsync; live_read (no live_readwrite)
WebhookInbound pushed events, signature- or secret-verifiedsync (event-driven)
A source is always {plugin, config}. Three payload shapes parse and all normalise onto source.config, but source.config is the one to send: it is the shape a saved connector round-trips through and the shape the API and MCP clients emit.

Database source config

json
{
  "plugin": "database",
  "config": {
    "db_type": "postgresql",
    "host": "db.example.com",
    "port": 5432,
    "database": "analytics",
    "schema": "public",
    "username": "reader",
    "password": "REDACTED",
    "query_type": "table",
    "table_names": ["orders"],
    "ssl_mode": "require",
    "batch_size": 1000
  }
}
Table selection is always a list under table_names, even for one table. query_type can be "table" (read the named tables) or "query" (run a hand-written SELECT as the source). For incremental sync add an incremental block — and note that the switch is the mode field, not a boolean: { "mode": "incremental", "cursor_column": "updated_at", "cursor_type": "datetime" }. A database source names the cursor cursor_column; an http_api source names it cursor_field. See Database Connectors for the full reference.

Warehouse source config

json
{
  "plugin": "database",
  "config": {
    "db_type": "bigquery",
    "project_id": "my-gcp-project",
    "dataset": "analytics",
    "location": "US",
    "service_account_json": "REDACTED",
    "query_type": "table",
    "table_names": ["orders"]
  }
}
Warehouse connectors use the same "database" plugin and are distinguished only by db_type — bigquery, snowflake, databricks, clickhouse, redshift, or fabric. Snowflake authenticates with a key-pair JWT or an OAuth client; BigQuery with a service account; Databricks with a personal access token or OAuth machine-to-machine; Redshift with AWS IAM; Fabric with an Entra ID service principal.

HTTP API source config

json
{
  "plugin": "http_api",
  "config": {
    "url": "https://api.example.com/data",
    "method": "GET",
    "auth": {
      "type": "api_key",
      "api_key": "YOUR_API_KEY",
      "header_name": "X-API-Key",
      "api_key_location": "header"
    },
    "pagination": { "pagination_type": "offset", "limit": 100 },
    "response": { "data_path": "results", "total_path": "count" }
  }
}
The api_key fields are flat on the auth object — api_key, header_name, and api_key_location ("header" or "query"). For api_key_location "query", name the parameter with api_key_param instead of header_name. url is the only mandatory field.

File source config

json
{
  "plugin": "csv_file",
  "config": {
    "source_type": "s3",
    "s3_bucket": "my-data-bucket",
    "s3_region": "us-east-1",
    "file_path": "exports/users/*.csv",
    "file_format": "csv",
    "csv_delimiter": ",",
    "csv_has_header": true
  }
}
CSV options are prefixed: csv_delimiter, csv_quote_char, csv_has_header, csv_encoding, csv_skip_rows. source_type accepts s3, sftp, and url; gcs and azure_blob are listed by the config type but are rejected as not implemented at run time.

Webhook source config

json
{
  "plugin": "webhook",
  "config": {
    "auth_type": "signature_hmac",
    "hmac_secret": "REDACTED",
    "hmac_header": "X-Hub-Signature-256",
    "hmac_algorithm": "sha256",
    "hmac_prefix": "sha256=",
    "payload_type": "json",
    "response_mode": "async"
  }
}

Add a Connector Over the API

The API flow mirrors the wizard: test the config, create the connector, run discovery, then confirm which tables go live and in which mode.

1. Test the source config

bash
curl -X POST https://api.supero.dev/api/v1/connectors/test-config \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "source": {
      "plugin": "database",
      "config": {
        "db_type": "postgresql",
        "host": "db.example.com",
        "port": 5432,
        "database": "analytics",
        "username": "reader",
        "password": "REDACTED"
      }
    }
  }'
test-config validates the plugin, checks required fields, and opens a real connection — without creating anything. It returns success plus a checks object (plugin_valid, config_valid, source_reachable, auth_valid) and, for most database and warehouse sources, sample_record.tables — the list of tables and views with a row estimate each. That list is the same one the console shows in its Tables picker, and there is no separate list-tables endpoint.
To re-test a connector you have already saved, pass its id as connector_id in the same request, or use POST /api/v1/connectors/{connector_id}/test, which reads the stored configuration server-side. A plain test-config carrying a config you read back from the API will fail on authentication, because credentials are masked on read and cannot be replayed.

2. Create the connector

bash
curl -X POST https://api.supero.dev/api/v1/connectors \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "orders-db",
    "source": {
      "plugin": "database",
      "config": { "db_type": "postgresql", "host": "db.example.com", "port": 5432, "database": "analytics", "username": "reader", "password": "REDACTED", "query_type": "table", "table_names": ["orders", "customers"] }
    },
    "target": { "tables": [] },
    "trigger": { "type": "manual" },
    "project_uuid": "8f14e45f-2d3a-4b1c-9e6a-1234567890ab"
  }'

ℹ️ The create response does not echo what you sent

A successful create returns the connector with source, target, and trigger as null. That is the response shape, not a sign that the configuration was dropped. GET the connector back to confirm what was stored — and do that whenever you rely on a field surviving, since credentials come back masked and any field outside the published config type may not round-trip.

3. Run discovery

Discovery inspects the source, samples rows, and proposes schemas. It is always asynchronous and returns 201 with an execution_id. The connector does not need to be enabled to run it.
bash
curl -X POST https://api.supero.dev/api/v1/connectors/{connector_id}/discover \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "streams": ["orders", "customers"], "sample_limit": 100, "timeout_seconds": 300, "infer_from": "samples" }'

# poll:
curl https://api.supero.dev/api/v1/connectors/{connector_id}/discover/{execution_id} \
  -H "Authorization: Bearer $ACCESS_TOKEN"

# then read the proposal:
curl "https://api.supero.dev/api/v1/connectors/{connector_id}/discover/{execution_id}/results?include_samples=true" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
Discovery fieldPurpose
streamsWhich tables to inspect. Omit or send null to inspect everything the source exposes.
sample_limitRows sampled per stream, 1 to 1000. Default 100.
timeout_seconds30 to 1800. Default 300.
infer_from"samples" (default) reads real rows and infers types from them. "schema" skips sampling — use it when you have more than 100 tables.
The results endpoint returns streams (columns, types, nullability, sample values), inferred_schemas, field_mappings, a suggested_namespace, inference_warnings, and samples. It returns HTTP 200 even when discovery failed — check the error and message keys rather than the status code. A discovery started while another execution is already running on the connector returns 409.

4. Confirm which tables go live

Review the proposal, then update the connector’s target.tables[] with the tables you want and each table’s mode. Leaving mode unset defaults to sync — except on a warehouse, where it is auto-promoted to live_read.
json
{
  "target": {
    "namespace": "sales",
    "tables": [
      { "schema": "order", "source": "orders", "operation": "upsert", "batch_size": 1000 },
      { "schema": "customer", "source": "public.customers", "mode": "live_read" }
    ]
  }
}
Send that as the body of a PUT to https://api.supero.dev/api/v1/connectors/{connector_id}. PUT is the only update method on this endpoint — PATCH is not routed and returns 405. A table left unconfirmed is simply not brought live; nothing is auto-created on your behalf.

The Control-Plane API

Everything the admin console does, it does through these endpoints. All of them are under https://api.supero.dev.
ActionMethod and path
Create a connectorPOST /api/v1/connectors
List connectorsGET /api/v1/connectors (add ?include_stats=true for run counts, ?project_uuid=, ?scope=domain for cross-project)
Get one connectorGET /api/v1/connectors/{connector_id}
Update a connectorPUT /api/v1/connectors/{connector_id} — the only update verb; PATCH returns 405
Delete a connectorDELETE /api/v1/connectors/{connector_id}
Enable / disablePOST /api/v1/connectors/{connector_id}/enable or /disable
Test a config before creatingPOST /api/v1/connectors/test-config
Test a saved connectorPOST /api/v1/connectors/{connector_id}/test
Start schema discoveryPOST /api/v1/connectors/{connector_id}/discover
Poll discovery progressGET /api/v1/connectors/{connector_id}/discover/{execution_id}
Read discovery resultsGET /api/v1/connectors/{connector_id}/discover/{execution_id}/results
Trigger a runPOST /api/v1/connectors/{connector_id}/run
Cancel a running executionPOST /api/v1/connectors/{connector_id}/runs/{execution_id}/cancel
Status, stats, and recent executionsGET /api/v1/connectors/{connector_id}/status?limit=10
Analytical SQL against a warehousePOST /api/v1/connectors/{connector_id}/run_query
Import a connector into another projectPOST /api/v1/connectors/{connector_id}/import
Browse the public catalogGET /api/v1/connectors/catalog
List source pluginsGET /api/v1/connector-plugins
Start an OAuth authorization-code flowGET /api/v1/connectors/{connector_id}/oauth/authorize
OAuth redirect targetGET /api/v1/connectors/oauth/callback
Refresh an OAuth tokenPOST /api/v1/connectors/{connector_id}/oauth/refresh
Check OAuth authorization stateGET /api/v1/connectors/{connector_id}/oauth/status
POST /{id}/run takes { "full_sync": false } and returns 201 with an execution_id. It requires the connector to be enabled and trigger.allow_manual not to be false, and returns 409 if an execution is already running. A run cannot be scoped to a subset of tables — it always runs the connector’s current table list.
GET /{id}/status is the one endpoint that combines enabled, status, next_run_at, last_run_at, computed stats (total_runs, success_count, failure_count, avg_duration_ms) and recent_executions with per-run records_written and records_failed. Run-level status is one of completed, partial, failed, cancelled, or timeout — a wider vocabulary than the connector-level active / paused / error.

ℹ️ GET /api/v1/connector-plugins does not list every plugin

The plugin listing endpoint currently returns only http_api, csv_file, and webhook. The database plugin and the six warehouse dialects are registered but do not appear there, so an empty result for "database" does not mean database connectors are unavailable. Take the supported-sources table on this page as authoritative instead.

⚠️ Cancel is best-effort

POST /{connector_id}/runs/{execution_id}/cancel can report that a run is not cancellable even though it is genuinely running. If that happens, let the run finish or wait for it to time out — it is reaped automatically after 15 minutes of no progress. Do not treat a failed cancel as evidence that the run already stopped.

Operating a Connector

Open a connector from the gallery and you land on its detail page, which has four tabs — Overview, Schemas, Run History, Settings — plus a fifth Query tab on an eligible warehouse connector.
ActionWhereWhat it does
Enable / disableDetail page headerA disabled connector runs nothing — no schedule, no manual run. Any execution in flight is cancelled.
Run NowDetail page header, and each gallery cardRuns the connector once, honouring the incremental watermark. Replaced by a Read-only · live chip on a connector that copies nothing.
Full Re-syncDetail page headerRuns once ignoring the incremental watermark and re-pulls everything.
Run HistoryRun History tabThe last 50 executions: status, trigger type, when, duration, and records written. A live-only connector says so instead of showing an empty table.
Per-table settingsSettings › Tables & RoutingPer table: data mode, target schema, identity fields, operation (upsert / insert / update), batch size, and on-error behaviour (skip / fail).
Re-discoverSettings › Source TablesSaves first, then re-runs discovery for the selected tables. It starts the job and returns immediately — check Run History to see whether it finished.
Connect AccountOverview tabOnly for an http_api connector using the OAuth authorization-code flow. Redirects to the provider, then returns with the token stored. The banner also offers Refresh Token and Reconnect.
QueryQuery tabAd-hoc read-only SQL against a warehouse connector. Appears only when the connector attests a read-only role. See Warehouse Connectors.
DeleteSettings › Danger ZoneRemoves the connector. Read the warning below first.

🚨 Deleting a connector also deletes its object types

Deleting a connector also removes the object types it created, and the data in them. Export anything you need first. This is not limited to synced rows — the schemas themselves are removed, so anything stored against them goes with them.

Scheduling

A trigger is one of three types. manual runs only when you call the run endpoint. schedule runs on a five-field cron in a timezone you choose. webhook runs when a verified delivery arrives. Whatever the type, allow_manual (default true) also lets you fire an on-demand run.
WhereWhat you can set
Wizard, Step 4A cron preset — every 10 minutes, every 30 minutes, hourly, every 6 hours, daily at 02:00, weekly Monday 02:00 — or a free-text five-field cron plus a timezone.
Settings › Schedule / TriggerTrigger type, cron, timezone, timeout in minutes (1–1440), max records per execution, max errors before the run fails, and allow_manual.
Settings › Schedule / Trigger, incremental connectors onlyreconcile_cron — a second, less frequent cron that ignores the incremental watermark and re-pulls everything to repair drift. It can only be set here, never in the wizard.
A cron must have exactly five whitespace-separated fields. A six-field "with seconds" cron is rejected before the request is sent, and an invalid cron blocks the save rather than silently downgrading the connector to manual.

⚠️ Confirm a scheduled run actually happened

A schedule you set may not run in every environment. Confirm a run actually happened in Run History before depending on the cron; contact support if it has not. A connector whose cron cannot fire also comes back from the API with next_run_at set to null and a validation warning explaining why — the console does not display that warning today, so check the field over the API if a schedule looks inert.

Scoping a Live Source by Tenant

If a live-read or live-readwrite source holds data for more than one of your tenants in the same table (a shared org_id column, for example), add a tenant_binding to that table so each tenant only ever sees its own rows.
json
{
  "schema": "customer",
  "source": "public.customers",
  "mode": "live_read",
  "live": {
    "tenant_binding": {
      "mode": "column",
      "tenant_field": "org_id",
      "tenant_value_map": { "acme": "42", "globex": "77" },
      "on_unmapped_tenant": "deny"
    }
  }
}
tenant_binding.modeBehavior
fixedThe whole connector belongs to one tenant — no per-row filtering needed.
columnRows are filtered by tenant_field, mapped from your Supero tenant to the source’s value via tenant_value_map.

⚠️ Fails closed

A tenant with no entry in tenant_value_map is denied by default (on_unmapped_tenant: "deny") — an unrecognized tenant never falls through to seeing unfiltered data. See Live Data, Read-Only & Security for the full isolation model.

ℹ️ The wizard writes a fixed binding

The console’s Tenant Routing panel collects a tenant field for sync routing, but a table created as live through the wizard is always saved with a fixed tenant binding — the panel says so itself. To use column-based tenant scoping on a live table, set the binding over the API with a PUT.

Using Connector-Backed Data in Your App

This is the point of the transparent design: once a table is confirmed, its records are just another schema type as far as your app is concerned. You read and write them through the same CRUD and query endpoints you would use for any Supero-native data.
bash
curl https://api.supero.dev/api/v1/crud/acme-corp/customer?limit=20 \
  -H "Authorization: Bearer $ACCESS_TOKEN"

curl -X POST https://api.supero.dev/api/v1/crud/acme-corp/query \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "type": "customer", "filters": {"org_id": "acme"} }'
filters is a flat map of field to value, not a list of comparison objects. See Querying & Pagination for the full query surface.
python
import supero

org = supero.connect(domain_name="acme-corp", api_key="ak_...")

# Works the same whether "customer" is a native schema or a live-read connector table
customers = org.crud.list("customer", limit=20)
recent = org.crud.query("customer").filter(org_id="acme").order_by("-created_at").all()

⚠️ Writes on read-only sources

create/update/delete calls against a table whose access_mode is live-ro or warehouse are rejected with 403 — your app can check access_mode up front to decide whether to show edit controls for that type.

Public Catalog: Zero-Setup Connectors

For quick prototyping or demo data, the public catalog is a curated list of well-known public REST APIs — currently 18 entries across categories like Finance & Markets, Crypto, News, Jobs, Government & Open Data, Health & Science, Maps & Places, Reference, Entertainment, and Commerce & Demo. Selecting an entry pre-fills a working http_api source config, so discovery can infer a usable schema without you writing one by hand. In the console it lives behind Public Connectors on the first step of the wizard.
bash
curl "https://api.supero.dev/api/v1/connectors/catalog?category=Crypto" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
Auth modeWhat it means
noneNo key required — the connector works immediately.
byoYou supply your own key; the catalog form tells you which field it fills.
Examples in the catalog include CoinGecko, Alpha Vantage, Hacker News, NewsAPI, Remotive Jobs, USGS Earthquakes, REST Countries, Open-Meteo, TMDB, and DummyJSON. Every catalog entry is a plain http_api connector once created, so it can be edited, scheduled, and re-pointed like any other. They are created as sync connectors; if you want one to serve live reads instead, set the table mode yourself after creation.

Ownership, Status, and Security Posture

A connector belongs to a domain and is linked to one or more projects via project_uuid / project_refs. Importing lets a second project reuse the same connector (and, optionally, its discovered schemas) instead of configuring the source twice — re-importing an already-linked connector is a harmless no-op. In the console, Import from other projects is on the first step of the wizard, and is available to platform and domain administrators.
statusMeaning
activeRunning normally / available for use.
pausedDisabled — scheduled and manual runs do not execute.
errorThe last run or connectivity check failed.

Security posture

  • •Secrets — database passwords, API keys, warehouse tokens — are stored server-side and are never echoed back in a GET or list response; fields that look like a credential (password, api_key, token, service_account, and similar) are masked before the response reaches your browser. That is also why a config you read back cannot be replayed into test-config.
  • •Connection tests and live REST reads only reach publicly routable hosts. Targets that resolve to a private, loopback, link-local, or cloud-metadata address are rejected before any connection is attempted.
  • •A source outage on a resolved live binding returns an error (502/503) rather than an empty result set. There is one narrow exception where a live-backed type can return 200 with zero rows without reaching your source — check the access_mode stamp rather than the row count. See Live Data, Read-Only & Security.
  • •An unmapped field on a live-read query fails closed with a 4xx error rather than silently dropping a filter or scoping predicate.

Next Steps