Nexus Partner API

Connection intelligence, built into your product.

Give your product the ability to understand who should meet, who can help, and why.

Nexus turns the people already inside your platform into intelligent search, personalized recommendations and ranked connections. You send the context you already have. Nexus returns the right people, in order, with a clear reason for every result.

Your product. Your experience. Nexus intelligence underneath it.

3 endpoints
Everything you need
Your UI
No Nexus-branded experience required
Your IDs
Results map directly back to your data
API key
Simple server-side authentication
Your first call
curl -X POST https://www.nexus.app/api/partner/{partner}/search \  -H "x-partner-api-key: $NEXUS_PARTNER_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "query": "climate fintech founders in Nairobi",    "limit": 5  }'

Build it with your coding agent

Copy a complete implementation brief for Claude Code, Cursor or another coding agent. It includes the API contract, endpoint behavior and examples. Add your API key and start building.

Overview

Give your product a superconnector

Your product already has the people. Nexus gives it the intelligence to understand how they should connect.

Search your entire network in plain English. Find the best people for any individual. Rank mentors against founders, investors against companies, members against opportunities, or any other relationship your product needs to understand.

Nexus does the hard part: understanding context, relevance, complementary needs, expertise and connection potential. Your application decides where that intelligence appears and what happens next.

Instead of building and maintaining your own people-search infrastructure, embedding pipeline, ranking logic, matching models and explanation layer, you make an API call. Nexus returns your own IDs, ranked by relevance, with a plain-English reason explaining each result.

1

Give Nexus context

Sync the people and profile information you want Nexus to understand.

2

Ask Nexus

Search in natural language, or ask Nexus to find the strongest connections for a particular person.

3

Use the intelligence anywhere

Receive ranked results using your own IDs, scores and explanations. Display them, trigger introductions, create recommendations, power workflows or apply your own business rules.

Three endpoints cover the whole surface.

Your system stays the source of truth

You do not move your product into Nexus. Your system remains the source of truth for your users and your business logic.

Nexus maintains the intelligence required to search and match the profile information you choose to provide. Every result comes back using the external_id from your system, so it maps directly into the product you already have.

Your dataset stays isolated

Your partner dataset is private to your integration. It does not appear on public or guest Nexus pages, it is not included in any Nexus community search, and it is not used in Nexus campaigns. It can only be read with your partner API key.

Nexus returns your identifiers, never its own internal IDs.

Everything you sync is member-visible by design

Synced fields feed the ranking and are quoted in the reasons returned by search and match. Treat every field as text a member could read. Do not send admin-private notes or internal commentary. The API cannot leak what it was never sent.

Use cases

What connection intelligence lets you build

These are examples, not product constraints. Nexus returns connection intelligence through the API; how you use it is entirely up to you.

1. Natural-language people search

Turn any directory, marketplace or network into intelligent search. A user can type:

  • "Fintech founders who have sold into large banks"
  • "Investors interested in climate hardware"
  • "Someone who has scaled a marketplace in Latin America"

Nexus understands the intent, ranks the people in your network and explains why each result is relevant. One /search request. No search syntax for the user to learn.

On your side, render each result straight from display and reason, and show display_score as the badge. Because the reason is generated from the person's own synced fields, it doubles as the card's subtitle.

2. Personalized "people you should meet"

Give every user recommendations that feel hand-picked. Pass Nexus a person and receive the strongest connections for them, ranked by relevance and accompanied by an explanation of why the two people should connect.

Use it for member recommendations, founder and investor discovery, internal experts, networking, customer communities, professional marketplaces or advisor discovery. It can power a recommendation feed, a profile sidebar, a weekly email, an introduction workflow or anything else you build.

One /match request with the person's id in whole-dataset mode returns the top limit people with a reason for each.

3. Intelligent matching at scale

Power structured matching without reducing people to tags and filters.

  • Mentors ↔ founders
  • Advisors ↔ companies
  • Buyers ↔ suppliers
  • Investors ↔ startups
  • New members ↔ established members

Your application controls hard eligibility rules such as geography, availability, language, programme or capacity. Nexus handles the harder question: out of everyone who is eligible, who is actually the best match? Send Nexus the candidate IDs and it ranks the pairings and explains each one.

Technically: filter to the eligible ids on your side, send them as candidate_external_ids to /match, apply your own threshold to relevance, and write the outcome to your own matches table. Nothing is stored on the Nexus side, so you can re-run whenever the roster changes.

4. Smarter onboarding from day one

