{"openapi":"3.1.0","info":{"title":"Lunar Atlas API","version":"v1","description":"Agent-vendor-neutral REST API for the Lunar Atlas catalog. The web UI walks through it. Agents walk through it. Single source of truth for every read and every write. See https://lunaratlas.dev/api for interactive docs.","contact":{"name":"Lunar Rails","url":"https://lunaratlas.dev"}},"servers":[{"url":"https://lunaratlas.dev/api/v1","description":"Production"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Atlas Agent API key. Minted by an admin/curator from /dashboard/team. Keys are scoped (read:atlas, read:people, read:proposals, write:proposals, read:gtm, write:gtm, write:sources), budgeted, revocable, and auditable."}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","retryable"],"properties":{"code":{"type":"string","enum":["VALIDATION_ERROR","UNAUTHORIZED","FORBIDDEN","NOT_FOUND","CONFLICT","RATE_LIMITED","BUDGET_EXHAUSTED","INTERNAL"]},"message":{"type":"string"},"hint":{"type":"string"},"retryable":{"type":"boolean"},"doc_url":{"type":"string","format":"uri"}}}}},"Segment":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string","example":"miners"},"name":{"type":"string","example":"Miners"},"description":{"type":"string","nullable":true},"parent_id":{"type":"string","format":"uuid","nullable":true},"sort_order":{"type":"integer"},"hue_token":{"type":"string","nullable":true},"focus_kind":{"type":"string","enum":["core","context"],"description":"core = one of the four primary Lunar Rails operating segments (Mining, Corporate Treasuries, Lightning, Family Offices); context = supporting ecosystem terrain."}}},"Capability":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string","example":"custody","description":"Stable lowercase slug. Use this value in propose endpoints, never the display name."},"name":{"type":"string","example":"Institutional Custody"},"description":{"type":"string","nullable":true},"horizon":{"type":"string","enum":["now","near","future"],"description":"Default Lunar Rails timeline for this capability. Agents may override per entity via the lr_fit horizon field."},"sort_order":{"type":"integer"}}},"Need":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"primary_capability_id":{"type":"string","format":"uuid","nullable":true}}},"Vertical":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"segment_hint_id":{"type":"string","format":"uuid","nullable":true},"sort_order":{"type":"integer"}}},"TaxonomyTerm":{"type":"object","description":"Stable agent-facing taxonomy term. Use slug values in filters and proposal payloads.","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string","example":"lightning.wallets.custodial"},"name":{"type":"string","example":"Custodial Lightning Wallets"},"description":{"type":"string","nullable":true},"kind":{"type":"string","enum":["segment","subsegment","product_category","capability","protocol","geography","lifecycle","risk","custom"]},"parent_id":{"type":"string","format":"uuid","nullable":true},"sort_order":{"type":"integer"},"status":{"type":"string","enum":["active","deprecated"]},"replaced_by":{"type":"object","nullable":true,"properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"}}}}},"FieldEvent":{"type":"object","description":"Event-planning record for conferences, summits, meetups, roadshows, and other field-intel surfaces. Agents with trusted GTM scopes can create events and attach segments, entities, and people.","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string","example":"btc-prague-2026"},"name":{"type":"string","example":"BTC Prague 2026"},"event_kind":{"type":"string","enum":["conference","summit","meetup","side_event","roadshow","webinar","other"]},"starts_at":{"type":"string","format":"date","nullable":true},"ends_at":{"type":"string","format":"date","nullable":true},"city":{"type":"string","nullable":true},"country":{"type":"string","nullable":true},"venue":{"type":"string","nullable":true},"website_url":{"type":"string","format":"uri","nullable":true},"priority":{"type":"string","enum":["must_attend","high","medium","watch","skip"]},"lifecycle_status":{"type":"string","enum":["researching","planning","outreach","booked","attended","follow_up","skipped"]},"strategic_reason":{"type":"string","nullable":true},"outreach_goal":{"type":"string","nullable":true},"notes_md":{"type":"string","nullable":true},"segments":{"type":"array","items":{"type":"object","properties":{"relevance":{"type":"string","nullable":true},"segment":{"$ref":"#/components/schemas/Segment"}}}},"entities":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"role":{"type":"string"},"outreach_status":{"type":"string"},"relationship_note":{"type":"string","nullable":true},"next_step":{"type":"string","nullable":true},"meeting_target":{"type":"boolean"},"entity":{"type":"object","additionalProperties":true}}}},"people":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"role":{"type":"string"},"outreach_status":{"type":"string"},"relationship_note":{"type":"string","nullable":true},"next_step":{"type":"string","nullable":true},"meeting_target":{"type":"boolean"},"person":{"type":"object","additionalProperties":true}}}},"goals":{"type":"array","items":{"$ref":"#/components/schemas/FieldEventGoal"}},"interactions":{"type":"array","items":{"$ref":"#/components/schemas/FieldEventInteraction"}},"followUps":{"type":"array","items":{"$ref":"#/components/schemas/FieldEventFollowUp"}},"scorecard":{"anyOf":[{"$ref":"#/components/schemas/FieldEventScorecard"},{"type":"null"}]},"roster":{"type":"array","items":{"$ref":"#/components/schemas/FieldEventRosterCandidate"},"description":"Agent-discovered roster candidates staged for this event — see the roster endpoints below."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"FieldEventInput":{"type":"object","required":["name"],"properties":{"slug":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*$","example":"btc-prague-2026"},"name":{"type":"string","minLength":2,"maxLength":160},"event_kind":{"type":"string","enum":["conference","summit","meetup","side_event","roadshow","webinar","other"],"default":"conference"},"starts_at":{"type":"string","format":"date","nullable":true},"ends_at":{"type":"string","format":"date","nullable":true},"city":{"type":"string","nullable":true},"country":{"type":"string","nullable":true},"venue":{"type":"string","nullable":true},"website_url":{"type":"string","format":"uri","nullable":true},"priority":{"type":"string","enum":["must_attend","high","medium","watch","skip"],"default":"watch"},"lifecycle_status":{"type":"string","enum":["researching","planning","outreach","booked","attended","follow_up","skipped"],"default":"researching"},"strategic_reason":{"type":"string","nullable":true,"maxLength":2000},"outreach_goal":{"type":"string","nullable":true,"maxLength":1200},"notes_md":{"type":"string","nullable":true,"maxLength":8000}}},"FieldEventEntityLinkInput":{"type":"object","required":["role"],"properties":{"entity_id":{"type":"string","format":"uuid"},"entity_slug":{"type":"string","example":"river-financial"},"role":{"type":"string","enum":["attending","sponsor","speaker","host","side_event_host","target_customer","prospect","partner","competitor","media","other"]},"outreach_status":{"type":"string","enum":["research","to_contact","contacted","meeting_requested","meeting_booked","met","follow_up","no_action"],"default":"research"},"relationship_note":{"type":"string","nullable":true},"next_step":{"type":"string","nullable":true},"meeting_target":{"type":"boolean","default":false}}},"FieldEventPersonLinkInput":{"type":"object","required":["role"],"properties":{"person_id":{"type":"string","format":"uuid"},"person_slug":{"type":"string"},"role":{"type":"string","enum":["attending","speaker","organizer","host","warm_intro","target_contact","relationship_owner","other"]},"outreach_status":{"type":"string","enum":["research","to_contact","contacted","meeting_requested","meeting_booked","met","follow_up","no_action"],"default":"research"},"relationship_note":{"type":"string","nullable":true},"next_step":{"type":"string","nullable":true},"meeting_target":{"type":"boolean","default":false}}},"FieldEventSegmentLinkInput":{"type":"object","properties":{"segment_id":{"type":"string","format":"uuid"},"segment_slug":{"type":"string","example":"lightning"},"relevance":{"type":"string","nullable":true}}},"FieldEventsProposalRequest":{"type":"object","required":["event"],"properties":{"event":{"$ref":"#/components/schemas/FieldEventInput"},"segments":{"type":"array","maxItems":20,"items":{"$ref":"#/components/schemas/FieldEventSegmentLinkInput"},"description":"Segments to tag the event with. Each entry needs segment_id or segment_slug."},"entities":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/FieldEventEntityLinkInput"},"description":"Known entities attending/sponsoring/etc. Each entry needs entity_id or entity_slug."},"people":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/FieldEventPersonLinkInput"},"description":"Known people attending/speaking/etc. Each entry needs person_id or person_slug."},"unmatched_entities":{"type":"array","maxItems":100,"items":{"type":"string","maxLength":200},"description":"Free-text entity names the agent couldn't resolve to a catalog entity. Carried for curator review, not auto-created."},"unmatched_people":{"type":"array","maxItems":100,"items":{"type":"string","maxLength":200},"description":"Free-text person names the agent couldn't resolve to a catalog person. Carried for curator review, not auto-created."},"match_rationale":{"type":"string","maxLength":2000,"description":"Why these segments/entities/people were matched to this event."},"sources":{"type":"array","maxItems":20,"description":"Optional evidence URLs carried as evidence_sources on each normalized change.","items":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"},"title":{"type":"string","maxLength":200},"trust_tier":{"type":"string","enum":["public","reputable","private","rumor"]},"note":{"type":"string","maxLength":1000}}}}}},"FieldEventGoal":{"type":"object","description":"Structured, trackable outcome for a field event (e.g. \"Book 3 treasury custody meetings\").","properties":{"id":{"type":"string","format":"uuid"},"field_event_id":{"type":"string","format":"uuid"},"title":{"type":"string","example":"Book 3 treasury custody meetings"},"metric":{"type":"string","nullable":true,"example":"Meetings booked"},"target_value":{"type":"number","nullable":true},"progress_value":{"type":"number","nullable":true},"owner_profile_id":{"type":"string","format":"uuid","nullable":true},"status":{"type":"string","enum":["on_track","at_risk","achieved","missed","dropped"]},"due_date":{"type":"string","format":"date","nullable":true},"notes":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"FieldEventGoalInput":{"type":"object","required":["title"],"properties":{"title":{"type":"string","minLength":2,"maxLength":200},"metric":{"type":"string","nullable":true,"maxLength":200},"target_value":{"type":"number","nullable":true},"progress_value":{"type":"number","nullable":true},"status":{"type":"string","enum":["on_track","at_risk","achieved","missed","dropped"],"default":"on_track"},"due_date":{"type":"string","format":"date","nullable":true},"notes":{"type":"string","nullable":true,"maxLength":2000}}},"FieldEventGoalPatchInput":{"type":"object","description":"All fields optional; at least one is required.","properties":{"title":{"type":"string","minLength":2,"maxLength":200},"metric":{"type":"string","nullable":true,"maxLength":200},"target_value":{"type":"number","nullable":true},"progress_value":{"type":"number","nullable":true},"status":{"type":"string","enum":["on_track","at_risk","achieved","missed","dropped"]},"due_date":{"type":"string","format":"date","nullable":true},"notes":{"type":"string","nullable":true,"maxLength":2000}}},"FieldEventInteraction":{"type":"object","description":"One concrete meeting/touchpoint at a field event.","properties":{"id":{"type":"string","format":"uuid"},"field_event_id":{"type":"string","format":"uuid"},"entity_id":{"type":"string","format":"uuid","nullable":true},"person_id":{"type":"string","format":"uuid","nullable":true},"counterpart_name":{"type":"string","nullable":true},"counterpart_context":{"type":"string","nullable":true},"scheduled_at":{"type":"string","format":"date-time","nullable":true},"location":{"type":"string","nullable":true},"purpose":{"type":"string","nullable":true},"owner_profile_id":{"type":"string","format":"uuid","nullable":true},"status":{"type":"string","enum":["planned","booked","completed","missed","cancelled"]},"outcome_notes":{"type":"string","nullable":true},"signal_strength":{"type":"string","enum":["none","weak","moderate","strong"]},"next_step":{"type":"string","nullable":true},"entity":{"type":"object","nullable":true,"additionalProperties":true},"person":{"type":"object","nullable":true,"additionalProperties":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"FieldEventInteractionInput":{"type":"object","description":"One of entity_id/entity_slug, person_id/person_slug, or counterpart_name is required.","properties":{"entity_id":{"type":"string","format":"uuid"},"entity_slug":{"type":"string"},"person_id":{"type":"string","format":"uuid"},"person_slug":{"type":"string"},"counterpart_name":{"type":"string","nullable":true,"maxLength":160},"counterpart_context":{"type":"string","nullable":true,"maxLength":1000},"scheduled_at":{"type":"string","format":"date-time","nullable":true},"location":{"type":"string","nullable":true,"maxLength":200},"purpose":{"type":"string","nullable":true,"maxLength":1000},"status":{"type":"string","enum":["planned","booked","completed","missed","cancelled"],"default":"planned"},"outcome_notes":{"type":"string","nullable":true,"maxLength":4000},"signal_strength":{"type":"string","enum":["none","weak","moderate","strong"],"default":"none"},"next_step":{"type":"string","nullable":true,"maxLength":1000}}},"FieldEventInteractionPatchInput":{"type":"object","description":"All fields optional; at least one is required.","properties":{"entity_id":{"type":"string","format":"uuid","nullable":true},"entity_slug":{"type":"string"},"person_id":{"type":"string","format":"uuid","nullable":true},"person_slug":{"type":"string"},"counterpart_name":{"type":"string","nullable":true,"maxLength":160},"counterpart_context":{"type":"string","nullable":true,"maxLength":1000},"scheduled_at":{"type":"string","format":"date-time","nullable":true},"location":{"type":"string","nullable":true,"maxLength":200},"purpose":{"type":"string","nullable":true,"maxLength":1000},"status":{"type":"string","enum":["planned","booked","completed","missed","cancelled"]},"outcome_notes":{"type":"string","nullable":true,"maxLength":4000},"signal_strength":{"type":"string","enum":["none","weak","moderate","strong"]},"next_step":{"type":"string","nullable":true,"maxLength":1000}}},"FieldEventFollowUp":{"type":"object","description":"Post-meeting or post-event action item. May link back to the interaction it came out of.","properties":{"id":{"type":"string","format":"uuid"},"field_event_id":{"type":"string","format":"uuid"},"interaction_id":{"type":"string","format":"uuid","nullable":true},"entity_id":{"type":"string","format":"uuid","nullable":true},"person_id":{"type":"string","format":"uuid","nullable":true},"owner_profile_id":{"type":"string","format":"uuid","nullable":true},"action_text":{"type":"string"},"follow_up_type":{"type":"string","enum":["email","call","meeting","intro","proposal","internal","other"]},"destination":{"type":"string","nullable":true,"example":"bd@example.com"},"due_date":{"type":"string","format":"date","nullable":true},"status":{"type":"string","enum":["open","in_progress","done","cancelled"]},"completed_at":{"type":"string","format":"date-time","nullable":true},"entity":{"type":"object","nullable":true,"additionalProperties":true},"person":{"type":"object","nullable":true,"additionalProperties":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"FieldEventFollowUpInput":{"type":"object","required":["action_text"],"properties":{"interaction_id":{"type":"string","format":"uuid","nullable":true},"entity_id":{"type":"string","format":"uuid"},"entity_slug":{"type":"string"},"person_id":{"type":"string","format":"uuid"},"person_slug":{"type":"string"},"action_text":{"type":"string","minLength":2,"maxLength":500},"follow_up_type":{"type":"string","enum":["email","call","meeting","intro","proposal","internal","other"],"default":"other"},"destination":{"type":"string","nullable":true,"maxLength":200},"due_date":{"type":"string","format":"date","nullable":true},"status":{"type":"string","enum":["open","in_progress","done","cancelled"],"default":"open"}}},"FieldEventFollowUpPatchInput":{"type":"object","description":"All fields optional; at least one is required. Setting status to \"done\" without an explicit completed_at stamps completed_at with the current time.","properties":{"entity_id":{"type":"string","format":"uuid","nullable":true},"entity_slug":{"type":"string"},"person_id":{"type":"string","format":"uuid","nullable":true},"person_slug":{"type":"string"},"action_text":{"type":"string","minLength":2,"maxLength":500},"follow_up_type":{"type":"string","enum":["email","call","meeting","intro","proposal","internal","other"]},"destination":{"type":"string","nullable":true,"maxLength":200},"due_date":{"type":"string","format":"date","nullable":true},"status":{"type":"string","enum":["open","in_progress","done","cancelled"]}}},"FieldEventScorecard":{"type":"object","description":"Curator-entered qualitative post-event verdict and 30/90-day review state. Quantitative metrics (goal achievement, meeting completion, signals captured, follow-up completion) are derived on read from goals/interactions/follow-ups elsewhere, never stored here.","properties":{"field_event_id":{"type":"string","format":"uuid"},"verdict":{"type":"string","enum":["strong","mixed","weak","too_early"],"nullable":true},"verdict_notes":{"type":"string","nullable":true},"review_30_completed_at":{"type":"string","format":"date-time","nullable":true},"review_30_notes":{"type":"string","nullable":true},"review_90_completed_at":{"type":"string","format":"date-time","nullable":true},"review_90_notes":{"type":"string","nullable":true},"team_time_hours":{"type":"number","nullable":true},"cost_amount":{"type":"number","nullable":true},"cost_currency":{"type":"string","nullable":true,"example":"USD"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"FieldEventScorecardPatchInput":{"type":"object","description":"All fields optional; at least one is required. Upserted — PATCH creates the scorecard row if it doesn't exist yet.","properties":{"verdict":{"type":"string","enum":["strong","mixed","weak","too_early"],"nullable":true},"verdict_notes":{"type":"string","nullable":true,"maxLength":4000},"review_30_completed_at":{"type":"string","format":"date-time","nullable":true},"review_30_notes":{"type":"string","nullable":true,"maxLength":4000},"review_90_completed_at":{"type":"string","format":"date-time","nullable":true},"review_90_notes":{"type":"string","nullable":true,"maxLength":4000},"team_time_hours":{"type":"number","nullable":true},"cost_amount":{"type":"number","nullable":true},"cost_currency":{"type":"string","nullable":true,"maxLength":10}}},"FieldEventRosterCandidate":{"type":"object","description":"Agent-discovered roster candidate for a field event — a sponsor, exhibitor, speaker, organizer, host, media contact, attendee, partner, target, or competitor found while researching the event. Event-scoped staging only; never a canonical entity/person until promoted through /v1/agents/proposals/entity or /v1/agents/proposals/person.","properties":{"id":{"type":"string","format":"uuid"},"field_event_id":{"type":"string","format":"uuid"},"candidate_type":{"type":"string","enum":["entity","person","unknown"]},"role":{"type":"string","enum":["sponsor","exhibitor","speaker","organizer","host","media","attendee","partner","target","competitor","other"]},"display_name":{"type":"string"},"context":{"type":"string","nullable":true,"description":"Organization, title, or other free-text context."},"source_url":{"type":"string","format":"uri","nullable":true},"evidence_note":{"type":"string","nullable":true},"confidence":{"type":"integer","minimum":1,"maximum":5},"review_status":{"type":"string","enum":["unreviewed","matched","promoted","dismissed"]},"matched_entity_id":{"type":"string","format":"uuid","nullable":true},"matched_person_id":{"type":"string","format":"uuid","nullable":true},"matched_entity":{"type":"object","nullable":true,"additionalProperties":true},"matched_person":{"type":"object","nullable":true,"additionalProperties":true},"meeting_target":{"type":"boolean"},"outreach_status":{"type":"string","enum":["research","to_contact","contacted","meeting_requested","meeting_booked","met","follow_up","no_action"]},"relationship_note":{"type":"string","nullable":true},"next_step":{"type":"string","nullable":true},"external_ref":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"FieldEventRosterCandidateInput":{"type":"object","required":["role","display_name"],"properties":{"external_ref":{"type":"string","nullable":true,"maxLength":200,"description":"Optional stable id from the source (e.g. the conference site's own sponsor/speaker slug) for precise re-ingestion matching."},"candidate_type":{"type":"string","enum":["entity","person","unknown"],"default":"unknown"},"role":{"type":"string","enum":["sponsor","exhibitor","speaker","organizer","host","media","attendee","partner","target","competitor","other"]},"display_name":{"type":"string","minLength":1,"maxLength":200},"context":{"type":"string","nullable":true,"maxLength":1000},"source_url":{"type":"string","format":"uri","nullable":true},"evidence_note":{"type":"string","nullable":true,"maxLength":2000,"description":"Why the agent believes this — quote, page section, etc."},"confidence":{"type":"integer","minimum":1,"maximum":5,"default":3},"matched_entity_id":{"type":"string","format":"uuid"},"matched_entity_slug":{"type":"string"},"matched_person_id":{"type":"string","format":"uuid"},"matched_person_slug":{"type":"string"},"meeting_target":{"type":"boolean","default":false},"outreach_status":{"type":"string","enum":["research","to_contact","contacted","meeting_requested","meeting_booked","met","follow_up","no_action"],"default":"research"},"relationship_note":{"type":"string","nullable":true,"maxLength":1000},"next_step":{"type":"string","nullable":true,"maxLength":1000}}},"FieldEventRosterBulkInput":{"type":"object","required":["candidates"],"properties":{"candidates":{"type":"array","minItems":1,"maxItems":200,"items":{"$ref":"#/components/schemas/FieldEventRosterCandidateInput"},"description":"Up to 200 candidates per call. Split larger rosters across multiple POSTs."}}},"FieldEventRosterPatchInput":{"type":"object","description":"All fields optional; at least one is required. Setting matched_entity_id/slug or matched_person_id/slug clears the other match and, unless review_status is also given, auto-advances review_status to \"matched\".","properties":{"role":{"type":"string","enum":["sponsor","exhibitor","speaker","organizer","host","media","attendee","partner","target","competitor","other"]},"display_name":{"type":"string","minLength":1,"maxLength":200},"candidate_type":{"type":"string","enum":["entity","person","unknown"]},"context":{"type":"string","nullable":true,"maxLength":1000},"source_url":{"type":"string","format":"uri","nullable":true},"evidence_note":{"type":"string","nullable":true,"maxLength":2000},"confidence":{"type":"integer","minimum":1,"maximum":5},"review_status":{"type":"string","enum":["unreviewed","matched","promoted","dismissed"]},"matched_entity_id":{"type":"string","format":"uuid","nullable":true},"matched_entity_slug":{"type":"string"},"matched_person_id":{"type":"string","format":"uuid","nullable":true},"matched_person_slug":{"type":"string"},"meeting_target":{"type":"boolean"},"outreach_status":{"type":"string","enum":["research","to_contact","contacted","meeting_requested","meeting_booked","met","follow_up","no_action"]},"relationship_note":{"type":"string","nullable":true,"maxLength":1000},"next_step":{"type":"string","nullable":true,"maxLength":1000}}},"ProposalSummary":{"type":"object","description":"Slim proposal row for list views.","properties":{"id":{"type":"string","format":"uuid"},"source":{"type":"string","enum":["fathom","gmail","voice_memo","manual","agent"]},"source_ref":{"type":"string","nullable":true},"status":{"type":"string","enum":["pending","accepted","rejected","unmatched"]},"target_entity":{"type":"object","nullable":true,"properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"}}},"match_confidence":{"type":"integer","nullable":true},"match_rationale":{"type":"string","nullable":true},"change_count":{"type":"integer"},"change_kinds":{"type":"array","items":{"type":"string"},"description":"Distinct change kinds in proposed_changes."},"applied_indices":{"type":"array","items":{"type":"integer"},"description":"Which indices into proposed_changes the curator applied."},"decision_notes":{"type":"string","nullable":true},"reviewed_at":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"}}},"ProposalDetail":{"allOf":[{"$ref":"#/components/schemas/ProposalSummary"},{"type":"object","properties":{"proposed_changes":{"type":"array","items":{"type":"object"},"description":"Full change payloads. Each item carries a `kind` discriminator plus kind-specific fields."}}}]},"SourceSummary":{"type":"object","description":"A source row backing an entity's Dossier. Audio, decks, transcripts, conversation notes, and public URL references. trust_tier signals how cite-able the source is.","properties":{"id":{"type":"string","format":"uuid"},"external_ref":{"type":"string","nullable":true},"kind":{"type":"string","enum":["transcript","deck","conversation","public_url","research","addendum"]},"title":{"type":"string"},"description":{"type":"string","nullable":true},"trust_tier":{"type":"string","enum":["public","reputable","private","rumor"]},"mime_type":{"type":"string","nullable":true},"size_bytes":{"type":"integer","nullable":true},"url":{"type":"string","nullable":true},"has_file":{"type":"boolean"},"is_referenceable":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"}}},"SegmentBreadcrumb":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"}}},"EntitySegmentMembership":{"type":"object","properties":{"is_primary":{"type":"boolean"},"segment":{"allOf":[{"$ref":"#/components/schemas/SegmentBreadcrumb"}],"description":"The specific segment membership row; child segments can appear here as secondary memberships."},"path":{"type":"array","items":{"$ref":"#/components/schemas/SegmentBreadcrumb"},"description":"Breadcrumb from top-level parent to this segment."},"display_path":{"type":"string","example":"Custody → Collaborative Custody"}}},"EntitySegmentResolution":{"type":"object","description":"Canonical segment resolution for agents and UI: top-level placement, optional child breadcrumb, all memberships, taxonomy terms, and a display path.","properties":{"entity_id":{"type":"string","format":"uuid"},"primary_top_level_segment":{"allOf":[{"$ref":"#/components/schemas/SegmentBreadcrumb"}],"nullable":true},"subsegment_breadcrumb":{"type":"array","items":{"$ref":"#/components/schemas/SegmentBreadcrumb"}},"all_segment_memberships":{"type":"array","items":{"$ref":"#/components/schemas/EntitySegmentMembership"}},"taxonomy_terms":{"type":"array","items":{"type":"object"}},"display_path":{"type":"string","nullable":true,"example":"Custody → Collaborative Custody"}}},"EntitySummary":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"ticker":{"type":"string","nullable":true},"country":{"type":"string","nullable":true},"region":{"type":"string","nullable":true},"city":{"type":"string","nullable":true},"is_public":{"type":"boolean"},"posture":{"type":"string","enum":["producer","holder","allocator","service_provider","merchant","institution","infrastructure"],"nullable":true},"competitive_posture":{"type":"string","enum":["incumbent","competitor","partner","complement","whitespace","not_applicable"],"nullable":true},"one_liner":{"type":"string","nullable":true},"logo_url":{"type":"string","nullable":true},"website_url":{"type":"string","nullable":true},"x_url":{"type":"string","nullable":true},"linkedin_url":{"type":"string","nullable":true},"github_url":{"type":"string","nullable":true},"nostr_url":{"type":"string","nullable":true},"crunchbase_url":{"type":"string","nullable":true},"strategic_importance":{"type":"integer","nullable":true},"opportunity_thesis":{"type":"string","nullable":true},"buying_trigger":{"type":"string","nullable":true},"trust_blocker":{"type":"string","nullable":true},"next_action":{"type":"string","nullable":true},"opportunity_owner":{"type":"string","nullable":true},"opportunity_rationale":{"type":"string","nullable":true},"show_opportunity_card":{"type":"boolean","description":"Curator-controlled opt-in for rendering the R2 / Opportunity Card on the entity page."},"relationship_status":{"type":"string","enum":["cold","warm","active","client","alumnus"],"nullable":true},"last_verified_at":{"type":"string","format":"date-time","nullable":true},"updated_at":{"type":"string","format":"date-time"},"created_at":{"type":"string","format":"date-time"},"segment":{"type":"object","nullable":true,"properties":{"slug":{"type":"string"},"name":{"type":"string"}}},"segment_resolution":{"$ref":"#/components/schemas/EntitySegmentResolution"}}},"EntityListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/EntitySummary"}},"next_cursor":{"type":"string","nullable":true},"total":{"type":"integer","nullable":true}}},"ManagementCoverageEntity":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"country":{"type":"string","nullable":true},"region":{"type":"string","nullable":true},"city":{"type":"string","nullable":true},"segment":{"type":"object","nullable":true,"properties":{"slug":{"type":"string"},"name":{"type":"string"}}}}},"ManagementCoverageCheck":{"type":"object","properties":{"kind":{"type":"string","enum":["missing_country","missing_city","missing_key_people","missing_relationship_path","missing_sources"]},"label":{"type":"string"},"complete":{"type":"integer"},"missing":{"type":"integer"},"coverage_pct":{"type":"number"}}},"AgentWorkItem":{"type":"object","properties":{"id":{"type":"string","example":"missing_key_people:river-financial"},"kind":{"type":"string","enum":["missing_country","missing_city","missing_key_people","missing_relationship_path","missing_sources"]},"priority":{"type":"string","enum":["high","medium"]},"entity":{"$ref":"#/components/schemas/ManagementCoverageEntity"},"reason":{"type":"string"},"suggested_endpoint":{"type":"string"},"expected_proposal_kind":{"type":"string"}}},"AgentWorkQueue":{"type":"object","properties":{"slug":{"type":"string","example":"people-gaps"},"name":{"type":"string","example":"Key People Gaps"},"description":{"type":"string"},"kinds":{"type":"array","items":{"type":"string","enum":["missing_country","missing_city","missing_key_people","missing_relationship_path","missing_sources"]}}}},"ManagementCoverage":{"type":"object","properties":{"generated_at":{"type":"string","format":"date-time"},"filters":{"type":"object","properties":{"segment":{"type":"string","nullable":true},"tag":{"type":"string","nullable":true},"include_children":{"type":"boolean"}}},"total_entities":{"type":"integer"},"checks":{"type":"array","items":{"$ref":"#/components/schemas/ManagementCoverageCheck"}},"gaps":{"type":"object","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/ManagementCoverageEntity"}}},"work_items":{"type":"array","items":{"$ref":"#/components/schemas/AgentWorkItem"}}}},"ProposalTarget":{"type":"object","description":"Every write endpoint accepts either a UUID or a slug. Provide one. match_rationale is optional human-readable context for the inbox card.","properties":{"target_entity_id":{"type":"string","format":"uuid"},"target_entity_slug":{"type":"string","example":"marathon-digital"},"match_rationale":{"type":"string"}}},"LrFitSuggestion":{"type":"object","required":["capability_slug","horizon","fit_score"],"properties":{"capability_slug":{"type":"string","example":"custody"},"horizon":{"type":"string","enum":["now","near","future","partner"]},"fit_score":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string"}}},"ProviderSuggestion":{"type":"object","required":["capability_slug"],"properties":{"capability_slug":{"type":"string","example":"custody"},"provider_entity_id":{"type":"string","nullable":true},"provider_name":{"type":"string","nullable":true},"confidence":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string"}}},"RelationshipSuggestion":{"type":"object","required":["related_entity_id","relationship_type"],"properties":{"related_entity_id":{"type":"string","description":"UUID or slug of another catalog entity"},"relationship_type":{"type":"string","enum":["custody","liquidity","payment","infra","capital","integration","partnership","adjacency"]},"description":{"type":"string"},"confidence":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string"}}},"EventSuggestion":{"type":"object","required":["occurred_at","event_kind","headline"],"properties":{"occurred_at":{"type":"string","example":"2026-05-12"},"event_kind":{"type":"string","example":"integration_announced"},"headline":{"type":"string","maxLength":200},"body":{"type":"string","nullable":true},"confidence":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string"}}},"LrFitProposalRequest":{"allOf":[{"$ref":"#/components/schemas/ProposalTarget"},{"type":"object","required":["suggestions"],"properties":{"suggestions":{"type":"array","items":{"$ref":"#/components/schemas/LrFitSuggestion"},"minItems":1,"maxItems":10}}}]},"ProvidersProposalRequest":{"allOf":[{"$ref":"#/components/schemas/ProposalTarget"},{"type":"object","required":["suggestions"],"properties":{"suggestions":{"type":"array","items":{"$ref":"#/components/schemas/ProviderSuggestion"},"minItems":1,"maxItems":10}}}]},"RelationshipsProposalRequest":{"allOf":[{"$ref":"#/components/schemas/ProposalTarget"},{"type":"object","required":["suggestions"],"properties":{"suggestions":{"type":"array","items":{"$ref":"#/components/schemas/RelationshipSuggestion"},"minItems":1,"maxItems":10}}}]},"EventsProposalRequest":{"allOf":[{"$ref":"#/components/schemas/ProposalTarget"},{"type":"object","required":["events"],"properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/EventSuggestion"},"minItems":1,"maxItems":20}}}]},"EntityFieldUpdates":{"type":"object","description":"Curator-reviewed field patch for an existing entity dossier. `scale_patch` merges into the existing entity.scale object instead of replacing it.","minProperties":1,"properties":{"one_liner":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"logo_url":{"type":"string","nullable":true},"website_url":{"type":"string","nullable":true},"x_url":{"type":"string","nullable":true},"linkedin_url":{"type":"string","nullable":true},"github_url":{"type":"string","nullable":true},"nostr_url":{"type":"string","nullable":true},"crunchbase_url":{"type":"string","nullable":true},"strategic_importance":{"type":"integer","minimum":1,"maximum":5},"show_opportunity_card":{"type":"boolean","description":"Opt in to rendering the entity R2 / Opportunity Card. Leave false for ecosystem-context records."},"scale_patch":{"type":"object","additionalProperties":true,"description":"Sparse patch for page-specific scale facts, e.g. treasury_btc, sovereign_btc, auc_usd_band, lightning_capacity_btc."}}},"BundleChange":{"oneOf":[{"type":"object","required":["kind","capability_slug","horizon","fit_score"],"properties":{"kind":{"type":"string","enum":["suggest_lr_fit"]},"capability_slug":{"type":"string"},"horizon":{"type":"string","enum":["now","near","future","partner"]},"fit_score":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string"}}},{"type":"object","required":["kind","capability_slug"],"properties":{"kind":{"type":"string","enum":["add_provider"]},"capability_slug":{"type":"string"},"provider_entity_id":{"type":"string","nullable":true},"provider_name":{"type":"string","nullable":true},"confidence":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string"}}},{"type":"object","required":["kind","related_entity_id","relationship_type"],"properties":{"kind":{"type":"string","enum":["suggest_relationship"]},"related_entity_id":{"type":"string"},"relationship_type":{"type":"string","enum":["custody","liquidity","payment","infra","capital","integration","partnership","adjacency"]},"description":{"type":"string"},"confidence":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string"}}},{"type":"object","required":["kind","occurred_at","event_kind","headline"],"properties":{"kind":{"type":"string","enum":["add_event"]},"occurred_at":{"type":"string"},"event_kind":{"type":"string"},"headline":{"type":"string"},"body":{"type":"string","nullable":true},"confidence":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string"}}},{"type":"object","required":["kind","field_updates"],"description":"Propose updating reader-facing dossier fields for the existing target entity. Applies only after curator approval.","properties":{"kind":{"type":"string","enum":["update_entity_fields"]},"field_updates":{"$ref":"#/components/schemas/EntityFieldUpdates"},"confidence":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string"}}},{"type":"object","required":["kind","append_text"],"properties":{"kind":{"type":"string","enum":["update_notes"]},"append_text":{"type":"string"},"confidence":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string"}}},{"type":"object","required":["kind","status"],"properties":{"kind":{"type":"string","enum":["set_relationship_status"]},"status":{"type":"string","enum":["cold","warm","active","client","alumnus"]},"confidence":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string"}}},{"type":"object","required":["kind","person"],"description":"Propose a new key person. In the same bundle, attach_person_role may reference this new person by person.slug.","properties":{"kind":{"type":"string","enum":["create_person"]},"person":{"type":"object","required":["slug","name"],"properties":{"slug":{"type":"string","pattern":"^[a-z0-9-]+$"},"name":{"type":"string"},"aliases":{"type":"array","items":{"type":"string"}},"country":{"type":"string","nullable":true},"city":{"type":"string","nullable":true},"bio_md":{"type":"string","nullable":true},"avatar_url":{"type":"string","nullable":true},"website_url":{"type":"string","nullable":true},"x_url":{"type":"string","nullable":true},"linkedin_url":{"type":"string","nullable":true},"github_url":{"type":"string","nullable":true},"nostr_url":{"type":"string","nullable":true},"posture_toward_lr":{"type":"string","nullable":true,"description":"Short useful context: why this person matters to Lunar Rails."},"importance_score":{"type":"integer","minimum":1,"maximum":5},"notes":{"type":"string","nullable":true}}},"confidence":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string"}}},{"type":"object","required":["kind","target_person_slug_or_id","person"],"description":"Propose updates to an existing person. Curator-only fields like next_action and trust_blocker are intentionally not accepted from agents.","properties":{"kind":{"type":"string","enum":["update_person"]},"target_person_slug_or_id":{"type":"string"},"person":{"type":"object","properties":{"name":{"type":"string"},"aliases":{"type":"array","items":{"type":"string"}},"country":{"type":"string","nullable":true},"city":{"type":"string","nullable":true},"bio_md":{"type":"string","nullable":true},"avatar_url":{"type":"string","nullable":true},"website_url":{"type":"string","nullable":true},"x_url":{"type":"string","nullable":true},"linkedin_url":{"type":"string","nullable":true},"github_url":{"type":"string","nullable":true},"nostr_url":{"type":"string","nullable":true},"posture_toward_lr":{"type":"string","nullable":true},"importance_score":{"type":"integer","minimum":1,"maximum":5},"notes":{"type":"string","nullable":true}}},"confidence":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string"}}},{"type":"object","required":["kind","taxonomy_term_slug"],"description":"Propose assigning the target entity to an agent-facing taxonomy term such as lightning.wallets.custodial.","properties":{"kind":{"type":"string","enum":["assign_taxonomy_term"]},"taxonomy_term_slug":{"type":"string","example":"lightning.wallets.custodial"},"confidence":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string"}}},{"type":"object","required":["kind","segment_slug"],"description":"Propose moving the target entity into a primary segment, optionally with a subsegment. Use GET /segments first; if the segment doesn't exist, propose it via POST /agents/proposals/segments.","properties":{"kind":{"type":"string","enum":["update_entity_segment"]},"segment_slug":{"type":"string","example":"self-custody-wallets"},"subsegment_slug":{"type":"string","nullable":true},"confidence":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string"}}},{"type":"object","required":["kind","lifecycle_status","reason"],"description":"Recommend a curator-reviewed lifecycle change for the target entity. Agents cannot delete entities; use false_positive or archived to recommend removal from active Atlas surfaces, or defunct for out-of-business entities.","properties":{"kind":{"type":"string","enum":["suggest_entity_lifecycle"]},"lifecycle_status":{"type":"string","enum":["active","defunct","archived","false_positive"]},"reason":{"type":"string"},"confidence":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string"}}},{"type":"object","required":["kind"],"description":"Propose explicit opportunity fields for the target entity. The curator accepts these before they become canonical. Include at least one field; use opportunity_rationale for the source-backed reasoning behind the proposed read.","properties":{"kind":{"type":"string","enum":["suggest_entity_opportunity"]},"opportunity_thesis":{"type":"string","nullable":true},"buying_trigger":{"type":"string","nullable":true},"trust_blocker":{"type":"string","nullable":true},"next_action":{"type":"string","nullable":true},"opportunity_owner":{"type":"string","nullable":true},"opportunity_rationale":{"type":"string","nullable":true},"confidence":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string"}}},{"type":"object","required":["kind","person_slug_or_id","role_kind"],"description":"Attach an existing or same-bundle-created person to the bundle target entity as a key person.","properties":{"kind":{"type":"string","enum":["attach_person_role"]},"person_slug_or_id":{"type":"string","description":"Existing person slug/UUID, or the slug from a create_person change in this same bundle."},"role_kind":{"type":"string","enum":["founder","ceo","cfo","head_of_treasury","board","investor","advisor","employee","ex_employee","partner_contact"]},"role_label":{"type":"string","nullable":true},"is_primary":{"type":"boolean"},"start_date":{"type":"string","format":"date","nullable":true},"end_date":{"type":"string","format":"date","nullable":true},"confidence":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string"}}},{"type":"object","required":["kind","segment_slug"],"description":"Add or curate a GTM board account. Applies to gtm_entity_assignments on curator accept, only setting the fields you send (never wipes existing data). HONESTY GUARD: setting `stage` (moving into the In-motion surface) REQUIRES `source_ref` — real contact evidence. Omit `stage` for research/watchlist adds.","properties":{"kind":{"type":"string","enum":["gtm_upsert_assignment"]},"segment_slug":{"type":"string","example":"mining","description":"GET /v1/gtm/segments for valid slugs."},"lane":{"type":"string","enum":["primary","secondary","watching"]},"stage":{"type":"string","nullable":true,"enum":["spoken-to","booked","introduced","follow-up","handoff"]},"handoff_state":{"type":"string","nullable":true,"enum":["ecosystem","needs-right-person","bd-handoff","product-follow-up","serviceability-review","nurture","pause"]},"classification":{"type":"string","nullable":true,"enum":["bd-ready","product-discovery","watchlist","not-relevant"]},"outreach_status":{"type":"string","enum":["not-contacted","reach-out-next","reached-out","replied"]},"learned":{"type":"string","nullable":true},"next_step":{"type":"string","nullable":true},"needs":{"type":"array","items":{"type":"string","enum":["kevin","tom","product","compliance"]},"nullable":true},"pillars":{"type":"object","nullable":true,"additionalProperties":{"type":"string","enum":["confirmed","hypothesized","not-relevant","asked-unanswered","unknown"]},"description":"Per-pillar GTM signal from a call/intel source, e.g. trading: confirmed, payments: hypothesized, yield: not-relevant."},"product_signal":{"type":"object","nullable":true,"properties":{"area":{"type":"string","description":"Service/product area, e.g. trading, payments, treasury, yield, access-to-capital-markets."},"insight":{"type":"string","description":"Concrete need, pain, workflow, product gap, or serviceability implication."}}},"service_lane":{"type":"string","nullable":true},"contact_path":{"type":"string","nullable":true},"active_channel":{"type":"string","nullable":true},"right_next_person":{"type":"string","nullable":true},"blocker":{"type":"string","nullable":true},"contact_origin":{"type":"string","nullable":true,"enum":["linkedin","conference","event","warm-intro","referral","personal","inbound","cold-outreach","other"]},"contact_origin_detail":{"type":"string","nullable":true},"comms_channel":{"type":"string","nullable":true,"enum":["email","signal","telegram","whatsapp","phone","linkedin","in-person","other"]},"client_for":{"type":"string","nullable":true,"description":"Potential client opportunity — what we could sell them."},"partner_for":{"type":"string","nullable":true,"description":"Potential partner opportunity — what we could partner on."},"source_ref":{"type":"object","nullable":true,"properties":{"label":{"type":"string"},"href":{"type":"string"}}},"last_touch":{"type":"string","nullable":true},"unreachable_reason":{"type":"string","nullable":true,"description":"Non-null marks the account unreachable for BD (e.g. Tether-owned); other reachability buckets derive from outreach evidence."},"sizing":{"type":"object","nullable":true,"description":"The entity's own estimated revenue (market size) plus scale: hashrate/capacity and share of its own vertical market. Revenue is from monthly Bitcoin production by vertical; method states how the number was made.","properties":{"est_monthly_revenue_btc":{"type":"number"},"est_annual_revenue_usd":{"type":"integer"},"est_monthly_volume_usd":{"type":"integer"},"method":{"type":"string"},"hashrate_eh":{"type":"number","description":"Installed/operated hashrate, EH/s."},"capacity_mw":{"type":"number","description":"Capacity in MW, for hosting/infra."},"market_share_pct":{"type":"number","description":"Share of its vertical market (0-100)."},"market_label":{"type":"string","description":"What the share is of, e.g. 'network hashrate', 'firmware market'."}}},"confidence":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string"}}},{"type":"object","required":["kind"],"description":"Rename the bundle target entity's slug and/or display name. At least one of new_slug/new_name is required. There is no direct rename endpoint — this only ever lands as a curator-reviewed proposal, never auto-accepted, and applying it folds the old slug/name into `aliases` so old references keep resolving.","properties":{"kind":{"type":"string","enum":["rename_entity"]},"new_slug":{"type":"string","minLength":2,"pattern":"^[a-z0-9-]+$","description":"New slug, lowercase letters/digits/dashes only. Rejected up front if another entity already has it."},"new_name":{"type":"string","minLength":1,"maxLength":200},"confidence":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string","maxLength":2000}}},{"type":"object","required":["kind","target_person_slug_or_id"],"description":"Rename a person's slug and/or display name. At least one of new_slug/new_name is required. Curator-reviewed only; the old slug/name fold into `aliases` on accept.","properties":{"kind":{"type":"string","enum":["rename_person"]},"target_person_slug_or_id":{"type":"string","description":"Existing person slug or UUID to rename."},"new_slug":{"type":"string","minLength":2,"pattern":"^[a-z0-9-]+$","description":"New slug, lowercase letters/digits/dashes only. Rejected up front if another person already has it."},"new_name":{"type":"string","minLength":1,"maxLength":200},"confidence":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string","maxLength":2000}}},{"type":"object","required":["kind","duplicate_entity_id"],"description":"Merge a duplicate entity into the bundle's target entity (the target is always the survivor). duplicate_entity_id accepts a UUID or slug. On curator accept, every foreign key referencing the duplicate is repointed to the target inside one transaction, the duplicate's slug/name fold into the target's aliases, and the duplicate is archived with merged_into_id set — never hard-deleted. Irreversible in practice; never bulk-auto-accepted.","properties":{"kind":{"type":"string","enum":["merge_entities"]},"duplicate_entity_id":{"type":"string","description":"The entity to absorb into the bundle target. UUID or slug."},"confidence":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string","maxLength":2000}}},{"type":"object","required":["kind","primary_person_slug_or_id","duplicate_person_slug_or_id"],"description":"Merge duplicate_person into primary_person (primary always survives). Both accept a UUID or slug and must differ. Same reference-safe merge_records() mechanics as merge_entities: FK repoint, alias fold-in, archive-with-redirect. Irreversible in practice; never bulk-auto-accepted.","properties":{"kind":{"type":"string","enum":["merge_people"]},"primary_person_slug_or_id":{"type":"string","description":"The surviving person. UUID or slug."},"duplicate_person_slug_or_id":{"type":"string","description":"The person to absorb into primary. UUID or slug."},"confidence":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string","maxLength":2000}}},{"type":"object","required":["kind","reason"],"description":"Soft-delete the bundle target entity: sets lifecycle_status='archived' with a reason. Agents cannot hard-delete; this only archives (same lifecycle_status column suggest_entity_lifecycle uses). Never bulk-auto-accepted.","properties":{"kind":{"type":"string","enum":["soft_delete_entity"]},"reason":{"type":"string","minLength":1,"maxLength":2000},"confidence":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string","maxLength":2000}}},{"type":"object","required":["kind","target_person_slug_or_id","reason"],"description":"Soft-delete a person: sets lifecycle_status='archived' with a reason. Agents cannot hard-delete; this only archives. Never bulk-auto-accepted.","properties":{"kind":{"type":"string","enum":["soft_delete_person"]},"target_person_slug_or_id":{"type":"string","description":"Existing person slug or UUID to archive."},"reason":{"type":"string","minLength":1,"maxLength":2000},"confidence":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string","maxLength":2000}}}],"discriminator":{"propertyName":"kind"}},"BundleProposalRequest":{"allOf":[{"$ref":"#/components/schemas/ProposalTarget"},{"type":"object","required":["changes"],"properties":{"changes":{"type":"array","items":{"$ref":"#/components/schemas/BundleChange"},"minItems":1,"maxItems":30},"sources":{"type":"array","maxItems":20,"description":"Optional evidence URLs carried with the proposal as evidence_sources on each normalized change. These do not directly create canonical source rows.","items":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"},"title":{"type":"string"},"trust_tier":{"type":"string","enum":["public","reputable","private","rumor"]},"note":{"type":"string"}}}}}}],"examples":[{"target_entity_slug":"river-financial","match_rationale":"Research found a relevant partnerships contact.","changes":[{"kind":"create_person","person":{"slug":"jane-doe","name":"Jane Doe","posture_toward_lr":"Owns partner evaluation for Lightning vendors.","importance_score":4},"confidence":4,"rationale":"Named in official River partnerships materials."},{"kind":"attach_person_role","person_slug_or_id":"jane-doe","role_kind":"partner_contact","role_label":"VP Partnerships · possible warm path","is_primary":true,"confidence":4,"rationale":"Relevant contact for a Lunar Rails intro path."}]}]},"EntityProposalRequest":{"type":"object","required":["entity"],"properties":{"entity":{"type":"object","required":["slug","name","segment_slug"],"properties":{"slug":{"type":"string","pattern":"^[a-z0-9-]+$","description":"Lowercase letters, digits, dashes only.","example":"anchorage-digital"},"name":{"type":"string","example":"Anchorage Digital"},"segment_slug":{"type":"string","description":"Must be a slug from GET /v1/segments.","example":"custody"},"subsegment_slug":{"type":"string","nullable":true},"ticker":{"type":"string","nullable":true},"country":{"type":"string","nullable":true},"region":{"type":"string","nullable":true},"city":{"type":"string","nullable":true},"is_public":{"type":"boolean"},"posture":{"type":"string","enum":["producer","holder","allocator","service_provider","merchant","institution","infrastructure"]},"competitive_posture":{"type":"string","enum":["incumbent","competitor","partner","complement","whitespace","not_applicable"]},"one_liner":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"logo_url":{"type":"string","nullable":true},"website_url":{"type":"string","nullable":true},"x_url":{"type":"string","nullable":true},"linkedin_url":{"type":"string","nullable":true},"github_url":{"type":"string","nullable":true},"nostr_url":{"type":"string","nullable":true},"crunchbase_url":{"type":"string","nullable":true},"aliases":{"type":"array","items":{"type":"string"}},"rationale":{"type":"string"}}},"match_rationale":{"type":"string"},"enrichment":{"type":"object","description":"Optional bundled enrichments that apply to the just-created entity after the curator accepts.","properties":{"lr_fit":{"type":"array","items":{"$ref":"#/components/schemas/LrFitSuggestion"},"maxItems":10},"providers":{"type":"array","items":{"$ref":"#/components/schemas/ProviderSuggestion"},"maxItems":10},"events":{"type":"array","items":{"$ref":"#/components/schemas/EventSuggestion"},"maxItems":20}}}}},"DrilldownEntity":{"type":"object","description":"Entity row shaped for Atlas drill-down pages and agent curation queues.","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"ticker":{"type":"string","nullable":true},"country":{"type":"string","nullable":true},"is_public":{"type":"boolean"},"posture":{"type":"string","nullable":true},"competitive_posture":{"type":"string","nullable":true},"one_liner":{"type":"string","nullable":true},"strategic_importance":{"type":"integer","minimum":1,"maximum":5},"relationship_status":{"type":"string"},"scale":{"type":"object","additionalProperties":true},"primary_in_segment":{"type":"boolean"},"matched_segment_paths":{"type":"array","items":{"type":"string"},"description":"Segment paths that caused this entity to match the drilldown request, including child matches when include_children=true."},"segment_resolution":{"$ref":"#/components/schemas/EntitySegmentResolution"},"last_verified_at":{"type":"string","format":"date-time","nullable":true},"updated_at":{"type":"string","format":"date-time"},"dossier_url":{"type":"string","example":"/entities/strategy"},"agent_dossier_endpoint":{"type":"string"},"lr_fit":{"type":"array","items":{"type":"object","properties":{"horizon":{"type":"string"},"fit_score":{"type":"integer","nullable":true}}}},"verticals":{"type":"array","items":{"type":"object"}}}},"DrilldownResponse":{"type":"object","properties":{"segment":{"$ref":"#/components/schemas/Segment"},"stats":{"type":"object","properties":{"total_entities":{"type":"integer"},"primary_targets":{"type":"integer"},"clients":{"type":"integer"},"strategic_4_plus":{"type":"integer"},"with_lr_fit":{"type":"integer"}}},"entities":{"type":"array","items":{"$ref":"#/components/schemas/DrilldownEntity"}},"curation_gaps":{"type":"object","properties":{"missing_one_liner":{"type":"array","items":{"type":"object"}},"missing_lr_fit":{"type":"array","items":{"type":"object"}},"unverified":{"type":"array","items":{"type":"object"}}}},"next_cursor":{"type":"string","nullable":true}}},"DrilldownProposalRequest":{"type":"object","required":["changes"],"properties":{"target_entity_id":{"type":"string","description":"Target entity UUID. Either this or target_entity_slug is required."},"target_entity_slug":{"type":"string","description":"Target entity slug. Either this or target_entity_id is required."},"intent":{"type":"string","enum":["fill_gap","update_scale","improve_dossier_summary","classify_target","other"]},"match_rationale":{"type":"string"},"changes":{"type":"array","minItems":1,"maxItems":10,"items":{"oneOf":[{"type":"object","required":["kind","field_updates"],"properties":{"kind":{"type":"string","enum":["update_entity_fields"]},"field_updates":{"$ref":"#/components/schemas/EntityFieldUpdates"},"confidence":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string"}}},{"type":"object","required":["kind","append_text"],"properties":{"kind":{"type":"string","enum":["update_notes"]},"append_text":{"type":"string"},"confidence":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string"}}},{"type":"object","required":["kind","status"],"properties":{"kind":{"type":"string","enum":["set_relationship_status"]},"status":{"type":"string","enum":["cold","warm","active","client","alumnus"]},"confidence":{"type":"integer","minimum":1,"maximum":5},"rationale":{"type":"string"}}}],"discriminator":{"propertyName":"kind"}}}},"examples":[{"target_entity_slug":"strategy","intent":"update_scale","match_rationale":"Treasury drill-down showed stale holdings metadata.","changes":[{"kind":"update_entity_fields","field_updates":{"scale_patch":{"treasury_btc":582000},"strategic_importance":5},"confidence":4,"rationale":"Public filings and treasury tracker show current BTC holdings."}]}]},"ProposalCreatedResponse":{"type":"object","properties":{"proposal_id":{"type":"string","format":"uuid"},"change_count":{"type":"integer"},"change_kinds":{"type":"array","items":{"type":"string"}},"replayed":{"type":"boolean"},"target_entity":{"type":"object"},"sources_received":{"type":"integer"},"warnings":{"type":"array","items":{"type":"string"}},"inbox_url":{"type":"string","format":"uri"},"status_url":{"type":"string","format":"uri"}}}},"parameters":{"LimitParam":{"name":"limit","in":"query","description":"Page size. Default 50, max 200.","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},"CursorParam":{"name":"cursor","in":"query","description":"Opaque cursor from a previous response's `next_cursor`. Omit on the first page.","schema":{"type":"string"}},"IdempotencyKey":{"name":"Idempotency-Key","in":"header","description":"Optional UUID/opaque key. The server caches the response for 24 hours; replays of the same key return the cached proposal_id instead of creating a duplicate.","schema":{"type":"string"}}},"responses":{"Unauthorized":{"description":"Missing or invalid bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"Bearer token is valid but missing the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"ValidationError":{"description":"A query parameter or body field is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"The referenced resource does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Conflict":{"description":"The requested write conflicts with an existing resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"ProposalCreated":{"description":"Proposal created and queued in the inbox.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProposalCreatedResponse"}}}},"ProposalReplayed":{"description":"An earlier request with the same Idempotency-Key already created this proposal. The cached proposal_id is returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProposalCreatedResponse"}}}}}},"paths":{"/whoami":{"get":{"summary":"Identify the calling agent","description":"Returns the calling identity, scopes, and budget. Call this on agent startup to confirm credentials.","responses":{"200":{"description":"Identity payload.","content":{"application/json":{"schema":{"type":"object","properties":{"profile_id":{"type":"string","format":"uuid"},"display_name":{"type":"string"},"role":{"type":"string"},"scopes":{"type":"array","items":{"type":"string","enum":["read:atlas","read:catalog","read:people","read:proposals","write:proposals","read:gtm","write:gtm","write:sources"]}},"budget":{"type":"object"},"api_version":{"type":"string"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/usage":{"get":{"summary":"Current period's API usage","description":"Returns call count and cost for the current period. Phase A returns placeholders; Phase C wires real per-key tracking.","responses":{"200":{"description":"Usage payload.","content":{"application/json":{"schema":{"type":"object","properties":{"profile_id":{"type":"string","format":"uuid"},"period":{"type":"object"},"calls":{"type":"integer","nullable":true},"cost_usd":{"type":"number","nullable":true}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/gtm/segments":{"get":{"summary":"List GTM operating segments","description":"Returns the GTM focus segments. Pass include_assignments=true to include active/parked entity assignments grouped under each segment, including GTM operating fields such as stage, handoff_state, learned, pillars, product_signal, source_ref, next_action, and the effective funnel_stage (funnel_stage_override when pinned, else derived).","responses":{"200":{"description":"GTM segment list."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/gtm/assignments":{"get":{"summary":"List GTM entity assignments","description":"Filter by entity slug/id, segment slug/id, lane, status, stage, classification, handoff_state, needs, or effective funnel_stage. Defaults to non-removed assignments. Results include the full GTM operating shape used by the GTM page plus funnel_stage/funnel_stage_label: stage, handoff_state, classification, outreach_status, learned, needs, pillars, product_signal, contact path, comms fields, source_ref, last_touch, client/partner opportunity, next_action, and funnel_stage_override. funnel_stage is funnel_stage_override when a curator has pinned one, else it's derived from stage/classification/handoff_state/client_for/partner_for.","parameters":[{"name":"entity","in":"query","schema":{"type":"string"}},{"name":"segment","in":"query","schema":{"type":"string"}},{"name":"lane","in":"query","schema":{"type":"string","enum":["primary","secondary","watching"]}},{"name":"status","in":"query","schema":{"type":"string","enum":["active","parked","removed"]}},{"name":"stage","in":"query","schema":{"type":"string","enum":["spoken-to","booked","introduced","follow-up","handoff","none"]}},{"name":"classification","in":"query","schema":{"type":"string","enum":["bd-ready","product-discovery","watchlist","not-relevant"]}},{"name":"handoff_state","in":"query","schema":{"type":"string","enum":["ecosystem","needs-right-person","bd-handoff","product-follow-up","serviceability-review","nurture","pause"]}},{"name":"needs","in":"query","schema":{"type":"string","enum":["kevin","tom","product","compliance"]}},{"name":"funnel_stage","in":"query","schema":{"type":"string","enum":["initial-contact","in-discovery","opportunity-identified","qualified-prospect"]},"description":"Filters on the effective funnel stage: funnel_stage_override when set, else derived from stage/classification/handoff/opportunity fields using the same mapping as the GTM page."}],"responses":{"200":{"description":"GTM assignments."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"summary":"Create or update a GTM entity assignment","description":"Upserts by (segment, entity). Use this for agent-assisted GTM board management after curator approval or with an explicitly trusted GTM key. HONESTY GUARD: setting `stage` (moving into the In-motion surface) REQUIRES `source_ref` evidence. Normal call/intel agents should usually submit `gtm_upsert_assignment` through /agents/proposals/bundle instead.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"entity_slug":{"type":"string","example":"strategy"},"entity_id":{"type":"string","format":"uuid"},"segment_slug":{"type":"string","example":"treasuries"},"segment_id":{"type":"string","format":"uuid"},"lane":{"type":"string","enum":["primary","secondary","watching"]},"status":{"type":"string","enum":["active","parked","removed"]},"fit":{"type":"string"},"rationale":{"type":"string"},"next_action":{"type":"string"},"owner":{"type":"string"},"sort_order":{"type":"integer"},"stage":{"type":"string","nullable":true,"enum":["spoken-to","booked","introduced","follow-up","handoff"],"description":"GTM stage when in motion. null/omitted = research pool only (not shown as momentum)."},"handoff_state":{"type":"string","nullable":true,"enum":["ecosystem","needs-right-person","bd-handoff","product-follow-up","serviceability-review","nurture","pause"]},"classification":{"type":"string","nullable":true,"enum":["bd-ready","product-discovery","watchlist","not-relevant"]},"outreach_status":{"type":"string","enum":["not-contacted","reach-out-next","reached-out","replied"],"description":"Pre-motion reach-out funnel for the research pool."},"learned":{"type":"string","nullable":true,"description":"What the conversation revealed (markdown ok)."},"needs":{"type":"array","items":{"type":"string","enum":["kevin","tom","product","compliance"]},"nullable":true},"pillars":{"type":"object","nullable":true,"additionalProperties":{"type":"string","enum":["confirmed","hypothesized","not-relevant","asked-unanswered","unknown"]},"description":"Per-pillar signal for the GTM page, e.g. trading/payment/treasury/yield/access-to-capital-markets mapped to confirmed, hypothesized, not-relevant, asked-unanswered, or unknown."},"product_signal":{"type":"object","nullable":true,"properties":{"area":{"type":"string"},"insight":{"type":"string"}},"description":"Concrete product/service implication from the source."},"service_lane":{"type":"string","nullable":true,"description":"Core service area: trading|payments|treasury|custody|liquidity|swap-engine|onboarding."},"contact_path":{"type":"string","nullable":true},"active_channel":{"type":"string","nullable":true},"right_next_person":{"type":"string","nullable":true},"blocker":{"type":"string","nullable":true},"contact_origin":{"type":"string","nullable":true,"description":"How the relationship was established: linkedin|conference|event|warm-intro|referral|personal|inbound|cold-outreach|other."},"contact_origin_detail":{"type":"string","nullable":true,"description":"Free text, e.g. 'BTC Prague 2026' or 'intro via Christian'."},"comms_channel":{"type":"string","nullable":true,"description":"Where comms happen: email|signal|telegram|whatsapp|phone|linkedin|in-person|other."},"client_for":{"type":"string","nullable":true,"description":"Potential client opportunity — what we could sell them (e.g. Custody API)."},"partner_for":{"type":"string","nullable":true,"description":"Potential partner opportunity — what we could partner on (e.g. Hashrate banking services)."},"source_ref":{"type":"object","nullable":true,"properties":{"label":{"type":"string"},"href":{"type":"string"}},"description":"Provenance pointer (capture/deal/note)."},"last_touch":{"type":"string","nullable":true},"likelihood":{"type":"string","nullable":true,"enum":["High","Medium","Low","None"],"description":"Conversion potential (curator judgement). None = structurally impossible to convert, e.g. competitor-owned."},"funnel_stage_override":{"type":"string","nullable":true,"enum":["initial-contact","in-discovery","opportunity-identified","qualified-prospect"],"description":"Curator-pinned funnel stage. When set, this is returned as funnel_stage instead of the derived value; it does not modify stage/classification/handoff_state/client_for/partner_for. Null/omitted leaves the funnel stage derived."},"unreachable_reason":{"type":"string","nullable":true,"description":"Non-null marks the account unreachable for BD (e.g. Tether-owned); other reachability buckets derive from outreach evidence."},"sizing":{"type":"object","nullable":true,"description":"The entity's own estimated revenue (market size) plus scale: hashrate/capacity and share of its own vertical market. Revenue is from monthly Bitcoin production by vertical; method states how the number was made.","properties":{"est_monthly_revenue_btc":{"type":"number"},"est_annual_revenue_usd":{"type":"integer"},"est_monthly_volume_usd":{"type":"integer"},"method":{"type":"string"},"hashrate_eh":{"type":"number","description":"Installed/operated hashrate, EH/s."},"capacity_mw":{"type":"number","description":"Capacity in MW, for hosting/infra."},"market_share_pct":{"type":"number","description":"Share of its vertical market (0-100)."},"market_label":{"type":"string","description":"What the share is of, e.g. 'network hashrate', 'firmware market'."}}}}}}}},"responses":{"201":{"description":"Assignment created or updated."},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/gtm/assignments/{id}":{"patch":{"summary":"Patch a GTM assignment","description":"Update one trusted GTM assignment. If `stage` is set to an in-motion value, the row must already have source_ref or this patch must include source_ref.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"lane":{"type":"string","enum":["primary","secondary","watching"]},"status":{"type":"string","enum":["active","parked","removed"]},"fit":{"type":"string"},"rationale":{"type":"string"},"next_action":{"type":"string"},"owner":{"type":"string","nullable":true},"sort_order":{"type":"integer"},"stage":{"type":"string","nullable":true,"enum":["spoken-to","booked","introduced","follow-up","handoff"]},"handoff_state":{"type":"string","nullable":true,"enum":["ecosystem","needs-right-person","bd-handoff","product-follow-up","serviceability-review","nurture","pause"]},"classification":{"type":"string","nullable":true,"enum":["bd-ready","product-discovery","watchlist","not-relevant"]},"outreach_status":{"type":"string","enum":["not-contacted","reach-out-next","reached-out","replied"]},"learned":{"type":"string","nullable":true},"needs":{"type":"array","items":{"type":"string","enum":["kevin","tom","product","compliance"]},"nullable":true},"pillars":{"type":"object","nullable":true,"additionalProperties":{"type":"string","enum":["confirmed","hypothesized","not-relevant","asked-unanswered","unknown"]}},"product_signal":{"type":"object","nullable":true,"properties":{"area":{"type":"string"},"insight":{"type":"string"}}},"service_lane":{"type":"string","nullable":true},"contact_path":{"type":"string","nullable":true},"active_channel":{"type":"string","nullable":true},"right_next_person":{"type":"string","nullable":true},"blocker":{"type":"string","nullable":true},"contact_origin":{"type":"string","nullable":true},"contact_origin_detail":{"type":"string","nullable":true},"comms_channel":{"type":"string","nullable":true},"source_ref":{"type":"object","nullable":true,"properties":{"label":{"type":"string"},"href":{"type":"string"}}},"last_touch":{"type":"string","nullable":true},"likelihood":{"type":"string","nullable":true,"enum":["High","Medium","Low","None"],"description":"Conversion potential (curator judgement). None = structurally impossible to convert, e.g. competitor-owned."},"funnel_stage_override":{"type":"string","nullable":true,"enum":["initial-contact","in-discovery","opportunity-identified","qualified-prospect"],"description":"Curator-pinned funnel stage. When set, this is returned as funnel_stage instead of the derived value; it does not modify stage/classification/handoff_state/client_for/partner_for. Set to null to clear the pin and fall back to the derived value."},"unreachable_reason":{"type":"string","nullable":true,"description":"Non-null marks the account unreachable for BD (e.g. Tether-owned); other reachability buckets derive from outreach evidence."},"sizing":{"type":"object","nullable":true,"description":"The entity's own estimated revenue (market size) plus scale: hashrate/capacity and share of its own vertical market. Revenue is from monthly Bitcoin production by vertical; method states how the number was made.","properties":{"est_monthly_revenue_btc":{"type":"number"},"est_annual_revenue_usd":{"type":"integer"},"est_monthly_volume_usd":{"type":"integer"},"method":{"type":"string"},"hashrate_eh":{"type":"number","description":"Installed/operated hashrate, EH/s."},"capacity_mw":{"type":"number","description":"Capacity in MW, for hosting/infra."},"market_share_pct":{"type":"number","description":"Share of its vertical market (0-100)."},"market_label":{"type":"string","description":"What the share is of, e.g. 'network hashrate', 'firmware market'."}}}}}}}},"responses":{"200":{"description":"Updated assignment."},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/gtm/briefs":{"get":{"summary":"List GTM intelligence briefs","responses":{"200":{"description":"Brief list."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"summary":"Create or update a GTM intelligence brief","description":"Stores a weekly intelligence brief draft/review/published record. Brief links point back to Atlas entities, GTM segments, and sources.","responses":{"201":{"description":"Brief created or updated."},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/gtm/briefs/{id}/links":{"get":{"summary":"List links for a GTM brief","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Brief links."}}},"post":{"summary":"Attach an entity, segment, or source to a GTM brief","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"Brief link created."},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/field-events":{"get":{"summary":"List Field Intel events","description":"Lists conference, summit, meetup, roadshow, and webinar planning records for the Events dashboard. Requires read:gtm. Filter by status, priority, kind, segment slug/id, entity slug/id, person slug/id, or name search.","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["researching","planning","outreach","booked","attended","follow_up","skipped"]}},{"name":"priority","in":"query","schema":{"type":"string","enum":["must_attend","high","medium","watch","skip"]}},{"name":"kind","in":"query","schema":{"type":"string","enum":["conference","summit","meetup","side_event","roadshow","webinar","other"]}},{"name":"segment","in":"query","schema":{"type":"string"}},{"name":"entity","in":"query","schema":{"type":"string"}},{"name":"person","in":"query","schema":{"type":"string"}},{"name":"q","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Event list.","content":{"application/json":{"schema":{"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/FieldEvent"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"summary":"Create or update a Field Intel event","description":"Trusted direct write for the Events operating surface. Upserts by slug when provided, otherwise generates a slug from the name. Requires write:gtm; normal entity/dossier enrichment should still go through curator-reviewed proposals.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FieldEventInput"}}}},"responses":{"201":{"description":"Event created or updated.","content":{"application/json":{"schema":{"type":"object","properties":{"event":{"$ref":"#/components/schemas/FieldEvent"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/field-events/{slug}":{"get":{"summary":"Read one Field Intel event","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Event detail.","content":{"application/json":{"schema":{"type":"object","properties":{"event":{"$ref":"#/components/schemas/FieldEvent"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"summary":"Patch one Field Intel event","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FieldEventInput"}}}},"responses":{"200":{"description":"Event updated."},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/field-events/{slug}/entities":{"post":{"summary":"Attach an entity to a Field Intel event","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FieldEventEntityLinkInput"}}}},"responses":{"201":{"description":"Entity link created or updated."},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/field-events/{slug}/people":{"post":{"summary":"Attach a person to a Field Intel event","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FieldEventPersonLinkInput"}}}},"responses":{"201":{"description":"Person link created or updated."},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/field-events/{slug}/segments":{"post":{"summary":"Attach a segment to a Field Intel event","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FieldEventSegmentLinkInput"}}}},"responses":{"201":{"description":"Segment link created or updated."},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/field-events/{slug}/goals":{"post":{"summary":"Add a goal to a Field Intel event","description":"Adds a structured, trackable goal (e.g. \"Book 3 treasury custody meetings\") scored into the post-event scorecard. Requires write:gtm.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FieldEventGoalInput"}}}},"responses":{"201":{"description":"Goal created.","content":{"application/json":{"schema":{"type":"object","properties":{"event":{"$ref":"#/components/schemas/FieldEvent"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/field-events/{slug}/goals/{goalId}":{"patch":{"summary":"Update a Field Intel event goal","description":"Typically used to move status and progress_value. Requires write:gtm.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"goalId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FieldEventGoalPatchInput"}}}},"responses":{"200":{"description":"Goal updated.","content":{"application/json":{"schema":{"type":"object","properties":{"event":{"$ref":"#/components/schemas/FieldEvent"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/field-events/{slug}/interactions":{"post":{"summary":"Log a meeting/touchpoint at a Field Intel event","description":"Resolves to an entity_id/entity_slug, a person_id/person_slug, or a freeform counterpart_name for a contact not in Atlas yet. Requires write:gtm.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FieldEventInteractionInput"}}}},"responses":{"201":{"description":"Interaction created.","content":{"application/json":{"schema":{"type":"object","properties":{"event":{"$ref":"#/components/schemas/FieldEvent"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/field-events/{slug}/interactions/{interactionId}":{"patch":{"summary":"Update a Field Intel event interaction","description":"Update a meeting's status, outcome notes, signal strength, or next step. Requires write:gtm.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"interactionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FieldEventInteractionPatchInput"}}}},"responses":{"200":{"description":"Interaction updated.","content":{"application/json":{"schema":{"type":"object","properties":{"event":{"$ref":"#/components/schemas/FieldEvent"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/field-events/{slug}/follow-ups":{"post":{"summary":"Add a follow-up action item to a Field Intel event","description":"Optionally linked to an interaction, entity, or person. Requires write:gtm.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FieldEventFollowUpInput"}}}},"responses":{"201":{"description":"Follow-up created.","content":{"application/json":{"schema":{"type":"object","properties":{"event":{"$ref":"#/components/schemas/FieldEvent"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/field-events/{slug}/follow-ups/{followUpId}":{"patch":{"summary":"Update a Field Intel event follow-up","description":"Update a follow-up's status (open/in_progress/done/cancelled) or fields. Setting status to done without an explicit completed_at stamps it with the current time. Requires write:gtm.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"followUpId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FieldEventFollowUpPatchInput"}}}},"responses":{"200":{"description":"Follow-up updated.","content":{"application/json":{"schema":{"type":"object","properties":{"event":{"$ref":"#/components/schemas/FieldEvent"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/field-events/{slug}/scorecard":{"get":{"summary":"Read a Field Intel event's post-event scorecard","description":"Returns the curator-entered qualitative verdict and 30/90-day review notes, or null if no scorecard row exists yet. Requires read:gtm.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Scorecard, or null.","content":{"application/json":{"schema":{"type":"object","properties":{"scorecard":{"anyOf":[{"$ref":"#/components/schemas/FieldEventScorecard"},{"type":"null"}]}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"summary":"Upsert a Field Intel event's post-event scorecard","description":"One row per event (upserted by field_event_id) — there is no separate create endpoint. Carries verdict, review notes, team time, and reported cost; quantitative metrics are derived elsewhere, never stored here. Requires write:gtm.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FieldEventScorecardPatchInput"}}}},"responses":{"200":{"description":"Scorecard upserted.","content":{"application/json":{"schema":{"type":"object","properties":{"event":{"$ref":"#/components/schemas/FieldEvent"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/field-events/{slug}/roster":{"get":{"summary":"Read a Field Intel event's roster candidates","description":"Lists agent-discovered roster candidates (sponsors, exhibitors, speakers, organizers, media, attendees, other targets) staged for this event, filterable by role, review_status, and meeting_target. Requires read:gtm.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"role","in":"query","schema":{"type":"string","enum":["sponsor","exhibitor","speaker","organizer","host","media","attendee","partner","target","competitor","other"]}},{"name":"review_status","in":"query","schema":{"type":"string","enum":["unreviewed","matched","promoted","dismissed"]}},{"name":"meeting_target","in":"query","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Roster candidate list.","content":{"application/json":{"schema":{"type":"object","properties":{"roster":{"type":"array","items":{"$ref":"#/components/schemas/FieldEventRosterCandidate"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"summary":"Bulk-ingest roster candidates discovered by an agent","description":"Agent-first conference ingestion: the calling agent researches the event externally (its own website, sponsor/speaker pages) and posts up to 200 structured candidates per call with source evidence. This endpoint does NOT scrape or fetch URLs itself — source_url/evidence_note are the agent's citations. Idempotent: re-posting the same candidates (matched by external_ref, or by role + a normalized display_name) updates the existing rows instead of duplicating them. Every candidate lands as an event-scoped staging row; it never creates a canonical entity/person — promote via /v1/agents/proposals/entity or /v1/agents/proposals/person once a curator or agent workflow confirms it. But a candidate that explicitly carries matched_entity_id/slug or matched_person_id/slug is treated as an assertion that the record already exists: this also idempotently upserts the matching field_event_entities/field_event_people row (role mapped onto the narrower canonical vocabulary, plus meeting_target/outreach_status/next_step/relationship_note), keyed on (field_event_id, entity_id or person_id, role). An unmatched candidate stays staged only, and clearing a match later never deletes a canonical link already created. Requires write:gtm.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FieldEventRosterBulkInput"}}}},"responses":{"201":{"description":"Candidates created and/or updated.","content":{"application/json":{"schema":{"type":"object","properties":{"created":{"type":"integer"},"updated":{"type":"integer"},"roster":{"type":"array","items":{"$ref":"#/components/schemas/FieldEventRosterCandidate"}}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/field-events/{slug}/roster/{candidateId}":{"patch":{"summary":"Refine one Field Intel event roster candidate","description":"Correct fields, resolve to an existing entity/person (matched_entity_id/slug or matched_person_id/slug — setting one clears the other), mark it a meeting target, move outreach status, or set review_status (dismissed/promoted). Setting a match without an explicit review_status auto-advances it to \"matched\". Never creates a *new* canonical entity/person. But linking to an *existing* one idempotently upserts the matching field_event_entities/field_event_people row too (role mapped onto the narrower canonical vocabulary, plus meeting_target/outreach_status/next_step/relationship_note), so the match is a real bidirectional canonical link, not just a pointer on the staging row. Clearing a match (dismissing/unmatching) never deletes a canonical link that already exists. Requires write:gtm.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"candidateId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FieldEventRosterPatchInput"}}}},"responses":{"200":{"description":"Candidate updated.","content":{"application/json":{"schema":{"type":"object","properties":{"candidate":{"$ref":"#/components/schemas/FieldEventRosterCandidate"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/discovery-sprints/{sprint}/targets/{target}":{"get":{"summary":"Read one discovery sprint target","description":"Returns bot-writable operating intelligence for one discovery sprint target: status, pain points, opportunities, current providers, contacts, key metrics, relationship label, next action, meeting summaries/Fathom links, source links, and missing info.","parameters":[{"name":"sprint","in":"path","required":true,"schema":{"type":"string"}},{"name":"target","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Discovery target payload."},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"summary":"Update one discovery sprint target","description":"Updates structured sprint operating fields after a bot log command or meeting. This is not a canonical entity mutation; it updates sprint working intelligence. Requires write:proposals on standard Atlas agent keys.","parameters":[{"name":"sprint","in":"path","required":true,"schema":{"type":"string"}},{"name":"target","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["identified","warm_path_needed","outreach_ready","contacted","scheduled","briefed","interviewed","follow_up","synthesized","parked"]},"pain_points":{"type":"array","items":{"type":"string"}},"opportunities":{"type":"array","items":{"type":"string"}},"current_providers":{"type":"array","items":{"type":"object","additionalProperties":true}},"contacts":{"type":"array","items":{"type":"object","additionalProperties":true}},"key_metrics":{"type":"object","additionalProperties":true},"relationship_label":{"type":"string","enum":["client","partner","competitor","supplier","watch","unknown"],"nullable":true},"next_action":{"type":"string","nullable":true},"meeting_summaries":{"type":"array","items":{"type":"object","additionalProperties":true}},"source_links":{"type":"array","items":{"type":"object","additionalProperties":true}},"build_vs_buy_signal":{"type":"string","nullable":true},"willingness_to_pay_signal":{"type":"string","nullable":true},"missing_info":{"type":"array","items":{"type":"string"}}},"additionalProperties":false}}}},"responses":{"200":{"description":"Updated discovery target payload."},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/segments/{slug}":{"get":{"summary":"Get one segment with optional Dossier embed","description":"Returns a single segment by slug, optionally with the segment-level Dossier. The Dossier is a curator-authored markdown narrative explaining how the segment actually works: structural dynamics, key flows, chokepoints, dominant business models. Use `?include=lore` (default) to include the narrative body; pass `?include=` (empty) for just the segment metadata.","parameters":[{"name":"slug","in":"path","required":true,"description":"Segment slug. e.g. 'miners', 'custody', 'lightning'.","schema":{"type":"string"}},{"name":"include","in":"query","description":"Comma-separated embeds. Currently supported: `lore`. Default is `lore`.","schema":{"type":"string"}}],"responses":{"200":{"description":"Segment with optional dossier embed.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Segment"},{"type":"object","properties":{"lore":{"type":"object","description":"Segment dossier. Empty body when no dossier has been written.","properties":{"body":{"type":"string"},"current_version_id":{"type":"string","format":"uuid","nullable":true},"last_edited_at":{"type":"string","format":"date-time","nullable":true}}}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/atlas/segments/{slug}/drilldown":{"get":{"summary":"Get a page-shaped Atlas segment drill-down","description":"Agent-friendly read model for Atlas drill-down pages. Uses entity_segments membership, includes child segments by default, and returns segment_resolution for each entity so agents can see primary top-level segment, subsegment breadcrumb, all memberships, taxonomy terms, and display paths.","parameters":[{"name":"slug","in":"path","required":true,"description":"Segment slug, e.g. treasuries, custody, governments.","schema":{"type":"string"}},{"name":"limit","in":"query","description":"Maximum entities to return. Default 200, max 500.","schema":{"type":"integer","minimum":1,"maximum":500,"default":200}},{"name":"include_children","in":"query","description":"When true/default, parent drilldowns include entities from child segment memberships. Use false for exact segment membership only.","schema":{"type":"string","enum":["true","false"],"default":"true"}}],"responses":{"200":{"description":"Drill-down read model.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DrilldownResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/atlas/segments/{slug}/drilldown/proposals":{"post":{"summary":"Propose drill-down curation updates","description":"Segment-scoped write surface for agents working from a drill-down page. Creates curator-reviewed inbox proposals; it never directly mutates canonical Atlas rows. Use for filling curation gaps, updating dossier summary fields, patching scale metadata, appending notes, or setting relationship status.","parameters":[{"name":"slug","in":"path","required":true,"description":"Segment slug for the drill-down context.","schema":{"type":"string"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DrilldownProposalRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/ProposalReplayed"},"201":{"$ref":"#/components/responses/ProposalCreated"},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/atlas/visualization/overlaps":{"get":{"summary":"Get heuristic Atlas role-overlap buckets","description":"Returns read-only Venn/overlap data for exactly three Atlas visualization roles. This is a heuristic wiki lens for discovery and mapping, not a canonical GTM assignment surface. Agents should use it to find bridge entities, then read entity dossiers before proposing any changes.","parameters":[{"name":"roles","in":"query","required":false,"description":"Exactly three comma-separated role slugs. Defaults to custody,liquidity,payments. Common roles include custody, liquidity, payments, mining, treasuries, lightning, compliance, banking, api-infra.","schema":{"type":"string","example":"custody,liquidity,payments"}}],"responses":{"200":{"description":"Heuristic role-overlap buckets and capped entity previews.","content":{"application/json":{"schema":{"type":"object","properties":{"heuristic":{"type":"boolean","const":true},"roles":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"label":{"type":"string"},"description":{"type":"string"},"color":{"type":"string"}}}},"buckets":{"type":"object","additionalProperties":{"type":"object","properties":{"count":{"type":"integer"},"entities":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"ticker":{"type":"string","nullable":true},"segment":{"$ref":"#/components/schemas/Segment"},"strategic_importance":{"type":"integer","nullable":true},"relationship_status":{"type":"string","nullable":true},"roles":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"label":{"type":"string"},"reason":{"type":"string"},"reason_label":{"type":"string"}}}}}}}}}}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/atlas/visualization/coverage":{"get":{"summary":"Get Atlas data coverage and curation gaps","description":"Returns management coverage for entity country, city, Key People, relationship path context, and source records. Use this before large cleanup runs so agents work from explicit gaps instead of guessing.","parameters":[{"name":"segment","in":"query","description":"Limit coverage to entities in this segment. Parent segments include child memberships by default.","schema":{"type":"string","example":"miners"}},{"name":"tag","in":"query","description":"Limit coverage to entities assigned this taxonomy term slug. Comma-separated slugs use OR semantics.","schema":{"type":"string","example":"lightning.wallets"}},{"name":"include_children","in":"query","description":"When segment is a parent, include child segment memberships by default. Set false for exact membership only.","schema":{"type":"string","enum":["true","false"],"default":"true"}},{"name":"sample_limit","in":"query","description":"Maximum sample entities per gap bucket and returned work items.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"Coverage checks, sample gaps, and prioritized work items.","content":{"application/json":{"schema":{"type":"object","properties":{"coverage":{"$ref":"#/components/schemas/ManagementCoverage"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/agent-work/queues":{"get":{"summary":"List Atlas agent work queues","description":"Returns stable queue definitions for data-quality cleanup work, including location, Key People, relationship path, and source gaps.","responses":{"200":{"description":"Available agent work queues.","content":{"application/json":{"schema":{"type":"object","properties":{"queues":{"type":"array","items":{"$ref":"#/components/schemas/AgentWorkQueue"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/agent-work/items":{"get":{"summary":"List prioritized Atlas cleanup work items","description":"Returns explicit data-quality work items for agents, filtered by segment, taxonomy tag, and gap kind. Each item includes the entity, reason, suggested endpoint, and expected proposal shape.","parameters":[{"name":"segment","in":"query","description":"Limit work items to entities in this segment. Parent segments include child memberships by default.","schema":{"type":"string","example":"treasuries"}},{"name":"tag","in":"query","description":"Limit work items to entities assigned this taxonomy term slug. Comma-separated slugs use OR semantics.","schema":{"type":"string","example":"lightning.infrastructure.lsp"}},{"name":"include_children","in":"query","description":"When segment is a parent, include child segment memberships by default. Set false for exact membership only.","schema":{"type":"string","enum":["true","false"],"default":"true"}},{"name":"kind","in":"query","description":"Comma-separated work kinds: missing_country, missing_city, missing_key_people, missing_relationship_path, missing_sources.","schema":{"type":"string","example":"missing_key_people,missing_relationship_path"}},{"name":"limit","in":"query","description":"Maximum returned work items.","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}}],"responses":{"200":{"description":"Prioritized cleanup work items.","content":{"application/json":{"schema":{"type":"object","properties":{"generated_at":{"type":"string","format":"date-time"},"filters":{"type":"object","properties":{"segment":{"type":"string","nullable":true},"tag":{"type":"string","nullable":true},"include_children":{"type":"boolean"}}},"queues":{"type":"array","items":{"$ref":"#/components/schemas/AgentWorkQueue"}},"items":{"type":"array","items":{"$ref":"#/components/schemas/AgentWorkItem"}}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/segments":{"get":{"summary":"List ecosystem segments","description":"Returns every segment in the taxonomy ordered by sort_order. Call this before proposing entities so segment_slug values are valid. For a single segment with its Dossier body, use GET /v1/segments/{slug}.","responses":{"200":{"description":"List of segments.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Segment"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/taxonomy":{"get":{"summary":"List agent-facing taxonomy terms","description":"Returns stable taxonomy/tag slugs for agents. Use these slugs in entity filters and taxonomy assignment proposals.","parameters":[{"name":"kind","in":"query","description":"Filter by taxonomy kind.","schema":{"type":"string"}},{"name":"parent","in":"query","description":"Parent taxonomy slug.","schema":{"type":"string"}},{"name":"include_deprecated","in":"query","description":"Include deprecated terms when true.","schema":{"type":"boolean"}}],"responses":{"200":{"description":"List of taxonomy terms.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/TaxonomyTerm"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/taxonomy/{slug}":{"get":{"summary":"Get one taxonomy term","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Taxonomy term with children.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaxonomyTerm"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/taxonomy/{slug}/entities":{"get":{"summary":"List entities assigned to a taxonomy term","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/LimitParam"},{"$ref":"#/components/parameters/CursorParam"}],"responses":{"200":{"description":"Paginated entities for a taxonomy term."},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/capabilities":{"get":{"summary":"List Lunar Rails capabilities","description":"Returns every capability. The slug is the load-bearing field; use it for `capability_slug` in lr_fit and provider proposals.","responses":{"200":{"description":"List of capabilities.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Capability"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/needs":{"get":{"summary":"List demand-side needs","description":"Returns every need in the taxonomy. Needs map to capabilities via primary_capability_id.","responses":{"200":{"description":"List of needs.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Need"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/verticals":{"get":{"summary":"List sub-classification verticals","description":"Returns every vertical. Used today for mining sub-segments (self_mining, mining_pool, hosting, etc.).","responses":{"200":{"description":"List of verticals.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Vertical"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/entities":{"get":{"summary":"List catalog entities with filters","description":"The load-bearing read endpoint. Agents drive their own work queues from the filter parameters. Filters compose; pagination is cursor-based. Use `last_verified_before` for freshness work, `missing_capability` for enrichment work, `needs_research=true` for entities with thin metadata.","parameters":[{"name":"segment","in":"query","description":"Entities with this segment membership. Parent segments include child memberships by default.","schema":{"type":"string","example":"custody"}},{"name":"include_children","in":"query","description":"When segment is a parent, include child segment memberships by default. Set false for exact membership only.","schema":{"type":"string","enum":["true","false"],"default":"true"}},{"name":"posture","in":"query","description":"Bitcoin posture enum.","schema":{"type":"string","enum":["producer","holder","allocator","service_provider","merchant","institution","infrastructure"]}},{"name":"competitive_posture","in":"query","description":"Lunar overlay posture enum.","schema":{"type":"string","enum":["incumbent","competitor","partner","complement","whitespace","not_applicable"]}},{"name":"country","in":"query","description":"Case-insensitive exact filter on entity country.","schema":{"type":"string","example":"United States"}},{"name":"region","in":"query","description":"Case-insensitive exact filter on entity region/state.","schema":{"type":"string","example":"Texas"}},{"name":"city","in":"query","description":"Case-insensitive exact filter on entity city.","schema":{"type":"string","example":"Austin"}},{"name":"has_lr_fit","in":"query","description":"Entities with at least one entity_lr_fit row.","schema":{"type":"string","enum":["true","false"]}},{"name":"has_providers","in":"query","description":"Entities with at least one entity_providers row.","schema":{"type":"string","enum":["true","false"]}},{"name":"missing_capability","in":"query","description":"Entities without an lr_fit row for this capability slug. Useful for enrichment runs ('find entities not yet rated for custody').","schema":{"type":"string","example":"custody"}},{"name":"tag","in":"query","description":"Entities assigned this taxonomy term slug.","schema":{"type":"string","example":"lightning.wallets.custodial"}},{"name":"any_tag","in":"query","description":"Comma-separated taxonomy slugs with OR semantics.","schema":{"type":"string","example":"lightning.wallets,lightning.infrastructure.lsp"}},{"name":"all_tags","in":"query","description":"Comma-separated taxonomy slugs with AND semantics.","schema":{"type":"string","example":"lightning,lightning.wallets,lightning.wallets.custodial"}},{"name":"last_verified_before","in":"query","description":"ISO date-time. Returns entities whose last_verified_at is older than this. Drives the verification agent loop.","schema":{"type":"string","format":"date-time"}},{"name":"needs_research","in":"query","description":"Convenience predicate: entities with neither lr_fit nor providers.","schema":{"type":"string","enum":["true"]}},{"name":"name","in":"query","description":"Case-insensitive substring search on the name field.","schema":{"type":"string"}},{"$ref":"#/components/parameters/LimitParam"},{"$ref":"#/components/parameters/CursorParam"}],"responses":{"200":{"description":"Paginated list of entities matching the filters.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntityListResponse"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/agents/proposals":{"get":{"summary":"List your proposals","description":"Return proposals visible to the calling agent. Defaults to mine_only=true so each agent sees its own backlog. Closes the feedback loop: an agent can check what it proposed earlier and which proposals the curator accepted, rejected, or left pending — without trawling the inbox UI.","parameters":[{"name":"status","in":"query","description":"Comma-separated subset of: pending, accepted, rejected, unmatched. Default returns all.","schema":{"type":"string"}},{"name":"target_entity","in":"query","description":"Filter to one entity's proposals (slug or UUID).","schema":{"type":"string"}},{"name":"mine_only","in":"query","description":"true (default) returns only proposals the calling agent created. Pass false for cross-agent visibility (orchestrator use).","schema":{"type":"boolean"}},{"name":"limit","in":"query","description":"Max items to return. 1..100. Default 25.","schema":{"type":"integer"}},{"name":"cursor","in":"query","description":"Pass next_cursor from the previous response to page backward through time.","schema":{"type":"string"}}],"responses":{"200":{"description":"List of proposal summaries.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ProposalSummary"}},"next_cursor":{"type":"string","nullable":true}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/agents/proposals/{id}":{"get":{"summary":"Get one of your proposals with full change payload","description":"Detail view including the full proposed_changes array, applied_indices, and decision_notes from the curator review. Returns 403 when the proposal belongs to a different agent.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Proposal detail.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProposalDetail"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"description":"Proposal belongs to another agent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/agents/proposals/entity":{"post":{"summary":"Propose a new entity (optionally with enrichment)","description":"The killer-feature endpoint for conversational entity authoring. Creates a single proposal in the inbox with create_entity FIRST followed by optional enrichment changes (lr_fit, providers, events). On accept the apply pipeline creates the entity, captures the new id, then applies the enrichment against it.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntityProposalRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/ProposalReplayed"},"201":{"$ref":"#/components/responses/ProposalCreated"},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"409":{"description":"An entity with this slug already exists. Use the bundle endpoint against the existing slug instead.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/agents/proposals/segments":{"post":{"summary":"Propose a new ecosystem segment","description":"Lands a create_segment change in the curator inbox. Agents never create canonical segments directly; curator acceptance inserts the segment row. Use this when the ecosystem map outgrows the current segment taxonomy.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["segment"],"properties":{"segment":{"type":"object","required":["slug","name"],"properties":{"slug":{"type":"string","pattern":"^[a-z0-9-]+$","example":"self-custody-wallets"},"name":{"type":"string","example":"Self-Custody Wallets"},"description":{"type":"string","nullable":true},"parent_slug_or_id":{"type":"string","nullable":true},"hue_token":{"type":"string","nullable":true,"example":"seg-self-custody-wallets"},"sort_order":{"type":"integer"}}},"rationale":{"type":"string"},"confidence":{"type":"integer","minimum":1,"maximum":5}}}}}},"responses":{"200":{"$ref":"#/components/responses/ProposalReplayed"},"201":{"$ref":"#/components/responses/ProposalCreated"},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"409":{"description":"A segment with this slug already exists.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/agents/proposals/lr-fit":{"post":{"summary":"Propose lr_fit rows for an entity (batch)","description":"Lands as one pending proposal in the inbox. Each suggestion is a single lr_fit row (capability + horizon + fit_score). Curator accepts via the inbox; nothing auto-applies.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LrFitProposalRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/ProposalReplayed"},"201":{"$ref":"#/components/responses/ProposalCreated"},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/agents/proposals/entity-relationship":{"post":{"summary":"Publish an entity's relationship path (how contact formed + where comms live)","description":"Records how the relationship was established (origin), where the conversation happens now (channel + label), owner, last touch, and an optional timeline touchpoint. Lands as one pending update_entity_relationship_context proposal in the inbox; the curator accepts to apply it to the canonical entity fields and (if a touchpoint is included) the relationship timeline. Read it back via GET /v1/entities/{id}. Scope: write:proposals.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"target_entity_id":{"type":"string","format":"uuid"},"target_entity_slug":{"type":"string","example":"braiins"},"match_rationale":{"type":"string"},"contact_origin":{"type":"string","enum":["conference","event","warm-intro","personal","linkedin","inbound","cold-outreach","partner-referral","other"],"description":"How the relationship was established (origin touch point)."},"contact_origin_detail":{"type":"string","example":"BTC Prague 2026, met at the Lunar booth"},"first_contact_at":{"type":"string","format":"date"},"current_comms_channel":{"type":"string","enum":["telegram","signal","whatsapp","email","phone","linkedin","in-person","other"],"description":"Where the conversation happens now."},"current_comms_label":{"type":"string","example":"Telegram group “Lunar × Braiins”"},"relationship_owner":{"type":"string"},"relationship_source_ref":{"type":"object","properties":{"label":{"type":"string"},"href":{"type":"string"}}},"relationship_last_touch":{"type":"string"},"touchpoint_kind":{"type":"string","enum":["conference","event","warm-intro","personal","linkedin","inbound","cold-outreach","partner-referral","channel-move","call-booked","call-complete","right-person-identified","other"],"description":"Optional — records a timeline touchpoint on the entity's relationship path."},"touchpoint_detail":{"type":"string"},"rationale":{"type":"string"},"confidence":{"type":"integer","minimum":1,"maximum":5}}}}}},"responses":{"200":{"$ref":"#/components/responses/ProposalReplayed"},"201":{"$ref":"#/components/responses/ProposalCreated"},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/agents/proposals/providers":{"post":{"summary":"Propose provider relationships for an entity (batch)","description":"Each suggestion names a capability and either a catalogued provider (provider_entity_id) or a free-text provider_name. Both can be supplied; the apply step prefers the linked entity.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProvidersProposalRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/ProposalReplayed"},"201":{"$ref":"#/components/responses/ProposalCreated"},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/agents/proposals/relationships":{"post":{"summary":"Propose entity-to-entity relationships (batch)","description":"Every related_entity_id must already exist in the catalog. Use UUID or slug.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RelationshipsProposalRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/ProposalReplayed"},"201":{"$ref":"#/components/responses/ProposalCreated"},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/agents/proposals/events":{"post":{"summary":"Propose events for an entity (batch)","description":"News items, deals, integration announcements, capital raises, etc. occurred_at is YYYY-MM-DD.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventsProposalRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/ProposalReplayed"},"201":{"$ref":"#/components/responses/ProposalCreated"},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/agents/proposals/field-events":{"post":{"summary":"Propose a field event with segment/entity/people intel (batch)","description":"Upserts a conference/summit/meetup as one pending upsert_field_event proposal, plus attach_field_event_segment / attach_field_event_entity / attach_field_event_person changes for each resolved link. Entity/person links accept an id or slug and are resolved server-side before the proposal is written; unresolved names go in unmatched_entities/unmatched_people so the curator can match or create them by hand — agents never auto-create entities or people from this endpoint. All changes land as a single inbox card. Scope: write:proposals.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FieldEventsProposalRequest"},"examples":{"default":{"value":{"event":{"name":"BTC Prague 2026","event_kind":"conference","starts_at":"2026-06-11","ends_at":"2026-06-13","city":"Prague","country":"Czechia","priority":"high","lifecycle_status":"planning"},"segments":[{"segment_slug":"lightning","relevance":"Lightning-heavy speaker lineup"}],"entities":[{"entity_slug":"river-financial","role":"sponsor","outreach_status":"to_contact","meeting_target":true}],"people":[{"person_slug":"jane-doe","role":"speaker","outreach_status":"research"}],"unmatched_entities":["Some Startup We Haven't Catalogued"],"match_rationale":"Sourced from the published BTC Prague 2026 speaker/sponsor page.","sources":[{"url":"https://btcprague.com/2026","title":"BTC Prague 2026 site","trust_tier":"public"}]}}}}}},"responses":{"200":{"$ref":"#/components/responses/ProposalReplayed"},"201":{"$ref":"#/components/responses/ProposalCreated"},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/agents/validate/bundle":{"post":{"summary":"Dry-run validate a bundle proposal","description":"Validates and normalizes a bundle payload without creating inbox noise. Use this before POST /agents/proposals/bundle when an agent is assembling larger multi-change proposals. Returns target resolution, normalized changes, source evidence handling, warnings, and the submit endpoint.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BundleProposalRequest"}}}},"responses":{"200":{"description":"Valid dry-run preview.","content":{"application/json":{"schema":{"type":"object","properties":{"valid":{"type":"boolean"},"dry_run":{"type":"boolean"},"would_create":{"type":"string"},"change_count":{"type":"integer"},"change_kinds":{"type":"array","items":{"type":"string"}},"target_entity":{"type":"object"},"normalized_changes":{"type":"array","items":{"type":"object"}},"sources_received":{"type":"integer"},"warnings":{"type":"array","items":{"type":"string"}},"submit_endpoint":{"type":"string","format":"uri"},"inbox_url":{"type":"string","format":"uri"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/agents/proposals/bundle":{"post":{"summary":"Propose multiple change kinds in one inbox card","description":"The killer-feature endpoint. One conversational turn produces ONE inbox card containing N change kinds (lr_fit + providers + relationships + events + notes + status + key people + GTM board updates). All changes share one target entity. The curator accepts the bundle in a single review. For Key People, use create_person/update_person plus attach_person_role; new people can be attached in the same bundle by referencing the create_person slug. For the GTM board (In-motion / research), use gtm_upsert_assignment — note the honesty guard: an in-motion `stage` requires `source_ref`. Identity-changing kinds — `rename_entity`, `rename_person`, `merge_entities`, `merge_people`, `soft_delete_entity`, `soft_delete_person` — are also supported. They land as proposals like everything else (there is no direct rename/merge/delete endpoint) but are never bulk-auto-accepted; a curator must review each one individually.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BundleProposalRequest"}}}},"responses":{"200":{"$ref":"#/components/responses/ProposalReplayed"},"201":{"$ref":"#/components/responses/ProposalCreated"},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/entities/{id}":{"get":{"summary":"Get a full entity dossier","description":"Returns an entity with optional embeds. The id may be a UUID or a slug. Use `?include=` to limit embeds for smaller responses.","parameters":[{"name":"id","in":"path","required":true,"description":"Entity UUID or slug.","schema":{"type":"string"}},{"name":"include","in":"query","description":"Comma-separated embeds: lr_fit, providers, relationships, events, segments, needs, verticals, people, lore. Default is all. The `lore` embed returns the entity's Dossier — the qualitative narrative body that captures operating story, flywheels, dependencies, and inside-baseball context that doesn't fit a column.","schema":{"type":"string"}}],"responses":{"200":{"description":"Entity dossier.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/EntitySummary"},{"type":"object","properties":{"description":{"type":"string","nullable":true},"logo_url":{"type":"string","nullable":true},"website_url":{"type":"string","nullable":true},"x_url":{"type":"string","nullable":true},"linkedin_url":{"type":"string","nullable":true},"github_url":{"type":"string","nullable":true},"nostr_url":{"type":"string","nullable":true},"crunchbase_url":{"type":"string","nullable":true},"scale":{"type":"object","nullable":true},"importance_rationale":{"type":"string","nullable":true},"notes":{"type":"string","nullable":true},"aliases":{"type":"array","items":{"type":"string"}},"lr_fit":{"type":"array","items":{"type":"object"}},"providers":{"type":"array","items":{"type":"object"}},"relationships":{"type":"array","items":{"type":"object"}},"events":{"type":"array","items":{"type":"object"}},"segments":{"type":"array","items":{"type":"object"}},"needs":{"type":"array","items":{"type":"object"}},"verticals":{"type":"array","items":{"type":"object"}},"people":{"type":"array","description":"Key people attached to this entity through person_entity_roles. Use this for account mapping: primary contacts, decision makers, warm paths, and next actions.","items":{"type":"object","properties":{"role_kind":{"type":"string"},"role_label":{"type":"string","nullable":true},"is_primary":{"type":"boolean"},"start_date":{"type":"string","format":"date","nullable":true},"end_date":{"type":"string","format":"date","nullable":true},"person":{"type":"object"}}}},"lore":{"type":"object","description":"Dossier narrative. Empty body when no dossier has been written.","properties":{"body":{"type":"string"},"current_version_id":{"type":"string","format":"uuid","nullable":true},"last_edited_at":{"type":"string","format":"date-time","nullable":true}}}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/entities/{id}/sources":{"get":{"summary":"List sources backing an entity's Dossier","description":"Returns every source row attached to the entity. Each row carries a trust_tier (public, reputable, private, rumor) so agents can decide how cite-able the source is. File-backed sources return only metadata; call GET /sources/{id} to mint a signed download URL.","parameters":[{"name":"id","in":"path","required":true,"description":"Entity UUID or slug.","schema":{"type":"string"}}],"responses":{"200":{"description":"List of sources.","content":{"application/json":{"schema":{"type":"object","properties":{"entity_id":{"type":"string","format":"uuid"},"entity_slug":{"type":"string"},"data":{"type":"array","items":{"$ref":"#/components/schemas/SourceSummary"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/sources/{id}":{"get":{"summary":"Get a source with a signed download URL","description":"Returns the full source row plus a short-lived signed download URL for file-backed sources. URL-only sources return the original URL directly. The signed URL expires after a few minutes; call this endpoint again to mint a fresh one.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Source detail with download URL.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SourceSummary"},{"type":"object","properties":{"download_url":{"type":"string","nullable":true},"download_expires_in_seconds":{"type":"integer","nullable":true}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/agents/sources":{"post":{"summary":"Create a URL-based source for an entity","description":"Register a URL (press release, filing, blog post, podcast episode page) as a source backing the entity's Dossier. File uploads from agents use POST /agents/sources/upload.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["target_entity_slug_or_id","kind","title","trust_tier","url"],"properties":{"target_entity_slug_or_id":{"type":"string"},"kind":{"type":"string","enum":["transcript","deck","conversation","public_url","research","addendum"]},"title":{"type":"string"},"description":{"type":"string"},"trust_tier":{"type":"string","enum":["public","reputable","private","rumor"]},"is_referenceable":{"type":"boolean"},"external_ref":{"type":"string","description":"Stable upstream source key for idempotent registration, e.g. fathom:{meeting_id}:{entity_slug}:notes."},"url":{"type":"string","format":"uri"}}}}}},"responses":{"201":{"description":"Source created.","content":{"application/json":{"schema":{"type":"object","properties":{"source_id":{"type":"string","format":"uuid"},"entity_id":{"type":"string","format":"uuid"},"replayed":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/agents/sources/upload":{"post":{"summary":"Upload a file-backed source for an entity","description":"Upload a private or public file-backed source such as meeting notes, transcripts, raw Fathom payloads, PDFs, or Markdown research. The source becomes downloadable through GET /sources/{id}; file downloads use short-lived signed URLs.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["target_entity_slug_or_id","kind","title","trust_tier","filename","mime_type","content_base64"],"properties":{"target_entity_slug_or_id":{"type":"string"},"kind":{"type":"string","enum":["transcript","deck","conversation","public_url","research","addendum"]},"title":{"type":"string"},"description":{"type":"string"},"trust_tier":{"type":"string","enum":["public","reputable","private","rumor"]},"is_referenceable":{"type":"boolean"},"external_ref":{"type":"string","description":"Stable upstream source key. Reusing the same key returns the existing source instead of uploading a duplicate."},"filename":{"type":"string"},"mime_type":{"type":"string","enum":["text/plain","text/markdown","application/json","application/pdf"]},"content_base64":{"type":"string","description":"Base64-encoded file bytes. Max decoded size: 5 MB."}}}}}},"responses":{"200":{"description":"Existing source returned for the supplied external_ref."},"201":{"description":"Source uploaded.","content":{"application/json":{"schema":{"type":"object","properties":{"source_id":{"type":"string","format":"uuid"},"entity_id":{"type":"string","format":"uuid"},"replayed":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"}}}},"/agents/proposals/lore-update":{"post":{"summary":"Propose an update to an entity's Dossier narrative","description":"Update the qualitative Dossier body for an entity. Submit the FULL new body (not a diff). The accept step in the curator inbox replaces the canonical body and preserves the prior state in entity_lore_versions, so history is never lost. Always read the existing dossier via GET /entities/{id}?include=lore before proposing, and submit additive edits that preserve what's already there.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["target_entity_slug_or_id","proposed_body","diff_summary"],"properties":{"target_entity_slug_or_id":{"type":"string","description":"Slug or UUID of the target entity."},"proposed_body":{"type":"string","maxLength":50000,"description":"Full new dossier body in markdown."},"diff_summary":{"type":"string","maxLength":200,"description":"One-line description of what changed. Shown on the inbox card."},"rationale":{"type":"string","maxLength":2000,"description":"Brief justification (sources, conversations, observations)."},"confidence":{"type":"integer","minimum":1,"maximum":5},"source_ids":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Optional list of entity_lore_sources rows that back this update. They link to the new version on accept."}}}}}},"responses":{"200":{"$ref":"#/components/responses/ProposalReplayed"},"201":{"$ref":"#/components/responses/ProposalCreated"},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/people":{"get":{"summary":"List people with filters","description":"Filterable, cursor-paginated listing of people (Track P). People are the humans inside entities — founders, executives, board members, key contacts. Use the `entity` filter to find everyone affiliated with one org; `role_kind` to find all CEOs or investors; `importance_min` for the people most worth caring about. Curator-only fields (trust_blocker, next_action) are never returned here.","parameters":[{"name":"entity","in":"query","description":"People with any role at this entity (slug or UUID).","schema":{"type":"string","example":"strategy"}},{"name":"segment","in":"query","description":"People whose role-entities sit in this segment (slug).","schema":{"type":"string","example":"treasuries"}},{"name":"role_kind","in":"query","description":"Filter by person_role_kind enum.","schema":{"type":"string","enum":["founder","ceo","cfo","head_of_treasury","board","investor","advisor","employee","ex_employee","partner_contact"]}},{"name":"importance_min","in":"query","description":"Minimum importance_score (1-5).","schema":{"type":"integer","minimum":1,"maximum":5}},{"name":"posture","in":"query","description":"Case-insensitive substring on posture_toward_lr.","schema":{"type":"string"}},{"name":"name","in":"query","description":"Case-insensitive substring on the name field.","schema":{"type":"string"}},{"$ref":"#/components/parameters/LimitParam"},{"$ref":"#/components/parameters/CursorParam"}],"responses":{"200":{"description":"Paginated list of people matching the filters.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"aliases":{"type":"array","items":{"type":"string"}},"country":{"type":"string","nullable":true},"city":{"type":"string","nullable":true},"avatar_url":{"type":"string","nullable":true},"website_url":{"type":"string","nullable":true},"x_url":{"type":"string","nullable":true},"linkedin_url":{"type":"string","nullable":true},"github_url":{"type":"string","nullable":true},"nostr_url":{"type":"string","nullable":true},"posture_toward_lr":{"type":"string","nullable":true},"importance_score":{"type":"integer"},"last_verified_at":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}},"next_cursor":{"type":"string","nullable":true},"total":{"type":"integer","nullable":true}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/people/{id}":{"get":{"summary":"Get a full person dossier","description":"Returns a person with optional embeds (roles, relationships, sources). The id may be UUID or slug. Curator-only fields are filtered out — agents see the public-ish projection. Use the roles embed to find which entities this person is connected to and how.","parameters":[{"name":"id","in":"path","required":true,"description":"Person UUID or slug.","schema":{"type":"string"}},{"name":"include","in":"query","description":"Comma-separated embeds: roles, relationships, sources. Default is all.","schema":{"type":"string"}}],"responses":{"200":{"description":"Person dossier.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"aliases":{"type":"array","items":{"type":"string"}},"country":{"type":"string","nullable":true},"city":{"type":"string","nullable":true},"bio_md":{"type":"string","nullable":true},"avatar_url":{"type":"string","nullable":true},"website_url":{"type":"string","nullable":true},"x_url":{"type":"string","nullable":true},"linkedin_url":{"type":"string","nullable":true},"github_url":{"type":"string","nullable":true},"nostr_url":{"type":"string","nullable":true},"posture_toward_lr":{"type":"string","nullable":true},"importance_score":{"type":"integer"},"last_verified_at":{"type":"string","format":"date-time","nullable":true},"roles":{"type":"array","items":{"type":"object"}},"relationships":{"type":"object","properties":{"out":{"type":"array","items":{"type":"object"}},"in":{"type":"array","items":{"type":"object"}}}},"sources":{"type":"array","items":{"type":"object"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/agents/proposals/person":{"post":{"summary":"Propose a new person or an update to an existing one","description":"Submit a person to the curator inbox (Track P). Omit `target_person_slug_or_id` to create a new person — `person.slug` and `person.name` are required. Set `target_person_slug_or_id` to update existing fields — only the keys you supply are touched on accept. Curator-only fields (trust_blocker, next_action) are silently dropped from agent input.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["person"],"properties":{"target_person_slug_or_id":{"type":"string","description":"If set, this is an update_person proposal. Slug or UUID."},"person":{"type":"object","description":"Person field values. On create, `slug` + `name` are required. On update, all keys optional; missing keys stay untouched.","properties":{"slug":{"type":"string","pattern":"^[a-z0-9-]+$"},"name":{"type":"string","maxLength":200},"aliases":{"type":"array","items":{"type":"string"}},"country":{"type":"string","nullable":true},"city":{"type":"string","nullable":true},"bio_md":{"type":"string","nullable":true,"maxLength":50000},"avatar_url":{"type":"string","nullable":true},"website_url":{"type":"string","nullable":true},"x_url":{"type":"string","nullable":true},"linkedin_url":{"type":"string","nullable":true},"github_url":{"type":"string","nullable":true},"nostr_url":{"type":"string","nullable":true},"posture_toward_lr":{"type":"string","nullable":true,"maxLength":200},"importance_score":{"type":"integer","minimum":1,"maximum":5},"notes":{"type":"string","nullable":true}}},"rationale":{"type":"string","maxLength":2000},"confidence":{"type":"integer","minimum":1,"maximum":5},"raw_transcript":{"type":"string","maxLength":50000,"description":"Optional verbatim transcript or observation that backs this proposal."}}}}}},"responses":{"200":{"$ref":"#/components/responses/ProposalReplayed"},"201":{"$ref":"#/components/responses/ProposalCreated"},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"A person with this slug already exists. Use target_person_slug_or_id to propose updates instead.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/agents/proposals/person-role":{"post":{"summary":"Propose attaching a person to an entity in a specific role","description":"Connect an existing person to an existing entity via person_entity_roles (Track P). On accept, inserts a person_entity_roles row. Use `start_date`/`end_date` for historical roles (e.g. an ex-CEO who left in 2024). For brand-new people, submit /agents/proposals/person first.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["person_slug_or_id","entity_slug_or_id","role_kind"],"properties":{"person_slug_or_id":{"type":"string"},"entity_slug_or_id":{"type":"string"},"role_kind":{"type":"string","enum":["founder","ceo","cfo","head_of_treasury","board","investor","advisor","employee","ex_employee","partner_contact"]},"role_label":{"type":"string","nullable":true,"maxLength":200,"description":"Free-text refinement, e.g. 'Head of Treasury, EMEA'."},"is_primary":{"type":"boolean"},"start_date":{"type":"string","format":"date","nullable":true},"end_date":{"type":"string","format":"date","nullable":true},"rationale":{"type":"string","maxLength":2000},"confidence":{"type":"integer","minimum":1,"maximum":5}}}}}},"responses":{"200":{"$ref":"#/components/responses/ProposalReplayed"},"201":{"$ref":"#/components/responses/ProposalCreated"},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/agents/proposals/segment-lore-update":{"post":{"summary":"Propose an update to a SEGMENT's Dossier narrative","description":"Update the qualitative Dossier body for an ecosystem segment (mining, custody, treasuries, lightning, etc.). Macro twin of /agents/proposals/lore-update. Submit the FULL new body (not a diff). The accept step replaces the canonical segment dossier body and preserves the prior state in segment_lore_versions. Always read the existing dossier via GET /segments/{slug}?include=lore before proposing, and submit additive edits.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["target_segment_slug","proposed_body","diff_summary"],"properties":{"target_segment_slug":{"type":"string","description":"Segment slug. Must match a slug from GET /v1/segments."},"proposed_body":{"type":"string","maxLength":50000,"description":"Full new segment dossier body in markdown."},"diff_summary":{"type":"string","maxLength":200,"description":"One-line description of what changed. Shown on the inbox card."},"rationale":{"type":"string","maxLength":2000,"description":"Brief justification (sources, conversations, observations)."},"confidence":{"type":"integer","minimum":1,"maximum":5}}}}}},"responses":{"200":{"$ref":"#/components/responses/ProposalReplayed"},"201":{"$ref":"#/components/responses/ProposalCreated"},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}}}}