List the connectors a workspace can install AND everything it has already connected, each with a one-click install deep link.
ONE tool answers both halves of the connect question — "what can I connect to Well?" and "what is connected, still syncing, or broken?" — because every existing connection is overlaid onto its catalog row. Do NOT read workspace_connectors records to work out connection coverage; this tool is that answer.
Each entry has:
- service_id: the connector's stable catalog id (e.g. "stripe"), used in the install link.
- name, category_id, direction: what the connector is.
- data_domains: the financial domains it serves — any of "bank", "accounting", "invoicing" — or null for a non-financial connector. One connector can serve several domains (Qonto serves all three). "bank" here means the connector delivers cash movements, which a payroll or billing platform also does; do NOT read it as "this is a bank". To list banks, pass kind: "bank", which the server scopes on its own bank classification.
- status: "available" connectors are connectable now; "coming_soon"/"unavailable"/"maintenance" are not.
- is_matched / is_selected: whether this workspace's detected tools matched this connector / already picked it.
- match_score: 0..1 confidence of that match; null when unmatched. A high score is a tool Well is confident the workspace already uses.
- is_connected: this workspace has a connection you should REPAIR or MANAGE, not install fresh. True for "enabled", "processing", "error", "need_reconnect" and "suspended"; false for "to_configure" and "disabled", where a fresh install IS the right next step.
- connection_status: the existing connection's state, or null when this workspace has no connection row for the connector at all. One of:
- "enabled" — connected and syncing.
- "processing" — the grant is in and the FIRST sync is still running; data may be partial. Connected: do NOT ask the user to connect it again.
- "error" — authenticated but its last real sync failed. Offer install_url as a reconnect.
- "need_reconnect" — the grant is dead and only the user can restore it. Offer install_url as a reconnect, NOT a first install.
- "suspended" — the connection is held back administratively; tell the user it is paused. The user cannot fix it by reconnecting.
- "to_configure" — a connect attempt that never completed its handshake. Nothing is connected: offer install_url as a first install, and never claim the tool is connected.
- "disabled" — the connection was torn down. Offer install_url as a first install.
A "degraded" connector never appears: it is resolved server-side against its own sync history into "enabled" or "error", so you never surface a state that clears itself. A connection whose state this build cannot read also reports null, and there is_connected stays true — read the two fields together, and treat "null status, is_connected true" as an existing connection whose health is unknown.
- workspace_connector_id: the connection instance's id, or null when there is no connection row. This is the id well_invoke_connector_tool and well_list_connector_tools need — resolve it HERE, never via well_query_records on workspace_connectors.
- last_successful_sync_at: ISO timestamp of the last SUCCESSFUL sync, or null when none has landed yet. An "enabled" connector with null here has a valid grant but has never delivered data.
- sync_in_progress: a data sync is running right now. Tell the user to wait rather than to act.
- is_preselected: Well recommends connecting this one now (a high-confidence match with is_connected false). The interactive picker pre-checks exactly these. A "to_configure" or "disabled" row can still be pre-checked — installing it IS the fix. On kind: "accounting" at most ONE row carries it — the single highest-confidence accounting tool — because connecting the accounting software is a pick-one step; every other scope pre-checks each high-confidence match.
- install_url: a one-click link that STARTS or REPAIRS the connection in Well. It works from any state — it signs the user in if needed, creates their workspace if they have none, then runs the connector's own auth flow — and it covers banks too (a bank opens its bank-login flow pre-selected). Null only when the connector is not "available". Hand this to the user to get started in one click.
install_all_url is a TOP-LEVEL field, not a per-connector one. It is ONE link that installs every installable connector in this result that is not already connected, in the order they are listed. Its reach is wider than the per-row links: a connector the catalog holds by service id alone carries a null install_url and is still installed by this link, so never read a null install_url as "cannot be installed". When the answer offers several connectors to install, hand the user install_all_url and do NOT list the per-connector install_url links beside it — the one link IS the whole offer, and a table of links beside it puts the reader back through several sign-ins. One link carries at most 10 connectors, and install_all_omitted names the service ids it left out, so offer those rows their own install_url. install_all_url is null when the result offers nothing to install. It is null too wherever the result names no set the user has chosen: the unfiltered catalog and the whole bank domain never carry the link, and a name search or an accounting or invoicing domain carries it only while the WHOLE result fits in one link and this page holds all of it — past that the link would stand for whichever rows the page happened to carry. from_selection always carries the link, however many vendors were picked, because the user named each one. Where install_all_url is null, the rows' own install_url links ARE the offer: list them, and never announce a batch link the result does not carry.
Scoping: pass kind ("bank" | "accounting" | "invoicing") to get only the connectors serving that domain — the whole set, server-ordered, including the long tail of bank institutions. Pass q to name-search the full catalog. Omit all three for the curated, matched-first view. Use well_list_connector_tools for a live connection's actions.
Pass from_selection: true for the connect step that FOLLOWS a vendor pick: it returns ONLY the connectors behind the counterparties the user picked on the missing-invoices card this session, every installable one pre-checked, because the user already chose them. It takes no q and no kind — those browse a catalog, and this names a set already decided. An empty list means the session holds no pick for this workspace, or no picked counterparty matched a connector.
Every result carries scope — "catalog", one of the three domains, or "picked_vendors" — naming what the list IS. The card words its title from that field, so a caller must not describe the result as a domain the scope does not name.