A new user should not have to spend weeks discovering who matters. As soon as somebody joins your product, Nexus can identify the people most relevant to them and explain why.

Use those results for "people you should meet", suggested mentors, relevant investors, recommended experts, useful peers or a personalized welcome email.

A newly synced member is available for matching immediately after a successful sync, so onboarding recommendations can happen in the same workflow: sync, then /match, in one job.

5. Understand the intelligence inside your entire networkEarly access

Search tells you who matches a question. Match tells you who should connect with a person. The Nexus knowledge graph goes one level higher: it helps your product understand the network itself.

  • What does this group collectively know?
  • What are people trying to accomplish?
  • Where is demand concentrated?
  • Where does relevant expertise exist?
  • Which valuable connections have not happened yet?

Nexus maps topics, industries, organizations, expertise, needs and opportunities across the people you provide, then returns that intelligence using your own identifiers. Use it to build network analytics, identify unmet demand, surface opportunities or automatically create high-value introductions.

Contact Nexus to enable knowledge graph access for your partner account.

Authentication

One API key. That's it.

Every Partner API request uses your server-side partner API key in the x-partner-api-key header. Nexus provides the key when your partner account is provisioned and delivers it out of band. Keep it server-side and you are ready to make authenticated requests. There is no query-string or body alternative, and no self-service key management.

Authenticated request
curl -X POST https://www.nexus.app/api/partner/{partner}/match \  -H "x-partner-api-key: $NEXUS_PARTNER_API_KEY" \  -H "Content-Type: application/json" \  -d '{ "subject_external_id": "acme-1042" }'

The key is compared in constant time. A missing or incorrect key returns 401 with the standard error envelope and the code unauthorized. Authentication is checked before anything else, so an unauthenticated call never consumes budget and never touches your data.

Conventions

Simple, predictable API behavior

The Partner API is deliberately small. Three POST endpoints, JSON request bodies, JSON responses and one authentication header.

Base URL and transport

All endpoints are served over HTTPS from https://www.nexus.app. Every endpoint is a POST with a JSON body and returns JSON. Send Content-Type: application/json. Responses are computed per request and never cached.

Every path contains a partner segment, shown here as {partner}. It is the slug assigned to your tenant at provisioning and is confirmed alongside your key. Paths are otherwise identical for every partner.

Error envelope

Every non-2xx response has the same shape: an error object with a machine-readable code and a human-readable message. Branch on the code, never on the message.

400 example
{
  "error": {
    "code": "missing_query",
    "message": "query is required."
  }
}

Budget responses add one top-level field, retry_after_seconds, the number of seconds until the daily budget resets.

429 example
{
  "error": {
    "code": "search_cap_exceeded",
    "message": "Daily search budget reached."
  },
  "retry_after_seconds": 18342
}

Order of checks

Each endpoint evaluates a request in the same order. Knowing it explains which error you see first.

  1. Authentication. A bad key returns 401 immediately.
  2. Daily budget. An exhausted budget returns 429.
  3. Body validation. A missing or invalid field returns 400.
  4. Tenant lookup. A partner tenant that is not provisioned returns 500 with partner_group_missing.
  5. The work itself.

Budget is consumed before validation

Because the budget check runs before the body is validated, an authenticated call that is rejected with 400 still counts against that day's budget. Validate on your side before retrying in a loop.

Malformed and unknown input

A body that is not valid JSON is treated as an empty body, so you receive the endpoint's "required field missing" error rather than a parse error. Unknown fields in a request are ignored. String inputs are trimmed before validation, so a value of only whitespace counts as missing.

Idempotency and state

Sync is idempotent: replaying the same batch produces the same dataset. Search and match are stateless reads. Nexus stores nothing per call beyond an anonymous daily counter, so re-running either is always safe.

Endpoint 1

Sync members

Give Nexus the people and context its connection intelligence should reason over.

Create, update or remove up to 200 people per request using the stable external_id from your own system. Once a record is successfully indexed, it is immediately available to search and match.

POST/api/partner/{partner}/members/sync

Request body

The body is an object with one key, members, holding 1 to 200 record objects. Each record has the fields below. Anything not listed is ignored.

