Get started with Peers
Peers matches the people in your space and auto-delivers introductions to your best matches, you're always in control. Pick how you drive it, talk to it through your AI assistant, or call the REST API. Most people connect through Claude and never touch the API.
Overview
A space is any group you want to make introductions within, an event, a community, a cohort, a network. People join and share what they need and offer. Peers looks for complementarity, scores candidate pairs, and auto-introduces your best matches directly: you're always in control (switch to approve-first or opt out anytime).
Connect, two ways
Both paths reach the same Peers. Start with your assistant; drop to the API only if you're building something custom.
Through your AI assistant
Recommended- 1Add
https://api.linkpeers.com/mcpto Claude, ChatGPT, Gemini, or Grok. - 2Authorize once: your assistant runs the OAuth flow. No keys to paste.
- 3Just chat: "create a space", "import my guest list", "run matching." Done.
Call the REST API
For builders- 1
POST /v1/keys/request: get a one-time code by email. - 2
POST /v1/keys/exchange: trade it for anmm_sk_key. - 3Call
/v1with anAuthorization: Bearerheader. Done.
You don't have to write code. Connect through your assistant and ask in plain language, it calls the tools for you. The tool and endpoint reference below is there when you need the detail.
The flow
However you connect, the lifecycle of a space is the same:
Create a space
Ask your assistant to create a space and pick a slug. You become its organizer.
Bring people in
Share the join link so people add themselves through their own assistant, or import an existing list from CSV. Importing is optional.
Matching runs
Matching runs automatically, hourly, and whenever someone joins or updates their profile. You can also trigger a run on demand. Peers scores complementarity and stages the best pairs.
Auto-intros go out
By default, Peers auto-introduces your best matches directly by email: you're always in control (switch to approve-first or opt out anytime).
Try it free in 3 calls
You do not need a plan, real members, or real email addresses to see what Peers would do. Ask your assistant for these three, in order:
create_space({ name: "Trial", slug: "my-trial", sandbox: true })
A private throwaway space. It can never send email to anyone, is never billed, is never auto-matched, and nobody else can join it — so join links, QR codes and the share kit do not apply. A sandbox never becomes a live space, so give it a preview slug and keep the real name for the real room.
import_attendees({ slug: "my-trial", sample: true })
Loads Peers' roster of fictional people, all on @example.com addresses that cannot reach a real inbox. Their profiles take about a minute to be read. Or upload your own list instead — import_attendees({ slug, records: [...] }), up to 50 people, any columns; everything beyond email, name and linkedin is read as free text, so a paragraph per person works better than a title alone. Use a real list only if you are allowed to share those people's details.
dry_run_matching({ slug: "my-trial" })
The real engine with sending switched off: every pair it would introduce, every pair it declined and why, and the actual email each pair would have received. The response carries a reportUrl you can open in a browser. Edit the space's matchPolicy with update_space and run it again to see exactly what your change did.
Calling a tool: payload and response
Normally your assistant does this for you. If you are driving MCP directly, every call is
JSON-RPC over POST /mcp with your API key in the Authorization
header. Tool arguments are the parameters listed for each tool below.
# Request POST /mcp Authorization: Bearer mm_sk_... Accept: application/json, text/event-stream { "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "dry_run_matching", "arguments": { "slug": "founders-2026", "refresh": true } } }
Every tool replies in the same envelope: a content array whose first entry is
text. Most tools return prose written for an assistant to relay. A few return JSON inside
that text so it can be reasoned over rather than read aloud, and dry_run_matching
is one of them.
# Response envelope (all tools) { "jsonrpc": "2.0", "id": 1, "result": { "content": [ { "type": "text", "text": "..." } ] } } # The text of a finished dry_run_matching, parsed { "status": "ready", "policyVersion": 3, "counts": { "candidates": 45, "judged": 12, "accepted": 3, "rejected": 9 }, "accepted": [ { "a": "Rhiannon Beck", "b": "Noor Haddad", "score": 0.88, "aGains": "...", "bGains": "...", "nextStep": "...", "risk": "low" } ], "declined": [ { "a": "Noor Haddad", "b": "Gustav Lindqvist", "why": "not_useful", "explanation": "Judge found no useful exchange: a judge/policy decision", "note": "..." } ], "changedSinceLastRun": { "added": [], "removed": [], "policyChanged": true } }
A first call returns {"status":"started"} instead: matching is asynchronous, so
wait ten to thirty seconds and call again to read the finished report. Other statuses you may
get back are rate_limited, in_flight, and a plan or member-floor
refusal, each with a message explaining what to do about it. Two declined
categories are not policy rejections and say so in their explanation:
lost_to_cap (approved, but over the space's pace) and not_judged
(outranked by stronger candidates).
Mutating tools are marked Mut. Read-only API keys are rejected
on those. Errors come back as a JSON-RPC error with a message written to be shown
to the user.
Organizer tools
For the person who runs the space. MUT marks a tool that changes data (blocked for read-only access).
Question-generation cost: if you do not provide questions, Peers generates them once when the space is created. Owner-authored questions skip that call and stay unchanged when goals change. Switching back to generated questions requires an explicit regenerateIntakeQuestions: true, which queues one generation call.
sandbox: true for a private throwaway space that can never email anyone: it is free to dry-run on any plan and is how you preview matching before inviting real people.name, slug, type?, description?, matchingGoals?, matchPolicy?, intakeQuestions?, sandbox?, listed?csv: a plain email/name list; those people still have to add their own needs and offers. records: an enriched list whose columns (title, company, looking_for, offers, linkedin) become a matchable profile immediately — Pro on a real space and requires attestPermission: true; free and unattested on a sandbox (up to 50 on a sandbox). sample: true: loads Peers' fictional roster into a sandbox space so a dry run has something to judge; refused on a real space. Profiles take about a minute to be read.slug, csv?, records?, sample?, attestPermission?reportUrl, the browser page for this space's dry runs. Re-runs automatically when the match policy version moves; pass refresh after a roster change. Status no_candidates means the run judged nothing (usually profiles were still being read): wait about a minute and call again rather than editing the policy. Free on a sandbox space, Pro on a real one; 10 runs per space per rolling 24 hours.slug, refresh?status is draft, active, or paused.slug, status, memberCapacity, price, currency, refundPolicy, defaultIntrosPerWeek?, defaultIntrosPerMonth?Participant tools
For everyone in a space: including the organizer, who is also a participant. A member never needs the website: their assistant can join, build a profile, browse the room, ask for an introduction and accept one, entirely through these tools.
referralCode: the person who invited you gets connected to you with a warm intro (and those intros don't count against anyone's weekly/monthly caps).slug, copyFromSlug?, referralCode?text.memoryId, text?slug to read current settings back without changing anything. matchStrictness: exploratory (widest, allows specific low-risk inferred matches), balanced (default), or selective (strongest explicit value only). accountIntrosPerWeek caps total introductions across every space; introsPerWeek/introsPerMonth set the pace for this space only. maxRequestsFromOthers caps how many people per week may ask to be introduced to you. referralIntros: whether people who join with your invite code get auto-connected to you (default on; these don't count toward your caps either way). Optionally add LinkedIn/phone shared only after mutual consent.slug, consentMode?, introCap?, introsPerWeek?, accountIntrosPerWeek?, maxRequestsFromOthers?, introsPerMonth?, matchStrictness?, referralIntros?, outreachOptOut?, linkedinUrl?, phone?, sharePhone?sensitiveAck.slug, sourceMemoryId?, sensitiveAck?, mode?REST API, authentication
Every request carries an API key in the Authorization header. Create one by
requesting a one-time code by email, then exchanging it. Read-only keys are rejected on any
write (non-GET) request. Paths are versioned under /v1.
# 1. Request a one-time code POST /v1/keys/request { "email": "you@example.com" } # 2. Exchange the emailed code for a key POST /v1/keys/exchange { "email": "you@example.com", "code": "1234", "name": "my-app" } → { "apiKey": "mm_sk_…", "keyPrefix": "mm_sk_…", "permissionLevel": "read_write" } # 3. Use it on every request Authorization: Bearer mm_sk_…
Spaces
matchPolicy accepts objective, mustHave[],
prefer[], avoid[], and organizerReview[].
Matching configuration is private to the organizer.
matchPolicy and intakeQuestions. Returns joinUrl and configuration state.regenerateIntakeQuestions: true for one generation job (organizer only).Chat & profile
{ message }. Returns { reply, done }.Import
Import a CSV directly, or presign an S3 upload for larger files.
file, ≤10MB). Enqueues an import job.{ records[], attestPermission }.{ filename }.{ storageKey }.Introductions
Consent and feedback are token-authenticated links delivered by email: no API key needed. They render a confirmation page and are idempotent.
side a|b, action accept|decline, signed ?t=.verdict up|down, signed ?t=.Keys & sign-in
mm_sk_ key.MCP clients don't use API keys. The /mcp endpoint authenticates
over OAuth 2.0 (PKCE), which your assistant negotiates automatically. API keys are only for direct REST calls.