facade
Manage Person
Create and manage people in your pipeline — the consolidated person writer.
Actions (id = person UUID unless noted):
- create: add a person manually (no id; payload = {first_name, last_name, company_name, email and/or linkedin_url (at least one), title?, company_website?, phone?, location?, objective_id?, skip_research?}); bulk via items (one payload per person).
- update_contact: override contact fields (payload = contact overrides).
- set_position: make one of the person's current positions their primary position for this workspace (payload = {company_id}).
- add_position: record a current or former role (payload = {company_name, title?, company_id?, relationship_type? (employment| founder|advisor|board|contractor|other), is_current? (default true), started_at_raw?, ended_at_raw?, make_primary? (current roles only)}). Positions are shared facts about the person; make_primary also makes it the role this workspace shows. The response's change names what the add created and the primary position it replaced.
- task: create a follow-up task on the person (payload = {title, description?, due_at? (ISO), priority? (low|medium|high|urgent), assigned_to?}). The response's task id and updated_at identify it.
- note: add a timeline note (payload = {body}).
- log_interaction: log a manual touch that happened outside an automated sequence — a call (with disposition + what was said), or an email/LinkedIn/other touch made elsewhere. payload = {interaction_kind: call|email|linkedin|meeting|other, direction?: outbound|inbound, summary?, disposition? (calls only), occurred_at? (ISO, backdatable), deal_id?}. Lands on the person's timeline attributed to you (performed_by_user_id).
- archive: soft-delete one or many people — stops outreach plans and rejects pending drafts (id or id array; no payload). DESTRUCTIVE.
- unarchive: restore archived people (id or id array; no payload).
- meeting_booked: mark a meeting booked with this person (payload = {idempotency_key: UUID}; reuse it when retrying the same booking).
- save_discovered: THE creator — save a researched prospect into the pipeline, atomically (no id; bulk via items). Two shapes: NEW prospect: payload = {person: {first_name, last_name, linkedin_url|email, company_id (from research action=save_company) or company_name plus company_domain/company_website/company_linkedin_url, ...research fields}, assessment: {match_score 0-100, match_summary, alignment_points?, concerns?, why_now?, recommended_approach?, overall_confidence?, scored_by?}, objective_id or assessment_objective_id}. Person + research + pipeline membership land in ONE transaction — a rejected or failed save persists nothing. EXISTING person: payload = {person_id, company_id, objective_id?, assessment_objective_id?, assessment?}; if company_id is unavailable, pass company_name plus at least one top-level company_domain, company_website, or company_linkedin_url. Never send a bare person_id: the binding atomically adds/promotes the current position and pins the pipeline membership while the assessment is applied update-in-place (THE path to score an existing stub). Pass exactly one of person / person_id. Use assessment_objective_id to preserve objective-scoring provenance without assigning the person. Your assessment is AUTHORITATIVE: the backend records it with provenance and never re-scores it. Backend floor stays mechanical: dedupe first (anchors resolving to an existing person continue as a duplicate update); new rows require a LinkedIn URL or email and stay within the per-tenant discovery-volume cap; the person shape requires assessment + an objective ref (did no fit analysis? use action=create instead). Duplicates do not consume or re-check the new-row cap. The response includes company_id and company_bound; require company_bound=true before treating the save as company-complete or calling manage_outreach action=start. If false, do not enroll—repair the company binding and retry save_discovered.
- set_persona: set a contact's buying-center role (Revenue Architecture Table 8.2) — initiator / user / champion / decider / gatekeeper / influencer / executive_buyer / approver / purchaser / unknown (payload = {persona, reasoning?}).
- set_meeting_purpose: say what a meeting was for (id = the meeting id, the source_id of a relationship-history event whose source_type is meetings, or li:<interaction id> for a logged meeting; payload = {purpose} — discovery / demo / proposal / negotiation / commit / kickoff / impact_review / renewal / expansion / winback / internal / other, or null to clear). The seller's word outlives the calendar title; a held meeting's timeline event moves to the new purpose's practice. The harness classifies buying role at touch time and writes it here; there is no backend classifier.
- set_meeting_no_show: mark a meeting as a no-show, or undo the mark (id = the meeting id: the source_id of a fetch type=relationship_history_detail event whose source_type is meetings; payload = {no_show: true|false}). A meeting with an external person counts toward a meeting objective once it starts unless it was cancelled or marked; only a started meeting can be a no-show (409 otherwise). Undo restores its earlier outcome.
- adopt_directory: add an existing shared canonical person to this tenant's CRM (id = directory person UUID; no payload). This copies no tenant-private notes, activity, objective, score, or outreach state. It is free for the tenant.
Bulk: id arrays apply the same action to each person (archive/unarchive route to the native bulk endpoints; others loop with per-item status — partial failure is reported per item, never silent). items is for create-like actions, max 100 per call. Payloads are validated by the underlying route's own schema, so a bad field returns that route's precise 422.
post/api/facade/manage_person
Request
- Base URL: https://api.vruum.ai
- URL: https://api.vruum.ai/api/facade/manage_person
- Auth: HTTPBearer (a scheme the document does not define)
Request body
Response
Successful Response
unknown required
Changes
No recorded changes to this operation across all 1 revision of this API.