Sync request fields
FieldTypeRequiredConstraintsDescription
external_idstringRequiredNon-empty after trimming. Must be stable across calls.Your identifier for the person. It is the upsert key and the identifier returned by every read endpoint.
emailstringRequiredMust look like an email address. Stored trimmed and lower-cased.Used to link a record to a person Nexus already knows when no record with this external_id exists yet.
first_namestringOptionalNoneGiven name.
last_namestringOptionalNoneFamily name.
titlestringOptionalTruncated to 100 characters with a warning.Job title or role.
organizationstringOptionalTruncated to 100 characters with a warning.Company or organisation name. Returned as display.organization.
aboutstringOptionalNoneFree-text bio. No length cap.
match_contextstringOptionalTruncated to 2,000 characters with a warning.Free-text context about what this person is working on, looking for, able to help with or hoping to accomplish. One of the highest-value fields you can provide for connection quality.
skillsstring[]OptionalDeduplicated case-insensitively, capped at 20 with a warning. A non-array is treated as empty.Expertise tags. Casing is normalised for display.
interestsstring[]OptionalDeduplicated case-insensitively, capped at 20 with a warning. A non-array is treated as empty.Interest tags. Casing is normalised for display.
citystringOptionalNoneCity. Combined with country to form display.location.
countrystringOptionalNoneCountry.
linkedinstringOptionalMust be a linkedin.com/in/ profile URL, otherwise dropped with a warning.LinkedIn profile URL.
websitestringOptionalNormalised to an absolute URL; https:// is added when missing.Personal or company website.
status"active" | "removed"OptionalDefaults to "active". Any other value rejects the record."removed" takes the person out of your dataset and out of every search and match result.
Request
{
  "members": [
    {
      "external_id": "acme-1042",
      "email": "priya.raman@example.com",
      "first_name": "Priya",
      "last_name": "Raman",
      "title": "Co-founder & CTO",
      "organization": "Northwind Grid",
      "about": "Building battery storage for rural micro-grids.",
      "match_context": "Pre-seed. Wants a power-electronics advisor and hardware angel intros.",
      "skills": ["embedded systems", "power electronics"],
      "interests": ["climate tech", "hardware fundraising"],
      "city": "Nairobi",
      "country": "Kenya",
      "linkedin": "https://www.linkedin.com/in/priya-raman-example",
      "website": "northwindgrid.example.com",
      "status": "active"
    },
    {
      "external_id": "acme-0871",
      "email": "tomas.lindqvist@example.com",
      "status": "removed"
    }
  ]
}

How a record is applied

Nexus first looks for a member in your dataset with the same external_id. If none exists, it looks for a person with the same email. What happens next depends on what it finds.

  • Nobody found. A new member is created from the record and reported as created.
  • A person that only your dataset knows. Your record is the source of truth: name and profile fields are overwritten verbatim and the skills and interests lists are replaced.
  • A person who also exists elsewhere on Nexus. The membership in your dataset is attached, only fields that are currently empty are filled, tags are added rather than replaced, and the person's name is left alone. The result carries linked_existing_user: true.

In both of the last two cases the result is created when the person was not previously in your dataset and updated when they were. After every record in the batch has been applied, each created or updated member is re-indexed before the response is sent, so a successful result is searchable and matchable as soon as the call returns.

A status: "removed" record deletes the person's membership in your dataset. Removal is idempotent: removing someone who is not in your dataset still reports removed. Removing an external_id and email Nexus has never seen is rejected with not_found. Re-sending a removed person as active restores them.

Each record is applied in its own transaction. A record that fails is reported as rejected and the rest of the batch continues.

Response

200 response
{
  "batch_id": "6f1c9c2e-3b7a-4d0e-9a1b-2c3d4e5f6a7b",
  "results": [
    {
      "external_id": "acme-1042",
      "status": "created",
      "embedding": "refreshed"
    },
    {
      "external_id": "acme-0871",
      "status": "removed",
      "embedding": "skipped"
    }
  ],
  "summary": {
    "created": 1,
    "updated": 0,
    "removed": 1,
    "rejected": 0
  }
}
Sync response fields
FieldTypeMeaning
batch_idstring (UUID)Identifier of this batch. Quote it when contacting support about a sync.
resultsobject[]One entry per record, in the same order as the request.
results[].external_idstring | nullYour identifier. Null when the record had no usable external_id (invalid_payload or missing_external_id).
results[].status"created" | "updated" | "removed" | "rejected"What happened to the record.
results[].codestringPresent only when status is rejected. One of the rejection codes below.
results[].messagestringPresent only on rejected records. Human-readable explanation.
results[].warningsstring[]Present only when a field was truncated or dropped. The record was still applied.
results[].linked_existing_usertruePresent only when the record was linked to a person who also exists elsewhere on Nexus.
results[].embedding"refreshed" | "failed" | "skipped"Present on created, updated and removed records. refreshed means the member is live in search and match. failed means the index update did not complete: re-send the record to retry. skipped is the value for removals.
summaryobjectCounts of created, updated, removed and rejected records in this batch.

