people

Create person

Manually add a person to a playtable (single row; bulk ingestion is a playtable-run of type import). The dedup ladder is team-scoped, two tiers: identity keys (ln_member_id, raw ln_id / sn_id / recruiter_id, emails) and flag keys (ln_nickname, phones).

An identity-tier hit: without on_duplicate → 409 duplicate_rejected with context { existing_sid, already_in_playtable_sid, matched_identifier_kind }; on_duplicate:"skip" → the existing row, already_exists:true; "move" → re-homed into the target playtable. A flag-tier hit (nickname, phone) without on_duplicate CREATES the row flagged status=duplicate (duplicate_of_sid set); an explicit on_duplicate resolves it the same way as identity.

No identity field at all → status=no_contact_data (dedup skipped; enrichment can lift it to ok). A stoplist check runs at insert → status=stoplisted on match. A LinkedIn URL is parsed to its identifier axes at the edge; emails lowercase. full_name, avatar_url and company_name are manual observations of the birth (the item's context shows them), never columns.

When NOT: bulk import / bulk delete / moving batches (playtable-runs), profile content like position or location (playtable field values, not entity columns).

Contract:

  • MCP tool create_person, registry package mcp.playtables/people, mount playtables.people.
  • Operation create, response envelope create.
  • Flags: none.
post/api/people

Request

  • Base URL
    https://beta.getsales.io/playtables/v1
  • Auth
    HTTP bearer and API key in header Team-SID

Request body

playtable_sidstring required

Target table (pt_tb_…) - the person's single membership.

full_namestring nullable

Display name, 1..255: a manual observation (it outranks every source until reset), never a column; null = unnamed until a source names the row.

avatar_urlstring uri nullable

Profile photo URL (max 2048): a manual observation like full_name, never a column; null = no picture known.

ln_member_idstring nullable

LinkedIn member urn id - strongest dedup key.

ln_idstring nullable

Raw LinkedIn profile URN (ACoAA…); no spaces. Decodes to ln_member_id.

sn_idstring nullable

Raw Sales Navigator URN (ACwAA…); no spaces. Decodes to the same ln_member_id.

recruiter_idstring nullable

Raw Recruiter URN (AEMAA…); no spaces. Decodes to the same ln_member_id.

ln_nicknamestring nullable

Vanity slug, or a profile URL: the service reduces a URL to its axis (a slug, or a URN moved to ln_id / sn_id / recruiter_id) and never stores the URL (SERVICE_CONVENTIONS §Y). Counts as contact data; dispatch still needs a URN.

work_emailstring email nullable

Stored lowercased - 3rd dedup key (with personal_email).

personal_emailstring email nullable

Personal address; stored lowercased, a dedup key together with work_email.

work_phone_numberstring nullable

Plain string, E.164 preferred.

personal_phone_numberstring nullable

Plain string, E.164 preferred; richer phone sets are field values.

company_sidstring nullable

Must exist; the person's company then resolves from the account (context.company).

company_namestring nullable

A name that is not an account, a manual observation; read only when company_sid is absent.

tag_sidsstring[] nullable

Each tag must exist (cr_tg_…).

external_refsobject nullable

Free-form CRM sync map; keys integration-defined, stored as-is.

on_duplicate'skip' | 'move'

skip = return the existing row; move = re-home it into playtable_sid. Applies on BOTH dedup tiers when given. Omitted: an identity-tier hit is 409, a flag-tier match (nickname, phone) is born flagged.

Response

create success envelope.

successtrue required
operation'create' required
already_existsboolean required

Changes

No recorded changes to this operation across all 1 revision of this API.