List connectors
/connector
The platform catalog — visible to every role, `connector:view` included — plus this organization's own custom connectors, listed ONLY for their owner and the members a grant reaches, like connections and toolboxes: a custom connector nobody shared with the caller is absent (and `404` by slug), whatever their role — `connector:view` and `connector:manage` widen nothing, an org admin included. The filter runs inside a fill loop, so a page holds `limit` rows whenever the caller can see that many, and `next_cursor` is set only when a visible row follows (one exception: a request that examines more than 4000 consecutive hidden connectors matching one query without finding a visible one returns an empty page with a cursor so paging can continue); it is sealed (opaque), bound to the organization and to the `search`/`category`/`custom` query it was returned for, and a cursor that does not open or is replayed under another query is a `400`. A search matching only hidden connectors is otherwise an empty page with a null cursor, exactly like a search matching nothing. There is no `?visibility=org` oversight mode (removed 2026-09-04); `can_manage` on an org-owned row reflects only a real `edit` grant of their own. Platform catalog rows omit `can_manage` (no ACL concept) and carry `can_use: true`. Connectors the caller's restrictions block are RETURNED, flagged `restricted`/`restricted_by`, not filtered out — a restriction flags, a missing grant hides. `prev_cursor` is always null here.
Query Parameters
Substring match on the connector name/label.
Exact category match.
Send true to narrow to this organization's own connectors.
Response Body
Set when this connector is restricted for the caller ONLY because the connector it was forked from is — a fork inherits its upstream's restrictions on purpose (forking a blocked connector is not a bypass), but nothing was set on the fork itself, so this says where the block came from. Null when not restricted, when a rule names this connector directly, or when the lineage could not be walked. Asking for access still targets THIS connector: approving the fork's own request lifts the inherited block for that fork only. Sibling of restricted_by (which stays the precedence layer); computed server-side in the same batch as the restriction evaluation — clients must not derive it from lineage.
2 properties
The upstream's display name — null, together with slug, when the caller may not be told it. The UI then says "a connector this was forked from".
The upstream connector the restriction is inherited from. For API consumers; never render it. Null — together with label — when the caller may not be told the upstream (an org-owned upstream they hold no grant on, or one that was deleted): a slug names the connector as surely as its label does.
How the CALLER reaches this connector — not who else can. owner — they own it. direct — a grant naming them personally. team — a grant to a team they belong to (or, per §6.2, one they administer), named in access_via_team. org — an organization-wide grant. When several sources apply the BROADEST wins and the caller's access level is not consulted: owner, else org, else team, else direct. So a caller granted edit personally AND view org-wide reads org — a narrower grant must never mask org-wide exposure, since this field says how far the connector reaches, not what the caller may do with it. Deliberately NOT gated on can_see_shares, and deliberately not a widening of it: this is the caller's OWN grant and their OWN team memberships, so a view/use grantee receives it while the grantee list — information about colleagues — stays closed to them. No other member is ever named. ABSENT when nothing reaches the caller — a transfer answering the ex-owner of a resource that was never shared, or a catalog row browsed with no grant behind it. Absent means "no source to name", never "not permitted", and never an implied org.
ownerdirectteamorg
Present exactly when access_via is team, absent otherwise. The team the caller reaches this connector through — one of their own teams, never a disclosure about anybody else.
2 properties
Team id (team_…).
Team display name, or null when the team no longer resolves in the directory — the same null contract every resolved grantee name carries.
True when the connector needs a customer OAuth app (BYOA) — a placeholder client id, a real id with a placeholder secret, or a real id with no platform OAuth secret stored for it. The first two are derived from the config on the catalog summary, so they are on every row; the third comes from one cached platform-credential read.
Org-owned rows only. Whether the caller may give this ownerless connector an owner: it has no owner row AND the caller holds connector:manage. Mirrors POST /connector/{slug}/owner naming another member. Independent of the caller's reach, so a manager browsing the catalog can see that a connector needs an owner; it says nothing about who has access.
Org-owned rows only. Whether the caller may make THEMSELVES the owner: can_assign_owner AND a real edit grant of their own. connector:manage alone never makes its holder the owner of a connector nobody shared with them. Mirrors POST /connector/{slug}/owner naming the caller.
Org-owned rows only. Whether the caller may delete this connector: the owner, and only the owner, so false for everyone on an ownerless connector. Currently the same formula as can_transfer, kept as its own field so a client gates Delete on the delete question. Mirrors DELETE /connector/{slug}; the console gates its Delete on this.
Whether THIS caller may fork the connector, computed server-side so a client never re-derives it: false for a remote MCP connector (POST /connector/{slug}/fork answers 409 connector_not_forkable), for a connector the caller is restricted from, without connector:create, and when the plan does not include custom connectors. On GET /connector rows and GET /connector/{slug}.
Present only on org-owned/custom connector rows (omitted for platform catalog rows, which have no ACL concept). Whether the caller may edit this connector's config — ownership or a real edit grant of their own. connector:manage alone no longer implies this (removed 2026-09-04): org owners/admins do not manage-by-default a connector nobody explicitly shared with them.
Org-owned rows only. can_share's formula — edit access or ownership AND connector:share — a THIRD formula, distinct from can_manage: an edit grantee whose role omits connector:share can reconfigure the connector but was never meant to grant or revoke someone else's access. Mirrors DELETE /connector/{slug}/share/{aclId}.
Org-owned rows only. Whether the caller may transfer this connector — ownership, full stop; no connector:manage fallback. Mirrors POST /connector/{slug}/transfer. False for everyone on an ownerless connector (transfer needs an owner). Not the delete gate — see can_delete.
Whether the caller may create (or re-authenticate) a connection from this connector — the use floor POST /connection and POST /connection/{id}/reconnect enforce, which answers 403 connector_not_shared when it is not met. For an org-owned connector: ownership or a use-or-better grant (direct, team or org-wide). Always true on a platform catalog row, which has no ACL. This is the SHARING answer, independent of restricted: a connector shared for viewing only is listed but not connectable, and a client should leave Connect off rather than show a button that refuses. A connector nobody shared with the caller at all is not listed.
True for a connector this organization authored or forked.
remote_mcp for an organization's own bring-your-own remote MCP connector (its tools are discovered per connection, not read from the catalog), catalog for every other connector. Read it instead of guessing from the slug. On the detail, a remote MCP connector also carries remote_mcp (url, auth_mode, oauth_registration, catalog_owner, listed_tool_count — the server's count of the rows GET /connector/{slug}/tool lists to this caller with no filter, turned-off tools included for a caller who can manage the connector — and support_contact, the email or https link staff entered for a connector Elaichi publishes, null otherwise) and auth; its tool_count is the server's count of the tools that are switched on.
catalogremote_mcp
Catalog owner. Org-owned values mark this org's custom connectors. Always this string — the owning MEMBER is owner_member, a separate field, so a client never has to tell a string from an object.
The resolved owning member, the same shape as a toolbox's owner. Org-owned rows the caller reaches (ownership or a grant) only: an object when somebody OTHER than the caller owns the connector (just { id } for an owner who has left the org); null when the connector has no owner yet (an ownerless connector — see POST /connector/{slug}/owner); absent when the caller owns it (owner_user_id already says so) or reaches it by nothing but connector:view. Names come from one batched lookup per page.
object · 4 properties
The person's picture — the same one the console's user menu draws: their stored profile picture, else a Gravatar URL (d=404, 96px) derived server-side from their email (the address itself is not sent), else null. Draw initials when it is null or the image fails to load.
User id (usr_…) — same value as owner_user_id.
Owning member (usr_…), from the connector's connector_owner row. Present only on an org-owned row the caller reaches (ownership or a grant) AND that has an owner — an ownerless connector has none until POST /connector/{slug}/owner (or the creator backfill) assigns one, and a member browsing on connector:view alone is not told whose it is — such a connector is not shown to them at all (org owners/admins included). The owner is implicit edit, plus delete and transfer — the two things no share confers.
True when the caller's restrictions block this whole connector. A blocked connector is LISTED and flagged, never omitted — a picker that only got "no match" could not tell "your admin blocked it" from "that provider does not exist". It still cannot be connected: POST /connection and GET /connector/{slug}/tools refuse it.
Which precedence layer the winning rule came from, or null when nothing blocks this connector. Adds which to restricted's whether and nothing else — no rule id, author, reason or coverage. Same field and same meaning as on GET /connector/{slug} and on a connection row.
roleusernull
A hint, not a promise: true when connecting this connector is most likely a provider sign-in with nothing to fill in first — exactly one auth method, and that method can redirect (OAuth). A list row judges the auth methods only; GET /connector/{slug} also rules out a method with form fields or a permissions_text notice. A client may use it to get a popup window ready inside the click that starts a connect. direct_connect_url on the POST /connection / reconnect response stays authoritative.
Stable connector key — this is the identifier everywhere, not an id.
curl -X GET 'https://api.elaichi.ai/connector' \
-H 'Authorization: Bearer $ELAICHI_API_TOKEN' \
-H 'Content-Type: application/json'const response = await fetch('https://api.elaichi.ai/connector', {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + process.env.ELAICHI_API_TOKEN,
'Content-Type': 'application/json',
},
});
const data = await response.json();
console.log(data);import os
import requests
url = "https://api.elaichi.ai/connector"
headers = {
"Authorization": f"Bearer {os.environ['ELAICHI_API_TOKEN']}",
"Content-Type": "application/json",
}
response = requests.get(url, headers=headers)
print(response.json())