Two more shapes a result entry can take:

Result entries with warnings, and a rejection
{
  "external_id": "acme-2210",
  "status": "updated",
  "linked_existing_user": true,
  "warnings": [
    "title truncated to 100 characters",
    "linkedin dropped: not a linkedin.com/in/ profile URL"
  ],
  "embedding": "failed"
}

{
  "external_id": "acme-3305",
  "status": "rejected",
  "code": "invalid_email",
  "message": "email \"not-an-address\" is not a valid address."
}

Rejection codes

A rejected record never fails the batch. The HTTP status is still 200 and the other records are applied.

  • invalid_payloadThe record is not a JSON object.
  • missing_external_idexternal_id is absent or empty.
  • missing_emailemail is absent or empty.
  • invalid_emailemail does not look like an address.
  • invalid_statusstatus is something other than "active" or "removed".
  • not_foundA removal named a person Nexus has never seen.
  • internal_errorThe record failed to process. Its transaction was rolled back; the rest of the batch continued.

Errors

Sync error responses
StatusCodeWhenBody
401unauthorizedMissing or incorrect API key.{ "error": { "code": "unauthorized", "message": "Invalid or missing x-partner-api-key." } }
429sync_cap_exceededDaily sync budget reached.{ "error": { "code": "sync_cap_exceeded", "message": "Daily sync budget reached." }, "retry_after_seconds": 18342 }
400invalid_batchBody is not { members: [...] }, or the array is empty or longer than 200.{ "error": { "code": "invalid_batch", "message": "Body must be { members: [...] } with 1 to 200 records." } }
500partner_group_missingYour partner tenant is not provisioned.{ "error": { "code": "partner_group_missing", "message": "Partner group is not provisioned." } }
500internal_errorThe batch failed as a whole. Records already committed stay committed.{ "error": { "code": "internal_error", "message": "Sync failed; quote the batch_id in support.", "batch_id": "6f1c9c2e-3b7a-4d0e-9a1b-2c3d4e5f6a7b" } }

Endpoint 3

Match

Find the right connections for any person.

Give Nexus one person, the subject, and it ranks the people most relevant to them. Nexus looks at the context available for both sides of the relationship and returns the strongest pairings, with a relevance score and a clear explanation of why each connection makes sense.

Search answers "who fits this request?". Match answers "who should this person meet?". You can let Nexus rank across the full dataset, or pass a specific eligible group and have Nexus rank only those people.

POST/api/partner/{partner}/match

Request body

Match request fields
FieldTypeRequiredConstraintsDescription
subject_external_idstringRequiredNon-empty after trimming. Must be a member of your dataset.The person to find matches for.
candidate_external_idsstring[]OptionalWhen present: 1 to 200 non-empty strings. Duplicates are removed.Rank exactly these people. Every id you send is accounted for in the response. Omit to rank your whole dataset.
limitintegerOptional1 to 100. Default 36. Clamped, truncated and defaulted the same way as search.Maximum results when candidate_external_ids is omitted. Ignored when candidates are supplied: the whole list is ranked.
include_reasonsbooleanOptionalDefault true. Only an explicit false disables reasons.Set false to skip reason generation.
Request, explicit candidates
{
  "subject_external_id": "acme-1042",
  "candidate_external_ids": ["acme-1187", "acme-2210", "acme-1042", "acme-9999"],
  "include_reasons": true
}
Request, whole dataset
{
  "subject_external_id": "acme-1042",
  "limit": 10
}

Match everyone, or only the people you allow

  • Whole dataset (candidate_external_ids omitted). Let Nexus find the strongest connections from everyone available. Nexus ranks every eligible member of your dataset, excluding the subject, and returns the top limit. unmatched is always empty in this mode.
  • Your candidate set (candidate_external_ids supplied). Apply your own eligibility rules first, then let Nexus rank everyone who remains. Nexus ranks exactly that list. Every requested id appears either in results or in unmatched with a code. Nothing is silently dropped, and limit does not apply.

Ranking is deterministic: the same people with the same synced data produce the same order. Ties are broken in a stable order.

