Rings AI
Relationship intelligence
- Category
- Sales & CRM
- Primary Subcategory
- Investor & Deal-Flow Relationship CRM
Integration details
Description
Rings AI lets users work with private relationship intelligence from their Rings tenant in ChatGPT. Users can look up people and companies, inspect activities, notes, meetings, opportunities, PathPower, recommended paths, and AI summaries, and create or update permitted Rings records such as tasks, notes, people, companies, and opportunities.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- Investor & Deal-Flow Relationship CRM
- Secondary Subcategories
- None listed
- Brand
- Rings AI
- Access
- Account required
- First tracked
- 2026-06-30
- Tool count
- 64
- Geography
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Get alerts for Rings AI
Get updates when Rings AI’s Discoverability Score or category rank changes.
ChatGPT Plugin Discovery Score
ChatGPT Plugin discovery is coming soon
ChatGPT can surface a Plugin when it matches a user's request.Your Plugin Discovery Score measures how often yours appears.
No spam. Unsubscribe any time.
What discovery looks like

Competing in ChatGPT Investor & Deal-Flow Relationship CRM
View Category64 tools agents can invoke
Each UUID joins with `entity_kind` = the list's own `kind` — a list is single-kind, so no per-entity kind is accepted. Idempotent: a UUID that is already a member is left untouched and omitted from the response's `entity_uuids`, which reports only the memberships this call created. Returns 404 when the list doesn't exist for the API key's tenant, and 409 when the list's membership is rule-owned (a dynamic list whose members Rings updates automatically, which would undo a manual edit).
post_add_entity_list_members
Idempotent on duplicates: if the association already exists the existing row is returned (still status 201 for client simplicity — matches the opportunity association sub-endpoint).
post_add_note_association
entity_type must be one of (uppercase): PERSON, COMPANY, NOTE, FILE, TASK, OPPORTUNITY. Unlike notes/tasks, OPPORTUNITY-to-OPPORTUNITY associations are allowed. Rejects with 404 when the opportunity or target entity doesn't exist for this tenant. Idempotent on duplicate associations — returns the existing association row rather than erroring.
post_add_opportunity_association
Links a person, company, note, file, or opportunity to the task. TASK-to-TASK links are not allowed. Returns 201 with the association record; if an identical association already exists the existing record is returned (idempotent). Returns 404 if the task is not visible to the caller. entity_type must be one of: PERSON, COMPANY, NOTE, FILE, OPPORTUNITY.
post_add_task_association
Each entry in `queries` is resolved independently using the same matching semantics as `GET /v1/companies/lookup`. Results are returned in the same order as the input.
post_lookup_companies_batch
Each entry in `queries` is matched independently using the same semantics as `GET /v1/persons/lookup` (email, linkedin_url, or domain match). Results are returned in the same order as the input queries. Entries with no matching criteria return empty matches rather than an error.
post_lookup_persons_batch
Dedupe: if the payload's `linkedin_url` or `website` matches an existing tenant-visible company (incl. Crunchbase / Rings Research globals), that record's UUID is reused so the tenant row converges onto the canonical entity instead of forking a duplicate. If no match is found, the downstream write generates a fresh UUID.
post_create_company
`entity_uuids`, if provided, are added as members at creation time (same `entity_kind` as the list's `kind`). List names are unique per tenant per `kind` — returns 409 if `name` is already in use for that `kind`.
post_create_entity_list
The full HTML `content` is stored with the note; a plain-text excerpt is also saved for list and search results. `associations` are guarded the same way as `POST /v1/notes/batch`: if a target entity can't be resolved yet (e.g. a person created moments earlier that isn't visible to this endpoint yet), the note is NOT created and the request fails with 409 and a retryable message — rather than creating the note with the association silently dropped.
post_create_note
associations and optional per-note idempotency. Each entry is created independently using the same path as `POST /v1/notes` (full body, excerpt, owner and inline `associations`). A single failing row comes back as status ERROR without sinking the rest of the batch; results are returned in input order. Supplying `idempotency_key` per note makes the import safely re-runnable: re-submitting the same key returns the existing note (status SKIPPED) instead of creating a duplicate. This is the note half of the bulk import flow — create the people first via `POST /v1/persons/batch`, then attach their notes here. A person/company created moments earlier may not yet be visible to this endpoint — newly written records become readable after a short sync delay. If a note's association can't be resolved, that note is NOT created and is returned with status ERROR and a retryable message — wait briefly for the entity to sync, then re-submit the same `idempotency_key`.
post_create_notes_batch
Required fields: name, type_uuid, stage_uuid. If the user hasn't specified an opportunity type or stage, ask them before calling this endpoint. To discover valid IDs, first call GET /v1/opportunity-types to choose a type_uuid (and inspect its pinning_config to learn whether a person/company association is required), then call GET /v1/opportunity-types/{type_uuid}/stages to choose a stage_uuid for that type. A stage_uuid is only valid for the type_uuid it belongs to. Optional: details, value, probability, source_date, intro_date, close_date, intro_person_uuid, owner_user_uuid, associations (to link persons/companies). owner_user_uuid takes a user uuid from GET /v1/users; the person uuid an existing opportunity reports under `owner` is accepted too. Defaults to the calling user. An owner that resolves to neither returns 400. Returns the new opportunity UUID and timestamps on success (201).
post_create_opportunity
All fields are optional. If the provided `email` matches an existing person in the tenant, the existing record is updated in place and its UUID is returned (deduplication by email). Returns the UUID and rings_updated_at timestamp on success.
post_create_person
Creates a task and optionally assigns it to users and associates it with entities (persons, companies, opportunities, etc.) in a single atomic operation. Returns the new task id on success. Enum values (case-sensitive, uppercase): - status: DRAFT | ACTIVE | COMPLETED | ARCHIVED (default: ACTIVE) - priority: LOW | MEDIUM | HIGH - visibility: RING (all tenant members) | PERSONAL (creator only, default: RING) - reminder_type: MINUTES | HOURS | DAYS | WEEKS (requires reminder_value)
post_create_task_endpoint
Only the note's owner or a ringmaster may delete it. Returns 204 on success, 404 when the note isn't visible to the caller's tenant, and 403 when the caller is neither the owner nor a ringmaster.
delete_delete_note
Returns 204 on success and 404 when the association doesn't exist or doesn't belong to the referenced note.
delete_delete_note_association
Removes the caller's tenant-scoped opportunities for the given UUIDs, cascades to their sub-opportunities (deleting a parent deletes every descendant in the same ring), then deletes any associations that reference the removed rows (as either the association parent or the associated entity). The cascade only ever touches rows and associations for UUIDs actually deleted from this tenant's ring, so a UUID belonging to another tenant can't have its associations wiped even if it's included in the request. UUIDs that don't resolve to a tenant-scoped opportunity are silently skipped (not an error) -- `deleted_count` reports how many opportunities were actually removed, including cascaded sub-opportunities. Always returns 200, even when `deleted_count` is 0. Returns 400 if more than 100 UUIDs are submitted in one request (the cap applies to the requested UUIDs, not the cascade).
delete_delete_opportunities
Returns 204 on success, 404 if the association doesn't exist or doesn't belong to the referenced opportunity.
delete_delete_opportunity_association
`current_company` reads as null afterward. Returns 204 on success (including when the person had no current company to begin with), and 404 if the person UUID is not visible to your tenant.
delete_remove_current_company
Removes membership only — the companies or persons themselves are untouched. Idempotent: a UUID that isn't currently a member is omitted from the response's `entity_uuids`, which reports only the memberships this call removed. Returns 404 when the list doesn't exist for the API key's tenant, and 409 when the list's membership is rule-owned (a dynamic list whose members Rings updates automatically, which would restore the entity).
delete_remove_entity_list_members
PERSONAL tasks can only be deleted by their creator; RING tasks can be deleted by any tenant member.
delete_delete_task_endpoint
Returns 404 when the association doesn't exist or doesn't belong to the given task.
delete_delete_task_association
Delegates to the GraphQL `emailBody` resolver core (undecorated) so access control (grant ownership + explicit EmailAccessPermission) is enforced in exactly one place. Returns: - 404 when the activity / message can't be resolved for the caller - 403 when the caller has no active grant for the activity's owner
get_get_activity_body
Scoped to the caller's tenant. Only emails are returned — calendar events don't belong to a thread. The response is metadata-only. Clients render a thread by fetching this list and then calling `/activities/{id}/body` for whichever messages they want to expand. Applies the same participant-or-delegated-access check as `/body`, so it is not a fallback when `/body` returns 404. Returns: - 403 without user context - 404 when the caller may not read this activity, it does not exist, or it has no thread
get_get_activity_thread
Parameters: - entity: person | company (required) - uuids: comma-separated list of entity UUIDs (max 100) Returns a score entry for every UUID in the input list. UUIDs with no PathPower data are included with score=null and strength_label=null. When score is present, strength_label is one of: weak, moderate, strong, very_strong (lowercase, underscore-separated PathPower bands).
get_get_bulk_pathpower
Returns the full company record including: - strongest_relationships: top 2 internal team members with the strongest connection into the company (use for "who internally knows Acme" without needing recommended-paths) - pathpower: overall relationship strength score (0.0-1.0) - next_meeting_at / my_next_meeting_at: the next scheduled meeting with anyone at the company, tenant-wide and for the calling user - last_activity_date, entity list memberships, industry tags, Rings AI operating and investor scores, custom field values, location and social URLs. Returns 404 if the company is not visible to your tenant.
get_get_company
Generates a live summary using the same pipeline as the web app. Returns 404 when the entity is not found.
get_get_company_ai_summary
Returns a paginated list of emails and calendar meetings where any participant is associated with the company, ordered by date descending. Filter parameters: - type: email | meeting — omit to return both - date_from: ISO date (YYYY-MM-DD), inclusive - date_to: ISO date (YYYY-MM-DD), inclusive Pagination: - page: Page number (default: 1) - per_page: Results per page (default: 10) - include_total: return total/total_is_approximate (default: false)
get_get_company_activities
"who internally knows people at this company" / "best path into" queries. Returns internal team members ranked by connection strength to people at the target company, each with 2-hop relationship paths. Use this to find who on the team can make introductions at a specific company. Each result includes the connector's name, relationship quality (rq), and the path hops linking them to contacts at the company. The response also carries a top-level `top_external_contacts` array — the company's top 5 external contacts ranked by PathPower, each with their role `tags` and two strongest internal connectors. This array is independent of pagination.
get_get_company_recommended_paths
Designed for MCP and AI agent clients that need to resolve "me", "my", or "I" into concrete UUIDs before calling other endpoints (e.g. fetching activity history or relationship data for the current user). Returns null fields when the API key is tenant-scoped with no user context.
get_get_me
Requires user context: the meeting is only returned when the calling user is an internal participant on it.
get_get_meeting
Tenant-scoped. Returns the full HTML body; if the body is temporarily unavailable the response falls back to the excerpt rather than erroring.
get_get_note
Returns the complete opportunity including stage, type, owner, intro person, associated persons and companies, custom fields, days in current stage, notes/files count, and activity dates. Returns 404 if the opportunity is not visible in the tenant's ring. Each associated person/company carries `city`, `state` and `country`, so an opportunity's geography can be read off the record itself instead of looking every association up individually.
get_get_opportunity
Each item records one move: `from_stage` -> `to_stage`, the timestamp it happened (`entered_at`), when the opportunity left that stage again (`exited_at`, null while it is still there), and how long it sat there (`days_in_stage`). The first transition of an opportunity has a null `from_stage` — that is the opportunity being created in its initial stage, not a move out of an unknown stage. Use this to answer pipeline-velocity questions ("how long did this deal spend in each stage", "where did it stall") that the point-in-time `days_in_stage` on `GET /v1/opportunities/{uuid}` can't. Stage names are resolved for stages that still exist in the tenant; a stage deleted since the transition returns its UUID with a null `name`. The full stage list for a type is available from `GET /v1/opportunity-types/{type_uuid}/stages`. Works for sub-opportunities as well as top-level ones. Returns 404 if the opportunity is not visible in the tenant's ring.
get_get_opportunity_stage_history
Returns the full person record including: - strongest_relationships: top 2 internal team members with the strongest connection to this person (use for "who internally knows X" without needing recommended-paths) - pathpower: overall relationship strength score (0.0–1.0) - priority_management.rq: the canonical relationship quality score (1–3, null when no signal exists). Ignore rq_manual and rq_math — use rq as the single source of truth. - Secondary emails, phone numbers, entity list memberships, company affiliation. Returns 404 if the person is not visible to your tenant.
get_get_person
Generates a live summary using the same pipeline as the web app. Returns 404 when the entity is not found.
get_get_person_ai_summary
Returns a paginated list of emails and calendar meetings where the person was a participant, ordered by date descending. Each item includes participants, from/to addresses (for emails), start/end times (for meetings), and attachment counts. Filter parameters: - type: email | meeting — omit to return both - date_from: ISO date (YYYY-MM-DD), inclusive - date_to: ISO date (YYYY-MM-DD), inclusive Pagination: - page: Page number (default: 1) - per_page: Results per page (default: 10) - include_total: return total/total_is_approximate (default: false)
get_get_person_activities
"who knows this person" / "introduce me to" / "path to" queries. Returns internal team members ranked by connection strength, each with 2-hop relationship paths showing how they connect to the target person. Use this instead of PathPower when you need actual introduction paths, not just a score. Each result includes the connector's name, relationship quality (rq), and the path hops linking them to the target.
get_get_person_recommended_paths
Returns the full task including assignments. PERSONAL tasks are only returned for their creator; RING tasks are visible to any tenant member. Returns 404 when the task doesn't exist or isn't visible to the caller.
get_get_task_endpoint
Returns a paginated list of companies visible to the tenant. All filter parameters are optional — omitting all of them returns all companies. Filters compose with AND; comma-separated values within a single filter are OR-matched. See each parameter for exact semantics. Filters cover identity (`name`, `domain`, `linkedin_url`, `description`, social URLs), location (`city`, `state`, `country`), status (`operating_status`, `acquisition_status`, `ipo_status`), industry tags, investor and funding attributes, and numeric/date ranges (founding year, employee count, Rings scores, investment dates). Use `uuids` (comma-separated) to hydrate a known set of companies in one call — this is the batched counterpart to `GET /v1/companies/{uuid}`. To resolve a company you only know by domain or name, use `GET /v1/companies/lookup` instead. Sort parameters: - sort_by: name | last_activity_date (default: unsorted) - order: asc | desc (default: asc) Pagination: - page: Page number (default: 1) - per_page: Results per page, max 50 (default: 10) - after: Opaque cursor from a previous response's `next_cursor`. Resumes immediately after that response's last record, so concurrent writes can't shift rows between pages the way `page` allows. `total` is not computed on this path — use `has_more`. Every response carries `next_cursor`, including page-numbered ones, so a caller can start with `page` and switch to cursors mid-scan.
get_list_companies
Company reads return custom field values in `company_custom_fields`, keyed by each field's `key` (e.g. `sector_1697011571764_3`), not its `uuid`. Use this to find out what each key means — its display `name`, `type` and, for selects, the allowed `choices` — and to find the `key` to write a value under. Definitions rarely change, so fetch them once rather than per company.
get_list_company_custom_fields
Use `GET /v1/companies?uuids=...` or `GET /v1/persons?uuids=...` to hydrate the returned UUIDs into full records, depending on the list's `kind` (from `GET /v1/lists`). `city`, `state` and `country` filter members by where they are based — "who on this list is in LA" in one call, instead of paging every member and hydrating each one to check. They AND together. Members with no location on record are excluded when a location filter is set.
get_list_entity_list_members
Filter parameters (all optional): - name: Exact (case-sensitive) name match - search: Case-insensitive substring search on name - kind: PERSON or COMPANY
get_list_entity_lists
Only meetings where the user appears as an internal calendar participant (same scope as in-app meeting tools) are returned. Supports filtering by date range, participant person/company, and title search. Results are sorted by start time descending (most recent first).
get_list_meetings
Supports: - `entity_uuid` + `entity_type`: notes associated with that entity. - `search`: full-text search across the note's subject and body. - Standard pagination, `sort_by`, `order`. Body content is intentionally omitted from the list view; fetch individual notes to get the HTML. The `excerpt` field is always populated.
get_list_notes
Returns a paginated list of opportunities visible to the tenant ring. Filter parameters (all optional): - name: Case-insensitive substring match on the opportunity's own name - search: Search name and associated person/company names. All words must match, in any order; falls back to fuzzy matching when nothing does. Does not search the opportunity type label - opportunity_type_uuid: Filter by opportunity type UUID (use GET /v1/opportunities to inspect `type.uuid` on existing records) - opportunity_stage_uuid: Filter by a single stage UUID - opportunity_stage_uuids: Comma-separated stage UUIDs (IN filter) - owner_user_uuid: Comma-separated owner UUID(s); accepts either a user UUID or the person UUID shown as `owner.uuid` on a record. Returns 400 if none of them resolve to a user in this tenant - include_no_owner: Widens owner_user_uuid to also match opportunities with no owner; no effect unless owner_user_uuid is set - has_owner: true for only owned opportunities, false for only unassigned ones; omit for both - intro_person_uuid: Filter by the intro person's UUID - related_company_uuid / related_person_uuid: parent opportunities that have a sub-opportunity associated with this entity - parent_uuid: Return only sub-opportunities of this parent UUID - hierarchy_type: 'PARENT' or 'CHILD' (ignored if parent_uuid is set) - company_uuid / person_uuid: Comma-separated UUID(s); union of opportunities associated with any of them - city / state / country: Where an associated person or company is based — this is how you answer "which of my deals are in LA". They AND together and must all match the same associated entity. Spell the state out ('Florida'), or pass a two-letter code with `country` ('FL' + 'US'); a code alone returns 400, since unscoped 'FL' resolves to Flintshire, GB - value_from / value_to, probability_from / probability_to: inclusive range filters - updated_after / updated_before: ISO 8601 date/datetime range on updated_at - source_date_from / source_date_to: ISO 8601 dates, required together - close_date_from / close_date_to: ISO 8601 dates, required together; opportunities with no close_date are excluded - last_activity_date_from / last_activity_date_to: ISO 8601 datetimes, required together Sort parameters: - sort_by: name | created_at | updated_at | value | weighted_value | probability | source_date | intro_date | close_date | last_activity_date | details | next_step | stage | owner | intro_person | days_in_stage | notes_and_files_count - order: asc | desc (default: asc) Pagination: - page: Page number (default: 1) - per_page: Results per page (default: 10) The response also includes `total_value`/`total_weighted_value`: sums of `value`/`weighted_value` across the full filtered set, not just the page.
get_list_opportunities
Answers "what is each stage of this pipeline worth" without paginating the opportunities themselves: one request returns count, value, and weighted value per group instead of one filtered list request per stage. Grouping: - group_by: STAGE | TYPE | OWNER | COMPANY | PERSON | ASSOCIATIONS - group_by_2: optional second dimension for a cross-tab. Only STAGE paired with OWNER is supported today; any other pairing returns 400. Filtering uses the same parameters as GET /v1/opportunities, so the same filters describe the same set of opportunities on both endpoints — except that the grouped rollup excludes opportunities sitting in a hidden stage (a stage toggled off in the stage editor), which the flat list still returns. For a pipeline breakdown, pass the parent opportunity's UUID as `parent_uuid`. Sorting: - sort_by: count | total_value | total_weighted_value | average_probability | group_label. Defaults to count, descending. - order: asc | desc Per group the response carries `count`, `total_value`, `total_weighted_value`, `average_probability`, and the `children_*` rollup of sub-opportunities. `average_days_in_stage` and `stalled_count` are only computed when `include_stage_metrics=true`, since computing them across the whole filtered set is slower. Two caveats worth knowing: - COMPANY, PERSON, and ASSOCIATIONS grouping fan a single opportunity out across every entity it is associated with, so per-group sums double-count and the `children_*` fields stay 0 to avoid compounding it. - `total`, `page`, and `per_page` describe groups, not opportunities, while `total_value`/`total_weighted_value` at the top level are deduplicated sums across the whole filtered set.
get_list_opportunities_grouped
Use this to find the `uuid` of a field before setting it on create or update, including fields no opportunity has a value for yet. Each field has its `uuid`, `key`, display `name`, `type` and, for selects, the allowed `choices`. `standard_key_to_uuid` maps the 16 standard web-app column keys (e.g. `targetSize`) to this tenant's field uuids. Definitions rarely change, so fetch them once rather than on every opportunity read.
get_list_opportunity_custom_fields
Use this to discover a valid `stage_uuid` before creating an opportunity. Pass `stage_type=PARENT` (default) for top-level opportunities or `stage_type=CHILD` for sub-opportunities. A stage is only valid when paired with the `type_uuid` it belongs to.
get_list_opportunity_stages
Use this to discover a valid `type_uuid` before creating an opportunity. Each item's `pinning_config` declares whether a person/company association is required for that type. To get the matching `stage_uuid`, call GET /v1/opportunity-types/{type_uuid}/stages.
get_list_opportunity_types
Returns a paginated list of people visible to the tenant. All filter parameters are optional — omitting all of them returns all persons. Filter parameters: - name: Case-insensitive substring match on person's display name - email: Exact match on primary email address - linkedin_url: Case-insensitive substring match on LinkedIn profile URL - modified_since: ISO 8601 timestamp — return only persons modified at or after this time (e.g. '2025-01-01T00:00:00Z') Sort parameters: - sort_by: name | last_activity_date (default: unsorted) - order: asc | desc (default: asc) Pagination: - page: Page number (default: 1) - per_page: Results per page, max 100 (default: 50)
get_list_persons
How do I improve a ChatGPT Plugin's discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
What are Rings AI alternatives on ChatGPT?
As of 2026-09-29, Rings AI competes with 4Degrees, 4Degrees - KSA, Affinity, MadeMarket in ChatGPT Investor & Deal-Flow Relationship CRM, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.