Candidates supplied, end to end
# 1. Your eligibility rules pick who is allowed to be matched.eligible_ids = pool.filter(p => p.accepting && p.languages.includes(person.language)) # 2. Nexus ranks exactly that list and explains each pairing.POST /api/partner/{partner}/match{ "subject_external_id": person.id, "candidate_external_ids": eligible_ids } # 3. Your threshold decides what gets surfaced. Store the outcome on your side.matches = response.results.filter(r => r.relevance >= YOUR_MIN_SCORE).slice(0, 3)

Response

200 response
{
  "subject_external_id": "acme-1042",
  "results": [
    {
      "external_id": "acme-1187",
      "rank": 1,
      "relevance": 0.6934,
      "reason": "Both are building climate-focused companies in Nairobi, and Amara's experience raising for hardware-adjacent products speaks to Priya's stated fundraising need.",
      "reason_source": "llm",
      "display": {
        "name": "Amara Okonkwo",
        "title": "Founder & CEO",
        "organization": "SunLedger",
        "location": "Nairobi, Kenya",
        "tags": ["Climate Finance", "Mobile Payments", "Angel Investing"],
        "avatar_url": "https://cdn.example.com/avatars/acme-1187.png"
      }
    }
  ],
  "unmatched": [
    { "external_id": "acme-1042", "code": "is_subject" },
    { "external_id": "acme-2210", "code": "no_embedding" },
    { "external_id": "acme-9999", "code": "unknown_external_id" }
  ]
}
Match response fields
FieldTypeMeaning
subject_external_idstringThe subject, echoed back trimmed.
resultsobject[]Ranked candidates, strongest first. The subject never appears.
results[].external_idstringYour identifier for the candidate.
results[].rankinteger1-based position in this response.
results[].relevancenumber0 to 1, four decimal places. Higher means a stronger pairing. Apply your own minimum before surfacing a match. Nexus ranks, you gate.
results[].reasonstringOne neutral, third-person sentence naming a checkable fit between the two people. Safe to show to either side.
results[].reason_source"llm" | "overlap"llm for a model-written sentence, available for up to the first 15 results. overlap for a deterministic sentence built from what the two profiles share.
results[].displayobjectSame card block as search: name, title, organization, location, tags, avatar_url.
unmatchedobject[]Requested candidates that could not be ranked, each with external_id and a code.

Codes in unmatched:

  • is_subjectThe candidate is the subject.
  • unknown_external_idNo member of your dataset has this id.
  • not_searchableThe member exists but is not currently eligible to appear in results.
  • no_embeddingThe member has not been indexed yet. Re-sync the record; a successful sync reports embedding: "refreshed".

Note the differences from search: match results carry no type and no display_score, and the deterministic reason source is overlap rather than evidence. As with search, reasons degrade to the deterministic sentence and never cause an error.

Errors

Match error responses
StatusCodeWhenBody
401unauthorizedMissing or incorrect API key.{ "error": { "code": "unauthorized", "message": "Invalid or missing x-partner-api-key." } }
429match_cap_exceededDaily match budget reached.{ "error": { "code": "match_cap_exceeded", "message": "Daily match budget reached." }, "retry_after_seconds": 18342 }
400missing_subjectsubject_external_id is absent, not a string, or empty after trimming.{ "error": { "code": "missing_subject", "message": "subject_external_id is required." } }
400invalid_candidatescandidate_external_ids is present but not an array of 1 to 200 non-empty strings.{ "error": { "code": "invalid_candidates", "message": "candidate_external_ids must be 1 to 200 non-empty strings when provided." } }
404subject_not_foundNo member of your dataset has the subject id.{ "error": { "code": "subject_not_found", "message": "No synced member has this external_id." } }
422subject_not_embeddedThe subject exists but has not been indexed. Re-sync that record.{ "error": { "code": "subject_not_embedded", "message": "Re-sync this member to generate their embedding." } }
500partner_group_missingYour partner tenant is not provisioned.{ "error": { "code": "partner_group_missing", "message": "Partner group is not provisioned." } }
500internal_errorThe match failed. Safe to retry.{ "error": { "code": "internal_error", "message": "Match failed." } }

Limits

Clear limits. Predictable behavior.

Request sizes

Request size limits
LimitValueOver the limit
Records per sync call1 to 200400 invalid_batch
Tags per list (skills, interests)20Truncated with a warning
title, organization length100 charactersTruncated with a warning
match_context length2,000 charactersTruncated with a warning
Search results (limit)1 to 36, default 36Clamped
Search candidate fence1 to 1,000 ids400 invalid_candidates
Match results when candidates omitted (limit)1 to 100, default 36Clamped
Match candidate list1 to 200 ids400 invalid_candidates
Model-written reasons per responseFirst 15 resultsDeterministic sentence for the rest

Daily budgets

Each endpoint has a budget of calls per UTC day. Budgets reset at 00:00 UTC, and a 429 tells you exactly how long to wait in retry_after_seconds. Budgets are counted per endpoint for your tenant, not per IP address.

Daily budgets
BudgetCalls per UTC dayWhen exhausted
Sync500429 sync_cap_exceeded
Search5,000429 search_cap_exceeded
Match5,000429 match_cap_exceeded
Search reasons (model-written)5,000Reasons fall back to evidence sentences. No error.
Match reasons (model-written)5,000Reasons fall back to overlap sentences. No error.

The values above are the current defaults.

Errors

Errors

Consistent error handling across every endpoint.

HTTP-level errors use the envelope described under Conventions. Per-record sync rejections arrive inside a 200 body and are listed under Sync.

All HTTP error codes
StatusCodeWhenBody
401unauthorizedAny endpoint. Missing or incorrect x-partner-api-key.{ "error": { "code": "unauthorized", "message": "..." } }
429sync_cap_exceededSync. Daily budget reached.{ "error": { ... }, "retry_after_seconds": 18342 }
429search_cap_exceededSearch. Daily budget reached.{ "error": { ... }, "retry_after_seconds": 18342 }
429match_cap_exceededMatch. Daily budget reached.{ "error": { ... }, "retry_after_seconds": 18342 }
400invalid_batchSync. members is missing, empty or longer than 200.{ "error": { "code": "invalid_batch", "message": "..." } }
400missing_querySearch. query is missing or empty.{ "error": { "code": "missing_query", "message": "..." } }
400missing_subjectMatch. subject_external_id is missing or empty.{ "error": { "code": "missing_subject", "message": "..." } }
400invalid_candidatesSearch or match. candidate_external_ids present but malformed or over the cap.{ "error": { "code": "invalid_candidates", "message": "..." } }
404subject_not_foundMatch. The subject is not in your dataset.{ "error": { "code": "subject_not_found", "message": "..." } }
422subject_not_embeddedMatch. The subject has not been indexed yet.{ "error": { "code": "subject_not_embedded", "message": "..." } }
500partner_group_missingAny endpoint. Tenant not provisioned.{ "error": { "code": "partner_group_missing", "message": "..." } }
500internal_errorAny endpoint. Unexpected failure. Sync includes batch_id.{ "error": { "code": "internal_error", "message": "..." } }

Retry guidance: 429 after retry_after_seconds; 500 on search and match immediately, since both are stateless; 500 on sync by re-sending the batch, since every record is idempotent and records that already committed are unaffected. Never retry a 400, 401, 404 or 422 without changing the request.

Operations

Production behavior

Everything below is what you need to know about timeouts, freshness, identifiers and retries when running the Partner API in production.

Timeouts

A sync call indexes every created or updated member before it responds, one at a time, so a full batch of 200 can take minutes. The sync handler may run for up to 300 seconds; set your client timeout at least that high, and prefer smaller batches when you need faster feedback. Search and match handlers may run for up to 60 seconds; typical responses are far quicker, and sending include_reasons: false removes the slowest step.

Freshness

A member whose sync result reports embedding: "refreshed" is live in search and match the moment the call returns. A member reporting embedding: "failed" keeps their previous index state until you re-send the record. A removed member disappears from both surfaces immediately.

Identifiers

Stable external_id values are load-bearing. Nexus matches by id first and by email second, so an id that changes on your side creates a second person on the next sync. If ids can change, say so before go-live.

What is never returned

No Nexus internal identifiers, no email addresses, no raw synced text other than what appears in display and the reason sentence, and no member who is not in your dataset. Search and match responses only ever contain people carrying one of your external ids.

Support

Quote the batch_id from a sync response when reporting a sync problem. It lets Nexus find the exact batch, its per-record outcomes and its timing.

Put Nexus connection intelligence inside your product.

Your users already have people they should know. Nexus gives your product the intelligence to find them. Search, recommend and match people natively inside your own experience without building the connection intelligence stack yourself.

Get a partner API key and we will provision your account, confirm your endpoints and help you make your first call.

Or hand it to your coding agent

Copy a self-contained implementation prompt for Claude Code, Cursor or another coding agent. It includes the complete API contract, typed client requirements, error handling and a smoke test. You provide the API key. It can handle the rest.