diff --git a/.github/workflows/docs-quality.yml b/.github/workflows/docs-quality.yml index 873bc07..6bb671f 100644 --- a/.github/workflows/docs-quality.yml +++ b/.github/workflows/docs-quality.yml @@ -52,3 +52,20 @@ jobs: redocly_output="$(npx --yes @redocly/cli@2.39.0 lint openapi.json --format json)" printf '%s\n' "$redocly_output" printf '%s\n' "$redocly_output" | jq -e '.totals.errors == 0 and .totals.warnings == 0' + + mintlify-deployment: + name: Mintlify Deployment + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: "22" + + - name: Validate Mintlify build + run: npx --yes mintlify@4.2.740 validate diff --git a/README.md b/README.md index eb6131c..4329435 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![API](https://img.shields.io/badge/API-REST-orange.svg)](https://www.lensmor.com/platform?utm_source=github&utm_medium=readme&utm_campaign=API-Doc) [![Docs](https://img.shields.io/badge/Docs-api.lensmor.com-green.svg)](https://api.lensmor.com/) -Lensmor provides developer-facing access to event, exhibitor, personnel, contact, and profile-matching data through the Lensmor API. +Lensmor provides developer-facing access to event, exhibitor, attendee-source, registered Visitor, contact, and profile-matching data through the Lensmor API. This repository hosts the public documentation site for developers integrating with [Lensmor](https://www.lensmor.com/?utm_source=github&utm_medium=readme&utm_campaign=API-Doc) — an AI-native event intelligence platform for B2B teams. @@ -14,6 +14,7 @@ Use the API to: - Check credit balance before running credit-consuming workflows - Browse and inspect event data +- Build attendee intelligence with Exhibitor, Social Signals, and registered Visitor source labels - Search exhibitors using company context and optional event scope - Retrieve exhibitor and personnel profiles - Search contacts with company-based inputs and unlock contact emails @@ -53,10 +54,12 @@ curl -X GET "https://platform.lensmor.com/external/events/list?page=1&pageSize=2 - `openapi.json` — OpenAPI 3.1 specification for documented endpoints - `api-catalog.json` — machine-readable API catalog pointing to the OpenAPI file - `llms.txt` and `llms-full.txt` — LLM-friendly documentation entry points +- `zh-Hans/` — Simplified Chinese core onboarding, attendee, access, and contact-unlock guides - `api-reference/credits/` — credit balance endpoint - `concepts/errors.mdx` — shared error conventions - `concepts/pagination.mdx` — pagination behavior - `concepts/identifiers.mdx` — identifier conventions +- `concepts/attendee-source-types.mdx` — product-to-API attendee source mapping and multi-source behavior - `concepts/credits-and-access.mdx` — credit costs, preview access, and unlock behavior - `concepts/rate-limits.mdx` — rate-limit headers and `429` behavior - `api-reference/events/` — event endpoints @@ -67,10 +70,10 @@ curl -X GET "https://platform.lensmor.com/external/events/list?page=1&pageSize=2 ## Typical use cases -- Build event discovery workflows -- Match exhibitors to a company profile or target audience -- Enrich sales, partnership, or market research pipelines -- Explore people and organizations connected to relevant events +- Build event discovery and field-marketing workflows +- Segment accessible attendees by Exhibitor, Social Signals, and registered Visitor source +- Match target accounts and exhibiting companies to relevant events +- Prioritize selected attendees and enrich their contact data for sales engagement or CRM workflows ## Local preview @@ -80,7 +83,7 @@ pnpm dlx mintlify dev ## Changelog -See `changelog.mdx` for versioned documentation updates. The current documentation version is `v0.24.0`. +See `changelog.mdx` for versioned documentation updates. The current documentation version is `v0.24.1`. --- diff --git a/api-catalog.json b/api-catalog.json index 872525d..96f9fd9 100644 --- a/api-catalog.json +++ b/api-catalog.json @@ -2,7 +2,7 @@ "apis": [ { "name": "Lensmor API", - "description": "Lensmor Event Intelligence API.", + "description": "Lensmor Event and Attendee Intelligence API.", "baseUrl": "https://platform.lensmor.com", "openapi": "https://api.lensmor.com/openapi.json" } diff --git a/api-reference-backup/contacts/search.mdx b/api-reference-backup/contacts/search.mdx index b23156e..9ae77f7 100644 --- a/api-reference-backup/contacts/search.mdx +++ b/api-reference-backup/contacts/search.mdx @@ -6,7 +6,7 @@ openapi: "openapi.json GET /external/contacts/search" Search contacts by company name. -Use this endpoint when you want a lightweight contact result set keyed off a company query, with optional role filtering. +Use this endpoint when you want a lightweight contact result set keyed off a company query, with optional role filtering and attendee source context aggregated across associated events. ## When to use this endpoint @@ -62,7 +62,7 @@ curl "https://platform.lensmor.com/external/contacts/search?company_name=Acme&pe "seniorityLevel": "vp", "linkedinUrl": "https://linkedin.com/in/jane", "companyName": "Acme", - "sourceType": ["exhibitor"], + "sourceType": ["social", "visitors"], "email": null, "phone": null, "contactUnlockStatus": "locked", @@ -90,7 +90,7 @@ curl "https://platform.lensmor.com/external/contacts/search?company_name=Acme&pe | `department`, `seniorityLevel` | Normalized role metadata when available. | | `linkedinUrl` | LinkedIn profile URL when available. | | `companyName` | Matched company name. | -| `sourceType` | Normalized source labels for the contact record. Values can include `exhibitor`, `social`, and `visitors`. | +| `sourceType` | Non-exclusive source labels aggregated across associated events. Product mapping: Exhibitor = `exhibitor`, Social Signals = `social`, Visitor = `visitors`. | | `email` | Email if already unlocked for the caller; otherwise `null`. | | `phone` | Phone number if already unlocked for the caller; otherwise `null`. | | `contactUnlockStatus` | Contact access state for this API key owner. | @@ -112,5 +112,6 @@ No matching contacts can return an empty paginated response. Use this as a valid ## Notes - Emails are returned only when the contact is already unlocked for the caller. +- Use [Personnel list](/api-reference/personnel/list-event-personnel) when you need source labels for one specific event. See [Attendee source types](/concepts/attendee-source-types) for the full mapping. - Contact-style list responses follow the shared [Pagination conventions](/concepts/pagination). - Each item includes `linkedinActivity` and `linkedinActivityStatus` for shape consistency, but they are always `null` on this endpoint. Only [Personnel list](/api-reference/personnel/list-event-personnel) populates LinkedIn activity data. diff --git a/api-reference-backup/events/unlock-event-visitor-access.mdx b/api-reference-backup/events/unlock-event-visitor-access.mdx index 95614fa..98a0704 100644 --- a/api-reference-backup/events/unlock-event-visitor-access.mdx +++ b/api-reference-backup/events/unlock-event-visitor-access.mdx @@ -6,7 +6,7 @@ openapi: "openapi.json POST /external/events/{id}/visitors/unlock" Unlock the visitor data layer for an event that already has base event access. -Use this endpoint when the caller needs visitor records in addition to the exhibitor and personnel coverage unlocked by [Unlock event](/api-reference/events/unlock-event-access). +Use this endpoint when the caller needs registered Visitor records in addition to the exhibitor and personnel coverage unlocked by [Unlock event](/api-reference/events/unlock-event-access). Visitor records are obtained through organizer or data-provider partnerships and are available only for selected events. ## Prerequisites @@ -16,7 +16,11 @@ Before executing this paid action: 2. Call [Actions precheck](/api-reference/actions/precheck-an-external-action) with `action_type: "unlock_event_visitors"` and the selected `event_id`. 3. Continue only when precheck returns `allowed: true`. -Visitor access requires an active subscription, available visitor data for the event, and enough credits. +Visitor access requires an active subscription, available Visitor data for the event, and enough credits. + + + The product label is **Visitor**, while personnel responses use the API source value `"visitors"`. See [Attendee source types](/concepts/attendee-source-types). + The first successful visitor unlock consumes `3000` credits. Precheck is read-only and should be used before the paid call. diff --git a/api-reference-backup/openapi.json b/api-reference-backup/openapi.json index e2295dc..1c2d407 100644 --- a/api-reference-backup/openapi.json +++ b/api-reference-backup/openapi.json @@ -2,7 +2,7 @@ "openapi": "3.1.0", "info": { "title": "Lensmor API", - "version": "0.24.0", + "version": "0.24.1", "description": "Lensmor Event Intelligence API for event discovery, exhibitor research, personnel lookup, credits, and profile matching.", "license": { "name": "Lensmor Terms of Service", @@ -1228,7 +1228,7 @@ "Personnel" ], "summary": "List event personnel", - "description": "Return paginated people for an event with preview or full-access semantics and visible coverage counts.", + "description": "Return paginated people for an event with event-scoped attendee source labels and preview or full base-event access semantics. The sourceType array can contain exhibitor, social, and visitors; labels are not mutually exclusive. The endpoint does not currently accept a source filter. Visitor is a separate access layer, so semantics.accessMode does not by itself confirm Visitor access.", "operationId": "listPersonnel", "parameters": [ { @@ -1294,6 +1294,10 @@ "fullName": "Jane Smith", "title": "VP of Retail Technology", "companyName": "Acme Retail Systems", + "sourceType": [ + "exhibitor", + "social" + ], "email": null, "phone": null, "contactUnlockStatus": "locked", @@ -1334,7 +1338,7 @@ "Personnel" ], "summary": "Get personnel profile", - "description": "Return the public professional profile for one personnel identifier.", + "description": "Return the public professional profile for one personnel identifier. The sourceType array can aggregate non-exclusive attendee source labels across the person's associated events.", "operationId": "getPersonnelProfile", "parameters": [ { @@ -1357,6 +1361,10 @@ "seniorityLevel": "vp", "linkedinUrl": "https://linkedin.com/in/jane-smith", "companyName": "Acme Retail Systems", + "sourceType": [ + "exhibitor", + "visitors" + ], "email": null, "phone": null, "contactUnlockStatus": "locked", @@ -1594,7 +1602,7 @@ "Contacts" ], "summary": "Search contacts", - "description": "Search public contact records by required company name and optional role or person-name filters.", + "description": "Search public contact records by required company name and optional role or person-name filters. Returned sourceType arrays can aggregate non-exclusive attendee source labels across associated events.", "operationId": "searchContacts", "parameters": [ { @@ -1645,6 +1653,10 @@ "fullName": "Jane Doe", "title": "VP Marketing", "companyName": "Acme", + "sourceType": [ + "social", + "visitors" + ], "email": null, "phone": null, "contactUnlockStatus": "locked", @@ -3892,7 +3904,7 @@ }, "sourceType": { "type": "array", - "description": "Normalized Lensmor source labels for this person. Possible values are exhibitor, social, and visitors.", + "description": "Lensmor source/business labels for this person. Source labels are not mutually exclusive. Product mapping: Exhibitor is exhibitor, Social Signals is social, and Visitor is visitors. Visitor represents registered attendees obtained through organizer or data-provider partnerships; Social Signals is not proof of official registration. Event personnel lists return event-scoped labels, while personnel profile and contact search can aggregate labels across associated events.", "items": { "type": "string", "enum": [ diff --git a/api-reference-backup/personnel/list.mdx b/api-reference-backup/personnel/list.mdx index db3550f..ec8c685 100644 --- a/api-reference-backup/personnel/list.mdx +++ b/api-reference-backup/personnel/list.mdx @@ -6,7 +6,7 @@ openapi: "openapi.json GET /external/personnel/list" List personnel records for a specific event. -Use this endpoint when you want a paginated people directory for one event, with optional exhibitor, department, level, and search filters. +Use this endpoint when you want a paginated people directory for one event, with optional exhibitor, department, level, and search filters. Each item can include event-scoped Exhibitor, Social Signals, and Visitor source labels. ## When to use this endpoint @@ -17,8 +17,13 @@ Common use cases: - browse people associated with an event - filter by department or seniority - find contacts for a selected exhibitor +- segment accessible attendees by their event-scoped `sourceType` labels - collect personnel IDs before calling [Unlock contact emails](/api-reference/contacts/unlock-contact-emails) + + The endpoint does not currently accept a source filter. Fetch the accessible result set and segment it client-side. See [Attendee source types](/concepts/attendee-source-types). + + ## Endpoint `GET /external/personnel/list` @@ -64,7 +69,7 @@ curl "https://platform.lensmor.com/external/personnel/list?event_id=139574&depar "seniorityLevel": "vp", "linkedinUrl": "https://linkedin.com/in/jane-smith", "companyName": "Acme Retail Systems", - "sourceType": ["exhibitor"], + "sourceType": ["exhibitor", "social"], "email": null, "phone": null, "contactUnlockStatus": "locked", @@ -121,7 +126,7 @@ curl "https://platform.lensmor.com/external/personnel/list?event_id=139574&depar | `department`, `seniorityLevel` | Normalized role metadata when available. | | `linkedinUrl` | LinkedIn profile URL when available. | | `companyName` | Associated company or exhibitor name. | -| `sourceType` | Normalized source labels for the person record. Values can include `exhibitor`, `social`, and `visitors`; an empty array means no supported source label is available. | +| `sourceType` | Event-scoped, non-exclusive source labels. Product mapping: Exhibitor = `exhibitor`, Social Signals = `social`, Visitor = `visitors`. An empty array means no supported source label is available. | | `email` | Email address if already unlocked for the caller; otherwise `null`. | | `phone` | Phone number if already unlocked for the caller; otherwise `null`. | | `contactUnlockStatus` | Contact access state, such as `locked` or unlocked states. | @@ -137,7 +142,7 @@ curl "https://platform.lensmor.com/external/personnel/list?event_id=139574&depar Locked events can still return preview personnel results. Read `semantics` before deciding whether to unlock the event: -- `accessMode` tells you whether the response is preview or full access. +- `accessMode` tells you whether base event coverage is preview or full access. It does not describe the separate Visitor access layer. - `counts.remainingLockedCount` tells you whether more records are hidden. - `unlock.requiredForMoreResults` tells you whether event unlock is useful for this query. - `guidance.message` provides a user-facing explanation. @@ -150,6 +155,8 @@ Locked events can still return preview personnel results. Read `semantics` befor ## Notes - Personnel list responses intentionally use the lightweight contact-style response shape. +- A person can have multiple source labels. Preserve every value rather than assigning one exclusive category. +- Visitor records are registered attendees obtained through organizer or data-provider partnerships. Visitor availability and access must be checked separately. - Emails are returned only when the contact is already unlocked for the caller. - Locked events can return preview results. Use `semantics.unlock` to decide whether to call [Unlock event](/api-reference/events/unlock-event-access). - Pagination behavior follows the shared [Pagination conventions](/concepts/pagination). diff --git a/api-reference-backup/personnel/profile.mdx b/api-reference-backup/personnel/profile.mdx index ecf4999..e498641 100644 --- a/api-reference-backup/personnel/profile.mdx +++ b/api-reference-backup/personnel/profile.mdx @@ -12,7 +12,7 @@ Use this endpoint when you already know the personnel identifier and need profil Use `GET /external/personnel/profile` after a user selects a person from a personnel list, contact search result, or LinkedIn-based event lookup. -This endpoint is intentionally lightweight. Use it to confirm the person's identity and current email unlock state before starting a contact unlock workflow. +This endpoint is intentionally lightweight. Use it to confirm the person's identity, aggregated source labels, and current email unlock state before starting a contact unlock workflow. ## Endpoint `GET /external/personnel/profile` @@ -44,7 +44,7 @@ curl "https://platform.lensmor.com/external/personnel/profile?personnel_id=789" "seniorityLevel": "vp", "linkedinUrl": "https://linkedin.com/in/jane-smith", "companyName": "Acme Retail Systems", - "sourceType": ["exhibitor"], + "sourceType": ["exhibitor", "visitors"], "email": null, "phone": null, "contactUnlockStatus": "locked", @@ -62,7 +62,7 @@ curl "https://platform.lensmor.com/external/personnel/profile?personnel_id=789" | `department`, `seniorityLevel` | Normalized role metadata when available. | | `linkedinUrl` | Public LinkedIn profile URL when available. | | `companyName` | Associated company or exhibitor. | -| `sourceType` | Normalized source labels such as `exhibitor`, `social`, and `visitors`. | +| `sourceType` | Non-exclusive source labels aggregated across the person's associated events. Product mapping: Exhibitor = `exhibitor`, Social Signals = `social`, Visitor = `visitors`. | | `email` | Email address if already unlocked for the caller; otherwise `null`. | | `phone` | Phone number if already unlocked for the caller; otherwise `null`. | | `contactUnlockStatus` | Current contact access state for this API key owner. | @@ -81,5 +81,7 @@ An empty `email` value does not necessarily mean Lensmor has no email data. It c ## Notes - This response stays intentionally lightweight. +- Use [Personnel list](/api-reference/personnel/list-event-personnel) when you need source labels for one specific event. Profile labels can reflect multiple associated events. +- See [Attendee source types](/concepts/attendee-source-types) for label meanings and Visitor access behavior. - Emails are returned only when the contact is already unlocked for the caller. - The response includes `linkedinActivity` and `linkedinActivityStatus` for shape consistency, but they are always `null` on this endpoint. Only [Personnel list](/api-reference/personnel/list-event-personnel) populates LinkedIn activity data. diff --git a/api-reference/openapi.json b/api-reference/openapi.json index e2295dc..1c2d407 100644 --- a/api-reference/openapi.json +++ b/api-reference/openapi.json @@ -2,7 +2,7 @@ "openapi": "3.1.0", "info": { "title": "Lensmor API", - "version": "0.24.0", + "version": "0.24.1", "description": "Lensmor Event Intelligence API for event discovery, exhibitor research, personnel lookup, credits, and profile matching.", "license": { "name": "Lensmor Terms of Service", @@ -1228,7 +1228,7 @@ "Personnel" ], "summary": "List event personnel", - "description": "Return paginated people for an event with preview or full-access semantics and visible coverage counts.", + "description": "Return paginated people for an event with event-scoped attendee source labels and preview or full base-event access semantics. The sourceType array can contain exhibitor, social, and visitors; labels are not mutually exclusive. The endpoint does not currently accept a source filter. Visitor is a separate access layer, so semantics.accessMode does not by itself confirm Visitor access.", "operationId": "listPersonnel", "parameters": [ { @@ -1294,6 +1294,10 @@ "fullName": "Jane Smith", "title": "VP of Retail Technology", "companyName": "Acme Retail Systems", + "sourceType": [ + "exhibitor", + "social" + ], "email": null, "phone": null, "contactUnlockStatus": "locked", @@ -1334,7 +1338,7 @@ "Personnel" ], "summary": "Get personnel profile", - "description": "Return the public professional profile for one personnel identifier.", + "description": "Return the public professional profile for one personnel identifier. The sourceType array can aggregate non-exclusive attendee source labels across the person's associated events.", "operationId": "getPersonnelProfile", "parameters": [ { @@ -1357,6 +1361,10 @@ "seniorityLevel": "vp", "linkedinUrl": "https://linkedin.com/in/jane-smith", "companyName": "Acme Retail Systems", + "sourceType": [ + "exhibitor", + "visitors" + ], "email": null, "phone": null, "contactUnlockStatus": "locked", @@ -1594,7 +1602,7 @@ "Contacts" ], "summary": "Search contacts", - "description": "Search public contact records by required company name and optional role or person-name filters.", + "description": "Search public contact records by required company name and optional role or person-name filters. Returned sourceType arrays can aggregate non-exclusive attendee source labels across associated events.", "operationId": "searchContacts", "parameters": [ { @@ -1645,6 +1653,10 @@ "fullName": "Jane Doe", "title": "VP Marketing", "companyName": "Acme", + "sourceType": [ + "social", + "visitors" + ], "email": null, "phone": null, "contactUnlockStatus": "locked", @@ -3892,7 +3904,7 @@ }, "sourceType": { "type": "array", - "description": "Normalized Lensmor source labels for this person. Possible values are exhibitor, social, and visitors.", + "description": "Lensmor source/business labels for this person. Source labels are not mutually exclusive. Product mapping: Exhibitor is exhibitor, Social Signals is social, and Visitor is visitors. Visitor represents registered attendees obtained through organizer or data-provider partnerships; Social Signals is not proof of official registration. Event personnel lists return event-scoped labels, while personnel profile and contact search can aggregate labels across associated events.", "items": { "type": "string", "enum": [ diff --git a/changelog.mdx b/changelog.mdx index 7660d83..0c001db 100644 --- a/changelog.mdx +++ b/changelog.mdx @@ -5,6 +5,23 @@ description: "Versioned Lensmor API documentation updates, newly documented endp Track documentation updates, newly documented API capabilities, and behavior clarifications that may affect integrations. +## v0.24.1 + +Released July 24, 2026. + +### Added + +- Added the Attendee source taxonomy that maps product labels to API values: Exhibitor (`exhibitor`), Social Signals (`social`), and Visitor (`visitors`). +- Added an attendee-intelligence guide for field marketing, account-based event planning, sales engagement, and CRM enrichment workflows. +- Added Simplified Chinese navigation and translations for the core onboarding, attendee, access, and contact-unlock documentation. + +### Changed + +- Clarified that `sourceType` is a non-exclusive array and that personnel profile and contact search can aggregate labels across associated events. +- Clarified that Visitor represents registered attendees obtained through organizer or data-provider partnerships and remains a separate access layer from base event access. +- Added attendee source labels to Personnel List, Personnel Profile, and Contact Search OpenAPI examples. +- Updated OpenAPI metadata to version `0.24.1`. + ## v0.24.0 Released July 24, 2026. diff --git a/concepts/attendee-source-types.mdx b/concepts/attendee-source-types.mdx new file mode 100644 index 0000000..eb60851 --- /dev/null +++ b/concepts/attendee-source-types.mdx @@ -0,0 +1,71 @@ +--- +title: "Attendee source types" +description: "Map Lensmor attendee labels to API sourceType values and understand event scope, multi-source people, visitor access, and filtering behavior." +--- + +Lensmor groups people connected to an event under **Attendees**. The `sourceType` array explains how each person is connected to the event or to Lensmor's broader event graph. + +## Product labels and API values + +| Product label | API value | Meaning | +| --- | --- | --- | +| **Exhibitor** | `exhibitor` | A person associated with a company exhibiting at the event. | +| **Social Signals** | `social` | A person identified through LinkedIn signals connected to the event. This label is not proof of official event registration. | +| **Visitor** | `visitors` | A registered event attendee obtained through organizer or data-provider partnerships. Visitor data is available only for selected events. | + + + The product displays **Visitor** in the singular, while the current API value is `"visitors"`. + + +## Labels are not mutually exclusive + +`sourceType` is an array because one person can have more than one source relationship: + +```json +{ + "id": "789", + "fullName": "Jane Smith", + "companyName": "Acme Retail Systems", + "sourceType": ["exhibitor", "social"] +} +``` + +Do not force each person into a single category. Preserve every returned value and treat an empty array as “no supported source label is available.” + +## Source scope differs by endpoint + +- `GET /external/personnel/list` returns source labels in the requested event context. +- `GET /external/personnel/profile` can aggregate source labels across the person's associated events. +- `GET /external/contacts/search` can also return source labels aggregated across associated events because the search is company-scoped rather than event-scoped. + +If your UI needs to say “this person is a Visitor for this event,” use the event-scoped personnel list rather than an aggregated profile or contact-search result. + +## Visitor access + +Visitor is a separate access layer from base event access: + +- Base event access expands event-scoped exhibitor and personnel coverage. +- Visitor access adds eligible registered attendee records for events where visitor data is available. +- Call `POST /external/actions/precheck` with `unlock_event_visitors` or `unlock_event_full_access` before attempting a paid unlock. +- A visitor precheck can return `visitor_data_available: false`; treat that as an expected event-level availability state. + +The `semantics.accessMode` field on the personnel list describes base event preview/full access. It does not by itself prove that the separate Visitor layer is unlocked. + +## Filtering + +`GET /external/personnel/list` does not currently accept a `sourceType` filter. Fetch the accessible event-scoped result set, then segment it client-side: + +```js +const visitors = items.filter((person) => + person.sourceType?.includes("visitors") +); +``` + +Because labels can overlap, a person may appear in more than one client-side segment. + +## Related workflows + +- [Build attendee intelligence](/guides/build-attendee-intelligence) +- [Find and unlock an event](/guides/find-and-unlock-event) +- [Credits and access](/concepts/credits-and-access) +- [List event personnel](/api-reference/personnel/list-event-personnel) diff --git a/concepts/credits-and-access.mdx b/concepts/credits-and-access.mdx index 5cf8a72..45bf571 100644 --- a/concepts/credits-and-access.mdx +++ b/concepts/credits-and-access.mdx @@ -29,7 +29,9 @@ When an event is locked, list responses may include `semantics` metadata describ - whether more results require unlocking the event - which unlock action and credit amount applies -Base event unlock grants full access to event-scoped exhibitor and personnel results. Visitor access is a separate data layer that can be unlocked after base event access or together through the full-access endpoint. +Base event unlock grants full access to event-scoped exhibitor and personnel results. Visitor access is a separate registered-attendee data layer, sourced through organizer or data-provider partnerships, that can be unlocked after base event access or together through the full-access endpoint. + +`semantics.accessMode` on an event-scoped list describes base event access only. It does not prove that Visitor access is unlocked. Use the Visitor or full-access action precheck when registered Visitor records are required. ## Credit-consuming operations | Operation | Typical cost | Notes | @@ -113,7 +115,10 @@ Recommended behavior: Unlock base event-scoped exhibitor and personnel coverage. - Unlock missing base and visitor access layers in one atomic call. + Unlock missing base and registered Visitor access layers in one atomic call. + + + Understand Exhibitor, Social Signals, and Visitor labels. Start an asynchronous email unlock task. diff --git a/docs.json b/docs.json index 9dcba6e..36774c4 100644 --- a/docs.json +++ b/docs.json @@ -29,107 +29,148 @@ } }, "navigation": { - "tabs": [ + "languages": [ { - "tab": "Documentation", - "groups": [ + "language": "en", + "default": true, + "tabs": [ { - "group": "Introduction", - "pages": [ - "index", - "authentication", - "changelog" + "tab": "Documentation", + "groups": [ + { + "group": "Introduction", + "pages": [ + "index", + "authentication", + "changelog" + ] + }, + { + "group": "Guides", + "pages": [ + "guides/quickstart", + "guides/build-attendee-intelligence", + "guides/build-event-recommendations", + "guides/find-and-unlock-event", + "guides/unlock-contact-emails", + "guides/production-readiness" + ] + }, + { + "group": "Concepts", + "pages": [ + "concepts/errors", + "concepts/pagination", + "concepts/identifiers", + "concepts/attendee-source-types", + "concepts/credits-and-access", + "concepts/rate-limits" + ] + } ] }, { - "group": "Guides", - "pages": [ - "guides/quickstart", - "guides/build-event-recommendations", - "guides/find-and-unlock-event", - "guides/unlock-contact-emails", - "guides/production-readiness" - ] - }, - { - "group": "Concepts", - "pages": [ - "concepts/errors", - "concepts/pagination", - "concepts/identifiers", - "concepts/credits-and-access", - "concepts/rate-limits" + "tab": "API Reference", + "openapi": "openapi.json", + "groups": [ + { + "group": "Credits", + "pages": [ + "GET /external/credits/balance" + ] + }, + { + "group": "Actions", + "pages": [ + "POST /external/actions/precheck" + ] + }, + { + "group": "Events", + "pages": [ + "GET /external/events/list", + "GET /external/events/{id}", + "GET /external/events/brief", + "POST /external/events/fit-score", + "POST /external/events/rank", + "POST /external/events/{id}/unlock", + "POST /external/events/{id}/visitors/unlock", + "POST /external/events/{id}/full-access/unlock" + ] + }, + { + "group": "Exhibitors", + "pages": [ + "GET /external/exhibitors/list", + "POST /external/exhibitors/search", + "POST /external/exhibitors/search-by-company-name", + "POST /external/exhibitors/search-events", + "GET /external/exhibitors/profile", + "GET /external/exhibitors/events" + ] + }, + { + "group": "Personnel", + "pages": [ + "GET /external/personnel/list", + "GET /external/personnel/profile", + "GET /external/personnel/events", + "GET /external/personnel/events/by-linkedin", + "POST /external/personnel/unlock-linkedin-activity", + "POST /external/personnel/generate-outreach-message", + "GET /external/personnel/outreach" + ] + }, + { + "group": "Contacts", + "pages": [ + "GET /external/contacts/search", + "POST /external/contacts/unlock", + "GET /external/contacts/unlock-tasks/{taskId}", + "POST /external/contacts/unlock-phone", + "GET /external/contacts/unlock-phone-tasks/{taskId}" + ] + }, + { + "group": "Profile Matching", + "pages": [ + "POST /external/profile-matching/actions/apply-recommended-events/paged", + "GET /external/profile-matching/recommendations/exhibitors" + ] + } ] } ] }, { - "tab": "API Reference", - "openapi": "openapi.json", - "groups": [ - { - "group": "Credits", - "pages": [ - "GET /external/credits/balance" - ] - }, - { - "group": "Actions", - "pages": [ - "POST /external/actions/precheck" - ] - }, - { - "group": "Events", - "pages": [ - "GET /external/events/list", - "GET /external/events/{id}", - "GET /external/events/brief", - "POST /external/events/fit-score", - "POST /external/events/rank", - "POST /external/events/{id}/unlock", - "POST /external/events/{id}/visitors/unlock", - "POST /external/events/{id}/full-access/unlock" - ] - }, - { - "group": "Exhibitors", - "pages": [ - "GET /external/exhibitors/list", - "POST /external/exhibitors/search", - "POST /external/exhibitors/search-by-company-name", - "POST /external/exhibitors/search-events", - "GET /external/exhibitors/profile", - "GET /external/exhibitors/events" - ] - }, - { - "group": "Personnel", - "pages": [ - "GET /external/personnel/list", - "GET /external/personnel/profile", - "GET /external/personnel/events", - "GET /external/personnel/events/by-linkedin", - "POST /external/personnel/unlock-linkedin-activity", - "POST /external/personnel/generate-outreach-message", - "GET /external/personnel/outreach" - ] - }, - { - "group": "Contacts", - "pages": [ - "GET /external/contacts/search", - "POST /external/contacts/unlock", - "GET /external/contacts/unlock-tasks/{taskId}", - "POST /external/contacts/unlock-phone", - "GET /external/contacts/unlock-phone-tasks/{taskId}" - ] - }, + "language": "zh-Hans", + "tabs": [ { - "group": "Profile Matching", - "pages": [ - "POST /external/profile-matching/actions/apply-recommended-events/paged", - "GET /external/profile-matching/recommendations/exhibitors" + "tab": "文档", + "groups": [ + { + "group": "开始使用", + "pages": [ + "zh-Hans/index", + "zh-Hans/authentication", + "zh-Hans/guides/quickstart" + ] + }, + { + "group": "参会人员数据", + "pages": [ + "zh-Hans/concepts/attendee-source-types", + "zh-Hans/guides/build-attendee-intelligence", + "zh-Hans/guides/find-and-unlock-event" + ] + }, + { + "group": "访问与数据补全", + "pages": [ + "zh-Hans/concepts/credits-and-access", + "zh-Hans/guides/unlock-contact-emails" + ] + } ] } ] @@ -273,14 +314,14 @@ "permanent": true } ], - "description": "Lensmor API documentation for event intelligence, trade show discovery, exhibitor research, profile matching, credits, and contact email unlock workflows.", + "description": "Lensmor API documentation for event discovery, attendee intelligence, exhibitor research, registered visitor access, profile matching, and contact enrichment.", "seo": { "indexing": "navigable", "metatags": { "og:site_name": "Lensmor API Docs", "og:type": "website", "twitter:card": "summary_large_image", - "keywords": "Lensmor API, event intelligence API, trade show API, exhibitor API, B2B prospecting API, event recommendation API" + "keywords": "Lensmor API, event intelligence API, attendee data API, registered visitor data, trade show API, exhibitor API, B2B prospecting API, event recommendation API" } }, "search": { diff --git a/guides/build-attendee-intelligence.mdx b/guides/build-attendee-intelligence.mdx new file mode 100644 index 0000000..a08aea8 --- /dev/null +++ b/guides/build-attendee-intelligence.mdx @@ -0,0 +1,121 @@ +--- +title: "Build attendee intelligence" +description: "Build event audience workflows with Exhibitor, Social Signals, and Visitor source labels, then unlock only the data and contact fields you need." +--- + +Use this guide to build field-marketing, account-based event planning, and sales-engagement workflows around the people connected to an event. + +Lensmor Attendees include three source labels: + +- **Exhibitor** (`exhibitor`) — people associated with exhibiting companies. +- **Social Signals** (`social`) — people identified from LinkedIn signals connected to the event. +- **Visitor** (`visitors`) — registered attendees obtained through organizer or data-provider partnerships. + +A person can have multiple labels. See [Attendee source types](/concepts/attendee-source-types) for the complete mapping and scope rules. + +## Recommended workflow + + + + Search the event catalog, rank events, or apply profile matching. Fetch event detail before using its `eventId` in attendee requests. + + + Call `GET /external/personnel/list` and read both each person's `sourceType` array and the response-level `semantics` object. + + + Use the Visitor or full-access action precheck. Visitor data is available only for selected events. + + + Unlock base event access for broader exhibitor/personnel coverage, Visitor access for registered attendee records, or full access for both missing layers. + + + Segment accessible records client-side, score the people relevant to your workflow, and unlock email or phone fields only for selected personnel IDs. + + + +## 1. List people for an event + +```bash +curl "https://platform.lensmor.com/external/personnel/list?event_id=139574&page=1&pageSize=50" \ + -H "Authorization: Bearer $LENSMOR_API_KEY" +``` + +Each item can include a multi-value `sourceType`: + +```json +{ + "id": "789", + "fullName": "Jane Smith", + "title": "VP of Partnerships", + "companyName": "Acme Retail Systems", + "sourceType": ["exhibitor", "social"], + "contactUnlockStatus": "locked" +} +``` + +Use the event-scoped list when you need source meaning for one selected event. Personnel profile and contact search can aggregate labels across multiple associated events. + +## 2. Segment the accessible audience + +The personnel endpoint does not currently provide a server-side source filter. Preserve overlapping labels and segment the returned items in your application: + +```js +const bySource = { + exhibitor: items.filter((person) => person.sourceType?.includes("exhibitor")), + social: items.filter((person) => person.sourceType?.includes("social")), + visitors: items.filter((person) => person.sourceType?.includes("visitors")), +}; +``` + +Do not add the three segment counts together to calculate unique people because the same person can appear in multiple segments. + +## 3. Check Visitor availability and access + +Visitor data is a separate layer. Precheck before showing an unlock confirmation: + +```bash +curl -X POST "https://platform.lensmor.com/external/actions/precheck" \ + -H "Authorization: Bearer $LENSMOR_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "action_type": "unlock_event_visitors", + "call_source": "api", + "params": { + "event_id": "139574" + } + }' +``` + +Inspect `allowed`, `credits`, `reason`, and `detail.visitor_data_available`. If base event access is still locked, use the full-access precheck or unlock base event access first. + + + `semantics.accessMode: "full"` on the personnel list refers to base event access. Always use Visitor precheck state when your workflow specifically requires registered Visitor records. + + +## 4. Enrich only selected people + +After prioritizing attendees, collect their personnel IDs and call the contact email or phone unlock workflow. Both workflows can consume credits and run asynchronously, so show the user the selected scope, check balance, and poll the returned task ID. + +## Example use cases + +### Field marketing + +Compare Exhibitor, Social Signals, and Visitor records to understand the accessible event audience, then prioritize registered Visitors or relevant exhibiting-company contacts for campaign planning. + +### Account-based event planning + +Combine `GET /external/exhibitors/list` with event personnel. Identify target accounts exhibiting at the event, then inspect the source labels and roles of people connected to those companies. + +### Sales engagement + +Use source labels, title, department, and seniority to shortlist relevant attendees. Unlock contact fields only after the user confirms the final outreach list. + +### CRM enrichment + +Store the person ID, event ID, full `sourceType` array, and unlock state in your own integration. Preserve the event context so aggregated profile labels are not mistaken for event-specific registration. + +## Current limitations + +- Event list and event detail do not currently expose a public `hasVisitors` field. Use Visitor action precheck for a known event. +- Personnel list does not currently accept a source filter. +- Visitor coverage varies by event and must not be inferred from event category, size, or location. diff --git a/guides/find-and-unlock-event.mdx b/guides/find-and-unlock-event.mdx index 88b86fb..c8cd880 100644 --- a/guides/find-and-unlock-event.mdx +++ b/guides/find-and-unlock-event.mdx @@ -3,9 +3,9 @@ title: "Find and unlock an event" description: "Find a relevant trade show, inspect preview data, and unlock base event, visitor, or atomic full access with credit-safe prechecks." --- -Use this guide when your integration needs to move from discovery to base event coverage, visitor access, or both. +Use this guide when your integration needs to move from discovery to base event coverage, registered Visitor access, or both. -Event unlocks are intentionally explicit. Lensmor lets you preview exhibitor and personnel data first, then choose the access layer the user actually needs. +Event unlocks are intentionally explicit. Lensmor lets you preview exhibitor and personnel data first, then choose the access layer the user actually needs. Visitor records are registered event attendees obtained through organizer or data-provider partnerships and are available only for selected events. ## Recommended workflow @@ -59,6 +59,7 @@ Locked events can return a response like this: "fullName": "Jane Doe", "title": "VP of Partnerships", "companyName": "Example Retail Co", + "sourceType": ["exhibitor", "social"], "email": null, "contactUnlockStatus": "locked" } @@ -93,7 +94,7 @@ Locked events can return a response like this: } ``` -Use `semantics` to decide whether to unlock. Do not infer full access from pagination alone. +Use `semantics` to decide whether to unlock base event coverage. `semantics.accessMode` does not describe the separate Visitor layer, so do not infer Visitor access from pagination or `"full"` base access alone. ## 4. Unlock base event access @@ -130,7 +131,7 @@ If `alreadyUnlocked` is `true`, the event was already available and `creditsUsed Visitor access is separate from base event access: -- `POST /external/events/:id/visitors/unlock` costs `3000` credits and requires base event access, an active subscription, and visitor data. +- `POST /external/events/:id/visitors/unlock` costs `3000` credits and requires base event access, an active subscription, and registered Visitor data for the event. - `POST /external/events/:id/full-access/unlock` atomically charges only for missing layers: `2000` for base event access plus `3000` for visitor access. Precheck the intended action before execution: @@ -148,7 +149,7 @@ curl -X POST "https://platform.lensmor.com/external/actions/precheck" \ }' ``` -Continue only when `allowed` is `true`, show the returned `credits` to the user, and refresh the balance after execution. If full-access precheck returns `no_contacts_available` because visitor data is unavailable, use base event unlock when exhibitor and personnel coverage is still needed. +Continue only when `allowed` is `true`, show the returned `credits` to the user, and refresh the balance after execution. Read `detail.visitor_data_available` instead of inferring availability from the event category or list counts. If full-access precheck returns `no_contacts_available` because Visitor data is unavailable, use base event unlock when exhibitor and personnel coverage is still needed. ## Common mistakes @@ -158,6 +159,7 @@ Continue only when `allowed` is `true`, show the returned `credits` to the user, - Ignoring `semantics`. It tells you whether a list is in preview mode or has full access. - Calling visitor unlock before base event access. Precheck returns `state_conflict` in that state. - Treating base event access and visitor access as the same layer. They have separate access records and credit costs. +- Treating Social Signals as official registration evidence. Only the Visitor label represents registered attendees in the current source taxonomy. ## Related endpoints @@ -180,4 +182,7 @@ Continue only when `allowed` is `true`, show the returned `credits` to the user, Fetch people associated with a selected event. + + Map product attendee labels to API `sourceType` values. + diff --git a/guides/quickstart.mdx b/guides/quickstart.mdx index e5afa87..ddb4bba 100644 --- a/guides/quickstart.mdx +++ b/guides/quickstart.mdx @@ -9,7 +9,7 @@ The Lensmor API is designed around a typical event-intelligence workflow: 1. Start with a company profile, buyer profile, keyword, or target market. 2. Discover relevant trade shows and event records. -3. Inspect exhibitors and people connected to those events. +3. Inspect exhibitors and people connected to those events, including their Exhibitor, Social Signals, and Visitor source labels. 4. Unlock base event access, visitor access, full event access, or contact fields only when the data is actionable. ## Before you begin @@ -44,7 +44,7 @@ The response includes subscription credits, gift credits, the total balance, and | Search for events by keyword, country, city, or date | `GET /external/events/list` | Read-only | | Rank events from a company profile or audience description | `POST /external/profile-matching/actions/apply-recommended-events/paged` | Read-only | | Browse companies inside a selected event | `GET /external/exhibitors/list` | Read-only unless the user unlocks event access | -| Browse people inside a selected event | `GET /external/personnel/list` | Read-only unless the user unlocks event access or emails | +| Browse people inside a selected event | `GET /external/personnel/list` | Read-only; returned `sourceType` labels identify accessible Exhibitor, Social Signals, and Visitor records | | Unlock complete exhibitor and personnel coverage | `POST /external/events/:id/unlock` | `2000` credits when base event access is still locked | | Unlock visitor records after base event access | `POST /external/events/:id/visitors/unlock` | `3000` credits when visitor access is still locked | | Unlock missing base and visitor layers together | `POST /external/events/:id/full-access/unlock` | Dynamic cost from `0` to `5000` credits | @@ -87,9 +87,22 @@ curl "https://platform.lensmor.com/external/exhibitors/list?event_id=139574&page -H "Authorization: Bearer $LENSMOR_API_KEY" ``` -When the response contains `semantics.accessMode: "preview"`, read `semantics.counts.visibleTotal` and `semantics.unlock.requiredForMoreResults` before calling an unlock endpoint. These fields tell you whether more data is available and which action unlocks it. +Personnel items can include a multi-value `sourceType` array: -For visitor or combined full access, call `POST /external/actions/precheck` with `unlock_event_visitors` or `unlock_event_full_access` before execution. Precheck is read-only and returns current access state, eligibility, and expected credits. +```json +{ + "id": "789", + "fullName": "Jane Smith", + "companyName": "Acme Retail Systems", + "sourceType": ["exhibitor", "social"] +} +``` + +The values map to the product's **Exhibitor**, **Social Signals**, and **Visitor** labels. A person can have multiple labels, and the API uses `"visitors"` for the product's singular Visitor label. See [Attendee source types](/concepts/attendee-source-types). + +When the response contains `semantics.accessMode: "preview"`, read `semantics.counts.visibleTotal` and `semantics.unlock.requiredForMoreResults` before calling an unlock endpoint. These fields describe base event access and tell you whether more base personnel coverage is available. + +Visitor is a separate registered-attendee data layer. For Visitor or combined full access, call `POST /external/actions/precheck` with `unlock_event_visitors` or `unlock_event_full_access` before execution. Precheck is read-only and returns current access state, Visitor availability, eligibility, and expected credits. ## 5. Handle errors and limits @@ -105,6 +118,9 @@ See [Error conventions](/concepts/errors), [Credits and access](/concepts/credit ## Next steps + + Segment Exhibitor, Social Signals, and Visitor records without losing multi-source context. + Learn how preview, base event, visitor, and atomic full access work. diff --git a/guides/unlock-contact-emails.mdx b/guides/unlock-contact-emails.mdx index 1ba1c1d..1349f67 100644 --- a/guides/unlock-contact-emails.mdx +++ b/guides/unlock-contact-emails.mdx @@ -29,12 +29,13 @@ Most personnel responses include `id`, name, title, company context, and `contac "fullName": "Jane Doe", "title": "VP of Partnerships", "companyName": "Example Retail Co", + "sourceType": ["exhibitor", "visitors"], "email": null, "contactUnlockStatus": "locked" } ``` -Only send records that are still locked. Already unlocked contacts are not charged again, but filtering them out keeps your task easier to audit. +Preserve the full `sourceType` array when moving a selected attendee into your enrichment workflow. Only send records that are still locked. Already unlocked contacts are not charged again, but filtering them out keeps your task easier to audit. ## 2. Start the unlock task diff --git a/index.mdx b/index.mdx index 94f5391..c6de7c7 100644 --- a/index.mdx +++ b/index.mdx @@ -1,13 +1,13 @@ --- title: "Lensmor API Documentation" -description: "Lensmor API documentation for building event intelligence workflows, discovering trade shows, evaluating exhibitors, and unlocking contact data." +description: "Build event and attendee intelligence workflows with trade show discovery, Exhibitor and Social Signals data, registered Visitor access, and contact enrichment." --- -Build event intelligence workflows with the Lensmor API. Use it to discover trade shows, evaluate event fit, inspect exhibitor and personnel data, and unlock contact details when your team is ready to act. +Build event and attendee intelligence workflows with the Lensmor API. Use it to discover trade shows, evaluate event fit, inspect exhibitors and attendee source types, access registered Visitor data when available, and unlock contact details when your team is ready to act. Use this documentation to authenticate, make your first request, and integrate Lensmor event, exhibitor, personnel, contact, and recommendation resources into your own workflows. -Current documentation version: `v0.24.0` +Current documentation version: `v0.24.1` ## Base URL `https://platform.lensmor.com` @@ -33,8 +33,11 @@ Authorization: Bearer sk_your_api_key Match target accounts or buyer profiles against exhibitor data and related event presence. + + Distinguish Exhibitor, Social Signals, and registered Visitor records while preserving people with multiple source labels. + - Move from preview results to base event coverage, visitor access, or both in one atomic action. + Move from preview results to base event coverage, registered Visitor access, or both in one atomic action. Start asynchronous email unlock jobs and poll task status until contact data is ready. @@ -47,7 +50,7 @@ Authorization: Bearer sk_your_api_key | --- | --- | --- | | A keyword, geography, or date range | [Events list](/api-reference/events/list-events) | Broad event catalog search. | | A company website or buyer profile | [Apply profile and get recommended events](/api-reference/profile-matching/apply-profile-and-get-recommended-events) | Returns ranked events from profile context. | -| A known event ID | [Exhibitors list](/api-reference/exhibitors/list-event-exhibitors) or [Personnel list](/api-reference/personnel/list-event-personnel) | Shows event-scoped companies and people, with preview/full access semantics. | +| A known event ID | [Exhibitors list](/api-reference/exhibitors/list-event-exhibitors) or [Personnel list](/api-reference/personnel/list-event-personnel) | Shows event-scoped companies and people; personnel records can include Exhibitor, Social Signals, and Visitor source labels. | | An event that needs both base and visitor access | [Unlock full event access](/api-reference/events/unlock-full-event-access) | Prechecks and atomically unlocks missing access layers for up to `5000` credits. | | A company name and you want companies | [Exhibitor company search](/api-reference/exhibitors/search-exhibitors-by-company-name) | Precision-first company lookup. Non-empty results cost `50` credits. | | A company name and you want events | [Exhibitor event search](/api-reference/exhibitors/search-events-by-exhibitor-company-name) | Finds events associated with that company. Non-empty results cost `50` credits. | @@ -65,6 +68,9 @@ Authorization: Bearer sk_your_api_key Use Events, Exhibitors, Personnel, Contacts, or Profile Matching endpoints depending on your workflow. + + Treat `sourceType` as a multi-value array and keep event-scoped labels separate from source labels aggregated across a person's related events. + Read `semantics` metadata, handle `402 Payment Required`, and back off on `429 Too Many Requests`. @@ -83,7 +89,7 @@ If the request succeeds, continue with the [Quickstart guide](/guides/quickstart - **Credits** — inspect the API key owner's current credit balance. - **Events** — browse, score, rank, inspect event details, and unlock base or visitor access. - **Exhibitors** — list exhibitors, search by company context, inspect profiles, and fetch related events. -- **Personnel** — list people, inspect profiles, and fetch related events. +- **Personnel** — list people, interpret attendee source labels, inspect profiles, and fetch related events. - **Contacts** — search contacts, unlock emails, and poll unlock tasks. - **Profile Matching** — apply profile inputs and retrieve recommended events or exhibitors. @@ -92,6 +98,7 @@ If the request succeeds, continue with the [Quickstart guide](/guides/quickstart - [Error conventions](/concepts/errors) - [Pagination conventions](/concepts/pagination) - [Identifiers](/concepts/identifiers) +- [Attendee source types](/concepts/attendee-source-types) - [Credits and access](/concepts/credits-and-access) - [Rate limits](/concepts/rate-limits) diff --git a/llms-full.txt b/llms-full.txt index 8cd05fa..658f846 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -7,11 +7,11 @@ It intentionally uses plain Markdown code fences without Mintlify-specific metad Source: /index -Build event intelligence workflows with the Lensmor API. Use it to discover trade shows, evaluate event fit, inspect exhibitor and personnel data, and unlock contact details when your team is ready to act. +Build event and attendee intelligence workflows with the Lensmor API. Use it to discover trade shows, evaluate event fit, inspect exhibitors and attendee source types, access registered Visitor data when available, and unlock contact details when your team is ready to act. Use this documentation to authenticate, make your first request, and integrate Lensmor event, exhibitor, personnel, contact, and recommendation resources into your own workflows. -Current documentation version: `v0.24.0` +Current documentation version: `v0.24.1` ## Base URL `https://platform.lensmor.com` @@ -37,8 +37,11 @@ Authorization: Bearer sk_your_api_key Match target accounts or buyer profiles against exhibitor data and related event presence. + + Distinguish Exhibitor, Social Signals, and registered Visitor records while preserving people with multiple source labels. + - Move from preview results to base event coverage, visitor access, or both in one atomic action. + Move from preview results to base event coverage, registered Visitor access, or both in one atomic action. Start asynchronous email unlock jobs and poll task status until contact data is ready. @@ -51,7 +54,7 @@ Authorization: Bearer sk_your_api_key | --- | --- | --- | | A keyword, geography, or date range | [Events list](/api-reference/events/list-events) | Broad event catalog search. | | A company website or buyer profile | [Apply profile and get recommended events](/api-reference/profile-matching/apply-profile-and-get-recommended-events) | Returns ranked events from profile context. | -| A known event ID | [Exhibitors list](/api-reference/exhibitors/list-event-exhibitors) or [Personnel list](/api-reference/personnel/list-event-personnel) | Shows event-scoped companies and people, with preview/full access semantics. | +| A known event ID | [Exhibitors list](/api-reference/exhibitors/list-event-exhibitors) or [Personnel list](/api-reference/personnel/list-event-personnel) | Shows event-scoped companies and people; personnel records can include Exhibitor, Social Signals, and Visitor source labels. | | An event that needs both base and visitor access | [Unlock full event access](/api-reference/events/unlock-full-event-access) | Prechecks and atomically unlocks missing access layers for up to `5000` credits. | | A company name and you want companies | [Exhibitor company search](/api-reference/exhibitors/search-exhibitors-by-company-name) | Precision-first company lookup. Non-empty results cost `50` credits. | | A company name and you want events | [Exhibitor event search](/api-reference/exhibitors/search-events-by-exhibitor-company-name) | Finds events associated with that company. Non-empty results cost `50` credits. | @@ -69,6 +72,9 @@ Authorization: Bearer sk_your_api_key Use Events, Exhibitors, Personnel, Contacts, or Profile Matching endpoints depending on your workflow. + + Treat `sourceType` as a multi-value array and keep event-scoped labels separate from source labels aggregated across a person's related events. + Read `semantics` metadata, handle `402 Payment Required`, and back off on `429 Too Many Requests`. @@ -87,7 +93,7 @@ If the request succeeds, continue with the [Quickstart guide](/guides/quickstart - **Credits** — inspect the API key owner's current credit balance. - **Events** — browse, score, rank, inspect event details, and unlock base or visitor access. - **Exhibitors** — list exhibitors, search by company context, inspect profiles, and fetch related events. -- **Personnel** — list people, inspect profiles, and fetch related events. +- **Personnel** — list people, interpret attendee source labels, inspect profiles, and fetch related events. - **Contacts** — search contacts, unlock emails, and poll unlock tasks. - **Profile Matching** — apply profile inputs and retrieve recommended events or exhibitors. @@ -96,6 +102,7 @@ If the request succeeds, continue with the [Quickstart guide](/guides/quickstart - [Error conventions](/concepts/errors) - [Pagination conventions](/concepts/pagination) - [Identifiers](/concepts/identifiers) +- [Attendee source types](/concepts/attendee-source-types) - [Credits and access](/concepts/credits-and-access) - [Rate limits](/concepts/rate-limits) @@ -202,6 +209,23 @@ Source: /changelog Track documentation updates, newly documented API capabilities, and behavior clarifications that may affect integrations. +## v0.24.1 + +Released July 24, 2026. + +### Added + +- Added the Attendee source taxonomy that maps product labels to API values: Exhibitor (`exhibitor`), Social Signals (`social`), and Visitor (`visitors`). +- Added an attendee-intelligence guide for field marketing, account-based event planning, sales engagement, and CRM enrichment workflows. +- Added Simplified Chinese navigation and translations for the core onboarding, attendee, access, and contact-unlock documentation. + +### Changed + +- Clarified that `sourceType` is a non-exclusive array and that personnel profile and contact search can aggregate labels across associated events. +- Clarified that Visitor represents registered attendees obtained through organizer or data-provider partnerships and remains a separate access layer from base event access. +- Added attendee source labels to Personnel List, Personnel Profile, and Contact Search OpenAPI examples. +- Updated OpenAPI metadata to version `0.24.1`. + ## v0.24.0 Released July 24, 2026. @@ -318,7 +342,7 @@ The Lensmor API is designed around a typical event-intelligence workflow: 1. Start with a company profile, buyer profile, keyword, or target market. 2. Discover relevant trade shows and event records. -3. Inspect exhibitors and people connected to those events. +3. Inspect exhibitors and people connected to those events, including their Exhibitor, Social Signals, and Visitor source labels. 4. Unlock base event access, visitor access, full event access, or contact fields only when the data is actionable. ## Before you begin @@ -353,7 +377,7 @@ The response includes subscription credits, gift credits, the total balance, and | Search for events by keyword, country, city, or date | `GET /external/events/list` | Read-only | | Rank events from a company profile or audience description | `POST /external/profile-matching/actions/apply-recommended-events/paged` | Read-only | | Browse companies inside a selected event | `GET /external/exhibitors/list` | Read-only unless the user unlocks event access | -| Browse people inside a selected event | `GET /external/personnel/list` | Read-only unless the user unlocks event access or emails | +| Browse people inside a selected event | `GET /external/personnel/list` | Read-only; returned `sourceType` labels identify accessible Exhibitor, Social Signals, and Visitor records | | Unlock complete exhibitor and personnel coverage | `POST /external/events/:id/unlock` | `2000` credits when base event access is still locked | | Unlock visitor records after base event access | `POST /external/events/:id/visitors/unlock` | `3000` credits when visitor access is still locked | | Unlock missing base and visitor layers together | `POST /external/events/:id/full-access/unlock` | Dynamic cost from `0` to `5000` credits | @@ -396,9 +420,22 @@ curl "https://platform.lensmor.com/external/exhibitors/list?event_id=139574&page -H "Authorization: Bearer $LENSMOR_API_KEY" ``` -When the response contains `semantics.accessMode: "preview"`, read `semantics.counts.visibleTotal` and `semantics.unlock.requiredForMoreResults` before calling an unlock endpoint. These fields tell you whether more data is available and which action unlocks it. +Personnel items can include a multi-value `sourceType` array: + +```json +{ + "id": "789", + "fullName": "Jane Smith", + "companyName": "Acme Retail Systems", + "sourceType": ["exhibitor", "social"] +} +``` + +The values map to the product's **Exhibitor**, **Social Signals**, and **Visitor** labels. A person can have multiple labels, and the API uses `"visitors"` for the product's singular Visitor label. See [Attendee source types](/concepts/attendee-source-types). + +When the response contains `semantics.accessMode: "preview"`, read `semantics.counts.visibleTotal` and `semantics.unlock.requiredForMoreResults` before calling an unlock endpoint. These fields describe base event access and tell you whether more base personnel coverage is available. -For visitor or combined full access, call `POST /external/actions/precheck` with `unlock_event_visitors` or `unlock_event_full_access` before execution. Precheck is read-only and returns current access state, eligibility, and expected credits. +Visitor is a separate registered-attendee data layer. For Visitor or combined full access, call `POST /external/actions/precheck` with `unlock_event_visitors` or `unlock_event_full_access` before execution. Precheck is read-only and returns current access state, Visitor availability, eligibility, and expected credits. ## 5. Handle errors and limits @@ -414,6 +451,9 @@ See [Error conventions](/concepts/errors), [Credits and access](/concepts/credit ## Next steps + + Segment Exhibitor, Social Signals, and Visitor records without losing multi-source context. + Learn how preview, base event, visitor, and atomic full access work. @@ -424,6 +464,129 @@ See [Error conventions](/concepts/errors), [Credits and access](/concepts/credit --- +## Build attendee intelligence + +Source: /guides/build-attendee-intelligence + +Use this guide to build field-marketing, account-based event planning, and sales-engagement workflows around the people connected to an event. + +Lensmor Attendees include three source labels: + +- **Exhibitor** (`exhibitor`) — people associated with exhibiting companies. +- **Social Signals** (`social`) — people identified from LinkedIn signals connected to the event. +- **Visitor** (`visitors`) — registered attendees obtained through organizer or data-provider partnerships. + +A person can have multiple labels. See [Attendee source types](/concepts/attendee-source-types) for the complete mapping and scope rules. + +## Recommended workflow + + + + Search the event catalog, rank events, or apply profile matching. Fetch event detail before using its `eventId` in attendee requests. + + + Call `GET /external/personnel/list` and read both each person's `sourceType` array and the response-level `semantics` object. + + + Use the Visitor or full-access action precheck. Visitor data is available only for selected events. + + + Unlock base event access for broader exhibitor/personnel coverage, Visitor access for registered attendee records, or full access for both missing layers. + + + Segment accessible records client-side, score the people relevant to your workflow, and unlock email or phone fields only for selected personnel IDs. + + + +## 1. List people for an event + +```bash +curl "https://platform.lensmor.com/external/personnel/list?event_id=139574&page=1&pageSize=50" \ + -H "Authorization: Bearer $LENSMOR_API_KEY" +``` + +Each item can include a multi-value `sourceType`: + +```json +{ + "id": "789", + "fullName": "Jane Smith", + "title": "VP of Partnerships", + "companyName": "Acme Retail Systems", + "sourceType": ["exhibitor", "social"], + "contactUnlockStatus": "locked" +} +``` + +Use the event-scoped list when you need source meaning for one selected event. Personnel profile and contact search can aggregate labels across multiple associated events. + +## 2. Segment the accessible audience + +The personnel endpoint does not currently provide a server-side source filter. Preserve overlapping labels and segment the returned items in your application: + +```js +const bySource = { + exhibitor: items.filter((person) => person.sourceType?.includes("exhibitor")), + social: items.filter((person) => person.sourceType?.includes("social")), + visitors: items.filter((person) => person.sourceType?.includes("visitors")), +}; +``` + +Do not add the three segment counts together to calculate unique people because the same person can appear in multiple segments. + +## 3. Check Visitor availability and access + +Visitor data is a separate layer. Precheck before showing an unlock confirmation: + +```bash +curl -X POST "https://platform.lensmor.com/external/actions/precheck" \ + -H "Authorization: Bearer $LENSMOR_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "action_type": "unlock_event_visitors", + "call_source": "api", + "params": { + "event_id": "139574" + } + }' +``` + +Inspect `allowed`, `credits`, `reason`, and `detail.visitor_data_available`. If base event access is still locked, use the full-access precheck or unlock base event access first. + + + `semantics.accessMode: "full"` on the personnel list refers to base event access. Always use Visitor precheck state when your workflow specifically requires registered Visitor records. + + +## 4. Enrich only selected people + +After prioritizing attendees, collect their personnel IDs and call the contact email or phone unlock workflow. Both workflows can consume credits and run asynchronously, so show the user the selected scope, check balance, and poll the returned task ID. + +## Example use cases + +### Field marketing + +Compare Exhibitor, Social Signals, and Visitor records to understand the accessible event audience, then prioritize registered Visitors or relevant exhibiting-company contacts for campaign planning. + +### Account-based event planning + +Combine `GET /external/exhibitors/list` with event personnel. Identify target accounts exhibiting at the event, then inspect the source labels and roles of people connected to those companies. + +### Sales engagement + +Use source labels, title, department, and seniority to shortlist relevant attendees. Unlock contact fields only after the user confirms the final outreach list. + +### CRM enrichment + +Store the person ID, event ID, full `sourceType` array, and unlock state in your own integration. Preserve the event context so aggregated profile labels are not mistaken for event-specific registration. + +## Current limitations + +- Event list and event detail do not currently expose a public `hasVisitors` field. Use Visitor action precheck for a known event. +- Personnel list does not currently accept a source filter. +- Visitor coverage varies by event and must not be inferred from event category, size, or location. + +--- + ## Build event recommendations Source: /guides/build-event-recommendations @@ -518,9 +681,9 @@ curl -X POST "https://platform.lensmor.com/external/events/rank" \ Source: /guides/find-and-unlock-event -Use this guide when your integration needs to move from discovery to base event coverage, visitor access, or both. +Use this guide when your integration needs to move from discovery to base event coverage, registered Visitor access, or both. -Event unlocks are intentionally explicit. Lensmor lets you preview exhibitor and personnel data first, then choose the access layer the user actually needs. +Event unlocks are intentionally explicit. Lensmor lets you preview exhibitor and personnel data first, then choose the access layer the user actually needs. Visitor records are registered event attendees obtained through organizer or data-provider partnerships and are available only for selected events. ## Recommended workflow @@ -574,6 +737,7 @@ Locked events can return a response like this: "fullName": "Jane Doe", "title": "VP of Partnerships", "companyName": "Example Retail Co", + "sourceType": ["exhibitor", "social"], "email": null, "contactUnlockStatus": "locked" } @@ -608,7 +772,7 @@ Locked events can return a response like this: } ``` -Use `semantics` to decide whether to unlock. Do not infer full access from pagination alone. +Use `semantics` to decide whether to unlock base event coverage. `semantics.accessMode` does not describe the separate Visitor layer, so do not infer Visitor access from pagination or `"full"` base access alone. ## 4. Unlock base event access @@ -645,7 +809,7 @@ If `alreadyUnlocked` is `true`, the event was already available and `creditsUsed Visitor access is separate from base event access: -- `POST /external/events/:id/visitors/unlock` costs `3000` credits and requires base event access, an active subscription, and visitor data. +- `POST /external/events/:id/visitors/unlock` costs `3000` credits and requires base event access, an active subscription, and registered Visitor data for the event. - `POST /external/events/:id/full-access/unlock` atomically charges only for missing layers: `2000` for base event access plus `3000` for visitor access. Precheck the intended action before execution: @@ -663,7 +827,7 @@ curl -X POST "https://platform.lensmor.com/external/actions/precheck" \ }' ``` -Continue only when `allowed` is `true`, show the returned `credits` to the user, and refresh the balance after execution. If full-access precheck returns `no_contacts_available` because visitor data is unavailable, use base event unlock when exhibitor and personnel coverage is still needed. +Continue only when `allowed` is `true`, show the returned `credits` to the user, and refresh the balance after execution. Read `detail.visitor_data_available` instead of inferring availability from the event category or list counts. If full-access precheck returns `no_contacts_available` because Visitor data is unavailable, use base event unlock when exhibitor and personnel coverage is still needed. ## Common mistakes @@ -673,6 +837,7 @@ Continue only when `allowed` is `true`, show the returned `credits` to the user, - Ignoring `semantics`. It tells you whether a list is in preview mode or has full access. - Calling visitor unlock before base event access. Precheck returns `state_conflict` in that state. - Treating base event access and visitor access as the same layer. They have separate access records and credit costs. +- Treating Social Signals as official registration evidence. Only the Visitor label represents registered attendees in the current source taxonomy. ## Related endpoints @@ -695,6 +860,9 @@ Continue only when `allowed` is `true`, show the returned `credits` to the user, Fetch people associated with a selected event. + + Map product attendee labels to API `sourceType` values. + --- @@ -729,12 +897,13 @@ Most personnel responses include `id`, name, title, company context, and `contac "fullName": "Jane Doe", "title": "VP of Partnerships", "companyName": "Example Retail Co", + "sourceType": ["exhibitor", "visitors"], "email": null, "contactUnlockStatus": "locked" } ``` -Only send records that are still locked. Already unlocked contacts are not charged again, but filtering them out keeps your task easier to audit. +Preserve the full `sourceType` array when moving a selected attendee into your enrichment workflow. Only send records that are still locked. Already unlocked contacts are not charged again, but filtering them out keeps your task easier to audit. ## 2. Start the unlock task @@ -1794,7 +1963,7 @@ Source: /api-reference/events/unlock-event-visitor-access Unlock the visitor data layer for an event that already has base event access. -Use this endpoint when the caller needs visitor records in addition to the exhibitor and personnel coverage unlocked by [Unlock event](/api-reference/events/unlock-event-access). +Use this endpoint when the caller needs registered Visitor records in addition to the exhibitor and personnel coverage unlocked by [Unlock event](/api-reference/events/unlock-event-access). Visitor records are obtained through organizer or data-provider partnerships and are available only for selected events. ## Prerequisites @@ -1804,7 +1973,11 @@ Before executing this paid action: 2. Call [Actions precheck](/api-reference/actions/precheck-an-external-action) with `action_type: "unlock_event_visitors"` and the selected `event_id`. 3. Continue only when precheck returns `allowed: true`. -Visitor access requires an active subscription, available visitor data for the event, and enough credits. +Visitor access requires an active subscription, available Visitor data for the event, and enough credits. + + + The product label is **Visitor**, while personnel responses use the API source value `"visitors"`. See [Attendee source types](/concepts/attendee-source-types). + The first successful visitor unlock consumes `3000` credits. Precheck is read-only and should be used before the paid call. @@ -2836,7 +3009,7 @@ Source: /api-reference/personnel/list-event-personnel List personnel records for a specific event. -Use this endpoint when you want a paginated people directory for one event, with optional exhibitor, department, level, and search filters. +Use this endpoint when you want a paginated people directory for one event, with optional exhibitor, department, level, and search filters. Each item can include event-scoped Exhibitor, Social Signals, and Visitor source labels. ## When to use this endpoint @@ -2847,8 +3020,13 @@ Common use cases: - browse people associated with an event - filter by department or seniority - find contacts for a selected exhibitor +- segment accessible attendees by their event-scoped `sourceType` labels - collect personnel IDs before calling [Unlock contact emails](/api-reference/contacts/unlock-contact-emails) + + The endpoint does not currently accept a source filter. Fetch the accessible result set and segment it client-side. See [Attendee source types](/concepts/attendee-source-types). + + ## Endpoint `GET /external/personnel/list` @@ -2894,7 +3072,7 @@ curl "https://platform.lensmor.com/external/personnel/list?event_id=139574&depar "seniorityLevel": "vp", "linkedinUrl": "https://linkedin.com/in/jane-smith", "companyName": "Acme Retail Systems", - "sourceType": ["exhibitor"], + "sourceType": ["exhibitor", "social"], "email": null, "phone": null, "contactUnlockStatus": "locked", @@ -2951,7 +3129,7 @@ curl "https://platform.lensmor.com/external/personnel/list?event_id=139574&depar | `department`, `seniorityLevel` | Normalized role metadata when available. | | `linkedinUrl` | LinkedIn profile URL when available. | | `companyName` | Associated company or exhibitor name. | -| `sourceType` | Normalized source labels for the person record. Values can include `exhibitor`, `social`, and `visitors`; an empty array means no supported source label is available. | +| `sourceType` | Event-scoped, non-exclusive source labels. Product mapping: Exhibitor = `exhibitor`, Social Signals = `social`, Visitor = `visitors`. An empty array means no supported source label is available. | | `email` | Email address if already unlocked for the caller; otherwise `null`. | | `phone` | Phone number if already unlocked for the caller; otherwise `null`. | | `contactUnlockStatus` | Contact access state, such as `locked` or unlocked states. | @@ -2967,7 +3145,7 @@ curl "https://platform.lensmor.com/external/personnel/list?event_id=139574&depar Locked events can still return preview personnel results. Read `semantics` before deciding whether to unlock the event: -- `accessMode` tells you whether the response is preview or full access. +- `accessMode` tells you whether base event coverage is preview or full access. It does not describe the separate Visitor access layer. - `counts.remainingLockedCount` tells you whether more records are hidden. - `unlock.requiredForMoreResults` tells you whether event unlock is useful for this query. - `guidance.message` provides a user-facing explanation. @@ -2980,6 +3158,8 @@ Locked events can still return preview personnel results. Read `semantics` befor ## Notes - Personnel list responses intentionally use the lightweight contact-style response shape. +- A person can have multiple source labels. Preserve every value rather than assigning one exclusive category. +- Visitor records are registered attendees obtained through organizer or data-provider partnerships. Visitor availability and access must be checked separately. - Emails are returned only when the contact is already unlocked for the caller. - Locked events can return preview results. Use `semantics.unlock` to decide whether to call [Unlock event](/api-reference/events/unlock-event-access). - Pagination behavior follows the shared [Pagination conventions](/concepts/pagination). @@ -2998,7 +3178,7 @@ Use this endpoint when you already know the personnel identifier and need profil Use `GET /external/personnel/profile` after a user selects a person from a personnel list, contact search result, or LinkedIn-based event lookup. -This endpoint is intentionally lightweight. Use it to confirm the person's identity and current email unlock state before starting a contact unlock workflow. +This endpoint is intentionally lightweight. Use it to confirm the person's identity, aggregated source labels, and current email unlock state before starting a contact unlock workflow. ## Endpoint `GET /external/personnel/profile` @@ -3030,7 +3210,7 @@ curl "https://platform.lensmor.com/external/personnel/profile?personnel_id=789" "seniorityLevel": "vp", "linkedinUrl": "https://linkedin.com/in/jane-smith", "companyName": "Acme Retail Systems", - "sourceType": ["exhibitor"], + "sourceType": ["exhibitor", "visitors"], "email": null, "phone": null, "contactUnlockStatus": "locked", @@ -3048,7 +3228,7 @@ curl "https://platform.lensmor.com/external/personnel/profile?personnel_id=789" | `department`, `seniorityLevel` | Normalized role metadata when available. | | `linkedinUrl` | Public LinkedIn profile URL when available. | | `companyName` | Associated company or exhibitor. | -| `sourceType` | Normalized source labels such as `exhibitor`, `social`, and `visitors`. | +| `sourceType` | Non-exclusive source labels aggregated across the person's associated events. Product mapping: Exhibitor = `exhibitor`, Social Signals = `social`, Visitor = `visitors`. | | `email` | Email address if already unlocked for the caller; otherwise `null`. | | `phone` | Phone number if already unlocked for the caller; otherwise `null`. | | `contactUnlockStatus` | Current contact access state for this API key owner. | @@ -3067,6 +3247,8 @@ An empty `email` value does not necessarily mean Lensmor has no email data. It c ## Notes - This response stays intentionally lightweight. +- Use [Personnel list](/api-reference/personnel/list-event-personnel) when you need source labels for one specific event. Profile labels can reflect multiple associated events. +- See [Attendee source types](/concepts/attendee-source-types) for label meanings and Visitor access behavior. - Emails are returned only when the contact is already unlocked for the caller. - The response includes `linkedinActivity` and `linkedinActivityStatus` for shape consistency, but they are always `null` on this endpoint. Only [Personnel list](/api-reference/personnel/list-event-personnel) populates LinkedIn activity data. @@ -3466,7 +3648,7 @@ Source: /api-reference/contacts/search-contacts Search contacts by company name. -Use this endpoint when you want a lightweight contact result set keyed off a company query, with optional role filtering. +Use this endpoint when you want a lightweight contact result set keyed off a company query, with optional role filtering and attendee source context aggregated across associated events. ## When to use this endpoint @@ -3522,7 +3704,7 @@ curl "https://platform.lensmor.com/external/contacts/search?company_name=Acme&pe "seniorityLevel": "vp", "linkedinUrl": "https://linkedin.com/in/jane", "companyName": "Acme", - "sourceType": ["exhibitor"], + "sourceType": ["social", "visitors"], "email": null, "phone": null, "contactUnlockStatus": "locked", @@ -3550,7 +3732,7 @@ curl "https://platform.lensmor.com/external/contacts/search?company_name=Acme&pe | `department`, `seniorityLevel` | Normalized role metadata when available. | | `linkedinUrl` | LinkedIn profile URL when available. | | `companyName` | Matched company name. | -| `sourceType` | Normalized source labels for the contact record. Values can include `exhibitor`, `social`, and `visitors`. | +| `sourceType` | Non-exclusive source labels aggregated across associated events. Product mapping: Exhibitor = `exhibitor`, Social Signals = `social`, Visitor = `visitors`. | | `email` | Email if already unlocked for the caller; otherwise `null`. | | `phone` | Phone number if already unlocked for the caller; otherwise `null`. | | `contactUnlockStatus` | Contact access state for this API key owner. | @@ -3572,6 +3754,7 @@ No matching contacts can return an empty paginated response. Use this as a valid ## Notes - Emails are returned only when the contact is already unlocked for the caller. +- Use [Personnel list](/api-reference/personnel/list-event-personnel) when you need source labels for one specific event. See [Attendee source types](/concepts/attendee-source-types) for the full mapping. - Contact-style list responses follow the shared [Pagination conventions](/concepts/pagination). - Each item includes `linkedinActivity` and `linkedinActivityStatus` for shape consistency, but they are always `null` on this endpoint. Only [Personnel list](/api-reference/personnel/list-event-personnel) populates LinkedIn activity data. @@ -4473,6 +4656,79 @@ Use the identifier returned by the matching resource endpoint: --- +## Attendee source types + +Source: /concepts/attendee-source-types + +Lensmor groups people connected to an event under **Attendees**. The `sourceType` array explains how each person is connected to the event or to Lensmor's broader event graph. + +## Product labels and API values + +| Product label | API value | Meaning | +| --- | --- | --- | +| **Exhibitor** | `exhibitor` | A person associated with a company exhibiting at the event. | +| **Social Signals** | `social` | A person identified through LinkedIn signals connected to the event. This label is not proof of official event registration. | +| **Visitor** | `visitors` | A registered event attendee obtained through organizer or data-provider partnerships. Visitor data is available only for selected events. | + + + The product displays **Visitor** in the singular, while the current API value is `"visitors"`. + + +## Labels are not mutually exclusive + +`sourceType` is an array because one person can have more than one source relationship: + +```json +{ + "id": "789", + "fullName": "Jane Smith", + "companyName": "Acme Retail Systems", + "sourceType": ["exhibitor", "social"] +} +``` + +Do not force each person into a single category. Preserve every returned value and treat an empty array as “no supported source label is available.” + +## Source scope differs by endpoint + +- `GET /external/personnel/list` returns source labels in the requested event context. +- `GET /external/personnel/profile` can aggregate source labels across the person's associated events. +- `GET /external/contacts/search` can also return source labels aggregated across associated events because the search is company-scoped rather than event-scoped. + +If your UI needs to say “this person is a Visitor for this event,” use the event-scoped personnel list rather than an aggregated profile or contact-search result. + +## Visitor access + +Visitor is a separate access layer from base event access: + +- Base event access expands event-scoped exhibitor and personnel coverage. +- Visitor access adds eligible registered attendee records for events where visitor data is available. +- Call `POST /external/actions/precheck` with `unlock_event_visitors` or `unlock_event_full_access` before attempting a paid unlock. +- A visitor precheck can return `visitor_data_available: false`; treat that as an expected event-level availability state. + +The `semantics.accessMode` field on the personnel list describes base event preview/full access. It does not by itself prove that the separate Visitor layer is unlocked. + +## Filtering + +`GET /external/personnel/list` does not currently accept a `sourceType` filter. Fetch the accessible event-scoped result set, then segment it client-side: + +```js +const visitors = items.filter((person) => + person.sourceType?.includes("visitors") +); +``` + +Because labels can overlap, a person may appear in more than one client-side segment. + +## Related workflows + +- [Build attendee intelligence](/guides/build-attendee-intelligence) +- [Find and unlock an event](/guides/find-and-unlock-event) +- [Credits and access](/concepts/credits-and-access) +- [List event personnel](/api-reference/personnel/list-event-personnel) + +--- + ## Credits and access Source: /concepts/credits-and-access @@ -4503,7 +4759,9 @@ When an event is locked, list responses may include `semantics` metadata describ - whether more results require unlocking the event - which unlock action and credit amount applies -Base event unlock grants full access to event-scoped exhibitor and personnel results. Visitor access is a separate data layer that can be unlocked after base event access or together through the full-access endpoint. +Base event unlock grants full access to event-scoped exhibitor and personnel results. Visitor access is a separate registered-attendee data layer, sourced through organizer or data-provider partnerships, that can be unlocked after base event access or together through the full-access endpoint. + +`semantics.accessMode` on an event-scoped list describes base event access only. It does not prove that Visitor access is unlocked. Use the Visitor or full-access action precheck when registered Visitor records are required. ## Credit-consuming operations | Operation | Typical cost | Notes | @@ -4587,7 +4845,10 @@ Recommended behavior: Unlock base event-scoped exhibitor and personnel coverage. - Unlock missing base and visitor access layers in one atomic call. + Unlock missing base and registered Visitor access layers in one atomic call. + + + Understand Exhibitor, Social Signals, and Visitor labels. Start an asynchronous email unlock task. diff --git a/llms.txt b/llms.txt index b30e4d9..42a1d32 100644 --- a/llms.txt +++ b/llms.txt @@ -1,6 +1,6 @@ # Lensmor API Documentation -> Lensmor Event Intelligence API documentation for event discovery, exhibitor research, personnel lookup, credits, and profile matching. +> Lensmor Event Intelligence API documentation for event discovery, attendee source intelligence, registered visitor access, exhibitor research, contact enrichment, credits, and profile matching. ## Primary Resources diff --git a/openapi.json b/openapi.json index e2295dc..1c2d407 100644 --- a/openapi.json +++ b/openapi.json @@ -2,7 +2,7 @@ "openapi": "3.1.0", "info": { "title": "Lensmor API", - "version": "0.24.0", + "version": "0.24.1", "description": "Lensmor Event Intelligence API for event discovery, exhibitor research, personnel lookup, credits, and profile matching.", "license": { "name": "Lensmor Terms of Service", @@ -1228,7 +1228,7 @@ "Personnel" ], "summary": "List event personnel", - "description": "Return paginated people for an event with preview or full-access semantics and visible coverage counts.", + "description": "Return paginated people for an event with event-scoped attendee source labels and preview or full base-event access semantics. The sourceType array can contain exhibitor, social, and visitors; labels are not mutually exclusive. The endpoint does not currently accept a source filter. Visitor is a separate access layer, so semantics.accessMode does not by itself confirm Visitor access.", "operationId": "listPersonnel", "parameters": [ { @@ -1294,6 +1294,10 @@ "fullName": "Jane Smith", "title": "VP of Retail Technology", "companyName": "Acme Retail Systems", + "sourceType": [ + "exhibitor", + "social" + ], "email": null, "phone": null, "contactUnlockStatus": "locked", @@ -1334,7 +1338,7 @@ "Personnel" ], "summary": "Get personnel profile", - "description": "Return the public professional profile for one personnel identifier.", + "description": "Return the public professional profile for one personnel identifier. The sourceType array can aggregate non-exclusive attendee source labels across the person's associated events.", "operationId": "getPersonnelProfile", "parameters": [ { @@ -1357,6 +1361,10 @@ "seniorityLevel": "vp", "linkedinUrl": "https://linkedin.com/in/jane-smith", "companyName": "Acme Retail Systems", + "sourceType": [ + "exhibitor", + "visitors" + ], "email": null, "phone": null, "contactUnlockStatus": "locked", @@ -1594,7 +1602,7 @@ "Contacts" ], "summary": "Search contacts", - "description": "Search public contact records by required company name and optional role or person-name filters.", + "description": "Search public contact records by required company name and optional role or person-name filters. Returned sourceType arrays can aggregate non-exclusive attendee source labels across associated events.", "operationId": "searchContacts", "parameters": [ { @@ -1645,6 +1653,10 @@ "fullName": "Jane Doe", "title": "VP Marketing", "companyName": "Acme", + "sourceType": [ + "social", + "visitors" + ], "email": null, "phone": null, "contactUnlockStatus": "locked", @@ -3892,7 +3904,7 @@ }, "sourceType": { "type": "array", - "description": "Normalized Lensmor source labels for this person. Possible values are exhibitor, social, and visitors.", + "description": "Lensmor source/business labels for this person. Source labels are not mutually exclusive. Product mapping: Exhibitor is exhibitor, Social Signals is social, and Visitor is visitors. Visitor represents registered attendees obtained through organizer or data-provider partnerships; Social Signals is not proof of official registration. Event personnel lists return event-scoped labels, while personnel profile and contact search can aggregate labels across associated events.", "items": { "type": "string", "enum": [ diff --git a/scripts/sync-public-assets.py b/scripts/sync-public-assets.py index 57cd43a..056dcff 100755 --- a/scripts/sync-public-assets.py +++ b/scripts/sync-public-assets.py @@ -49,9 +49,17 @@ def iter_pages(node: Any) -> Iterable[str]: def navigation_pages(config: dict[str, Any]) -> list[str]: + navigation = config.get("navigation", {}) + languages = navigation.get("languages", []) + if languages: + navigation = next( + (language for language in languages if language.get("default")), + languages[0], + ) + indexed_groups: list[tuple[int, dict[str, Any]]] = [] index = 0 - for tab in config.get("navigation", {}).get("tabs", []): + for tab in navigation.get("tabs", []): for group in tab.get("groups", []): indexed_groups.append((index, group)) index += 1 @@ -231,7 +239,7 @@ def render_api_catalog() -> str: "apis": [ { "name": "Lensmor API", - "description": "Lensmor Event Intelligence API.", + "description": "Lensmor Event and Attendee Intelligence API.", "baseUrl": API_BASE_URL, "openapi": f"{DOCS_BASE_URL}/openapi.json", } @@ -243,7 +251,7 @@ def render_api_catalog() -> str: def render_llms_index() -> str: return f"""# Lensmor API Documentation -> Lensmor Event Intelligence API documentation for event discovery, exhibitor research, personnel lookup, credits, and profile matching. +> Lensmor Event Intelligence API documentation for event discovery, attendee source intelligence, registered visitor access, exhibitor research, contact enrichment, credits, and profile matching. ## Primary Resources diff --git a/scripts/test_sync_public_assets.py b/scripts/test_sync_public_assets.py index feebf9d..2f4c01e 100644 --- a/scripts/test_sync_public_assets.py +++ b/scripts/test_sync_public_assets.py @@ -137,7 +137,7 @@ def test_public_openapi_has_descriptions_and_examples(self) -> None: def test_company_search_contract_matches_current_credit_rule(self) -> None: spec = json.loads(self.sync.OPENAPI_SOURCE.read_text(encoding="utf-8")) - self.assertEqual(spec["info"]["version"], "0.24.0") + self.assertEqual(spec["info"]["version"], "0.24.1") company_search = spec["paths"]["/external/exhibitors/search-by-company-name"]["post"] self.assertIn("non-empty", company_search["description"]) @@ -267,6 +267,20 @@ def test_v024_access_and_balance_contracts(self) -> None: source_type["items"]["enum"], ["exhibitor", "social", "visitors"], ) + self.assertIn("not mutually exclusive", source_type["description"]) + + source_examples = [ + spec["paths"]["/external/personnel/list"]["get"]["responses"]["200"] + ["content"]["application/json"]["example"]["items"][0]["sourceType"], + spec["paths"]["/external/personnel/profile"]["get"]["responses"]["200"] + ["content"]["application/json"]["example"]["sourceType"], + spec["paths"]["/external/contacts/search"]["get"]["responses"]["200"] + ["content"]["application/json"]["example"]["items"][0]["sourceType"], + ] + for example in source_examples: + with self.subTest(example=example): + self.assertTrue(example) + self.assertTrue(set(example).issubset({"exhibitor", "social", "visitors"})) for page_name in ( "unlock-event-visitor-access.mdx", @@ -351,6 +365,28 @@ def test_llms_full_covers_every_navigation_entry(self) -> None: ) self.assertEqual(len(sources), len(set(sources))) + def test_multilingual_navigation_has_unique_existing_pages(self) -> None: + config = json.loads(self.sync.DOCS_JSON.read_text(encoding="utf-8")) + languages = config["navigation"]["languages"] + + self.assertEqual(languages[0]["language"], "en") + self.assertTrue(languages[0]["default"]) + self.assertEqual(languages[1]["language"], "zh-Hans") + + all_pages: list[str] = [] + for language in languages: + for tab in language.get("tabs", []): + for group in tab.get("groups", []): + for page in group.get("pages", []): + if self.sync.OPERATION_PAGE_RE.match(page): + continue + all_pages.extend(self.sync.iter_pages(page)) + + self.assertEqual(len(all_pages), len(set(all_pages))) + for page in all_pages: + with self.subTest(page=page): + self.assertTrue((ROOT / f"{page}.mdx").exists()) + def test_legacy_api_routes_have_permanent_redirects(self) -> None: missing = self.sync.missing_legacy_redirects() self.assertEqual(missing, []) @@ -373,6 +409,7 @@ def test_internal_api_reference_links_target_generated_routes(self) -> None: ROOT / "index.mdx", *sorted((ROOT / "guides").rglob("*.mdx")), *sorted((ROOT / "concepts").rglob("*.mdx")), + *sorted((ROOT / "zh-Hans").rglob("*.mdx")), *sorted((ROOT / "api-reference-backup").rglob("*.mdx")), ] invalid: list[str] = [] diff --git a/zh-Hans/authentication.mdx b/zh-Hans/authentication.mdx new file mode 100644 index 0000000..7e468e8 --- /dev/null +++ b/zh-Hans/authentication.mdx @@ -0,0 +1,77 @@ +--- +title: "身份验证" +description: "了解如何使用用户 API Key 和 Bearer Token 调用 Lensmor API,并安全管理生产环境密钥。" +--- + +所有 Lensmor API 请求都需要用户 API Key。 + +## 获取 API Key + +1. 登录或创建 [Lensmor App](https://app.lensmor.com) 账号。 +2. 升级到付费订阅。 +3. 打开 **Settings → API Keys**。 +4. 点击 **Create API Key**,填写标签并立即复制完整密钥。密钥只显示一次。 + +API Key 以 `sk_` 开头: + +```text +sk_your_api_key +``` + +建议将密钥保存到服务端环境变量: + +```bash +export LENSMOR_API_KEY="sk_your_api_key" +``` + + + API Key 面向已订阅账号。如果升级后仍未看到 API Keys,请联系 Lensmor 支持。 + + +## Base URL + +`https://platform.lensmor.com` + +例如,`GET /external/events/list` 的完整请求地址是 `GET https://platform.lensmor.com/external/events/list`。 + +## Header 格式 + +```http +Authorization: Bearer sk_your_api_key +``` + +## 请求示例 + +```bash +curl "https://platform.lensmor.com/external/events/list?page=1&pageSize=20" \ + -H "Authorization: Bearer $LENSMOR_API_KEY" +``` + +缺少、格式错误、已撤销或无效的密钥会返回 `401 Unauthorized`。 + +## 安全建议 + +- 将 API Key 存放在 Secret Manager 或服务端环境变量中。 +- 不要把 API Key 放进浏览器 JavaScript、移动端安装包、公开代码仓库或分析事件。 +- 不要记录完整 `Authorization` Header。 +- 密钥意外泄露后应立即轮换。 +- 浏览器应用应通过自己的服务端代理调用 Lensmor API。 + + + 用户 API Key 是敏感凭证。它可以访问 Lensmor 数据,并可能触发与 Lensmor SaaS 共用 Credits 的付费工作流。 + + +## 测试与生产环境 + +Lensmor 当前没有独立 Sandbox,所有 API 请求都会访问生产 Base URL。 + +安全测试建议: + +- 优先使用只读接口,例如 Events List、Event Detail、Exhibitors List、Personnel List 和 Credits Balance。 +- 工作流验证完成前,不要调用 Event、Visitor、Full Access、Contact Unlock 或付费企业搜索接口。 +- 付费操作前调用 `GET /external/credits/balance`。 +- API 与 Lensmor SaaS 共用订阅账号的 Credits。 + + + 先完成只读数据流和错误处理,再启用任何会消耗 Credits 的操作。 + diff --git a/zh-Hans/concepts/attendee-source-types.mdx b/zh-Hans/concepts/attendee-source-types.mdx new file mode 100644 index 0000000..8b98652 --- /dev/null +++ b/zh-Hans/concepts/attendee-source-types.mdx @@ -0,0 +1,71 @@ +--- +title: "参会人员来源类型" +description: "了解 Lensmor 产品中的 Exhibitor、Social Signals 和 Visitor 如何映射到 API sourceType,以及多来源、作用域和访问规则。" +--- + +Lensmor 在产品中将与展会相关的人员统一归入 **Attendees(参会人员)**。API 返回的 `sourceType` 数组用于说明一个人与展会或 Lensmor 展会数据网络之间的来源关系。 + +## 产品标签与 API 值 + +| 产品标签 | API 值 | 含义 | +| --- | --- | --- | +| **Exhibitor** | `exhibitor` | 与该展会参展企业相关的参会人员。 | +| **Social Signals** | `social` | 通过 LinkedIn 相关信号识别出的、与该展会相关的人员。该标签不代表主办方正式注册记录。 | +| **Visitor** | `visitors` | Lensmor 通过主办方或数据合作伙伴获得的注册参会访客。只有部分展会提供 Visitor 数据。 | + + + 产品界面使用单数 **Visitor**,当前 API 值为复数 `"visitors"`。 + + +## 一个人可以拥有多个标签 + +`sourceType` 是数组,三个来源标签不是互斥分类。例如,一个参展企业员工也可能在 LinkedIn 上公开表达过参会意向: + +```json +{ + "id": "789", + "fullName": "Jane Smith", + "companyName": "Acme Retail Systems", + "sourceType": ["exhibitor", "social"] +} +``` + +集成时应保留所有返回值,不要强制把一个人归入唯一分类。空数组表示当前没有可用的受支持来源标签。 + +## 不同接口的来源作用域 + +- `GET /external/personnel/list` 返回指定展会范围内的来源标签。 +- `GET /external/personnel/profile` 可能聚合该人员在多个关联展会中的来源标签。 +- `GET /external/contacts/search` 以企业为查询范围,也可能返回跨关联展会聚合后的来源标签。 + +如果界面需要表达“这个人是本场展会的 Visitor”,应以展会范围的 Personnel List 为准,而不是使用聚合后的 Profile 或 Contact Search 结果。 + +## Visitor 访问规则 + +Visitor 与基础 Event Access 是两个独立访问层: + +- 基础 Event Access 扩展展会范围内的 Exhibitor 和 Personnel 数据覆盖。 +- Visitor Access 为具备数据的展会增加注册参会访客记录。 +- 执行付费解锁前,请通过 `POST /external/actions/precheck` 检查 `unlock_event_visitors` 或 `unlock_event_full_access`。 +- 当 `visitor_data_available` 为 `false` 时,表示该展会当前没有可用的 Visitor 数据,这是正常的展会级状态。 + +Personnel List 返回的 `semantics.accessMode` 只描述基础 Event Access,不能单独证明 Visitor Access 已解锁。 + +## 来源筛选 + +`GET /external/personnel/list` 当前没有 `sourceType` 服务端筛选参数。请先获取当前可访问的数据,再在客户端分类: + +```js +const visitors = items.filter((person) => + person.sourceType?.includes("visitors") +); +``` + +由于标签可能重叠,同一个人可以同时出现在多个分类中。 + +## 相关文档 + +- [构建参会人员洞察](/zh-Hans/guides/build-attendee-intelligence) +- [查找并解锁展会](/zh-Hans/guides/find-and-unlock-event) +- [Credits 与访问权限](/zh-Hans/concepts/credits-and-access) +- [Personnel List(英文)](/api-reference/personnel/list-event-personnel) diff --git a/zh-Hans/concepts/credits-and-access.mdx b/zh-Hans/concepts/credits-and-access.mdx new file mode 100644 index 0000000..8334c00 --- /dev/null +++ b/zh-Hans/concepts/credits-and-access.mdx @@ -0,0 +1,90 @@ +--- +title: "Credits 与访问权限" +description: "了解 Lensmor Credits、展会 Preview、基础 Event Access、Visitor Access、联系方式解锁和安全计费流程。" +--- + +Lensmor 的大多数只读发现接口只需要有效 API Key;展会解锁、联系方式解锁和部分企业搜索可能消耗 Credits。 + +API 与 Lensmor SaaS 共用订阅账号的 Credits 余额。 + +## Credits 余额 + +使用 `GET /external/credits/balance` 查看: + +- `subscriptionBalance` — 当前订阅周期的 Credits。 +- `addonBalance` — 有效的一次性 Add-On Credits。 +- `giftBalance` — 不过期的 Gift Credits。 +- `totalBalance` — 当前可用总余额。 +- `resetAt` — 最早的订阅 Credits 到期时间戳,或 `null`。 +- `addonExpireAt` — 最晚的 Add-On Credits 到期时间戳,或 `null`。 + +## Preview 与访问层 + +展会范围的 Exhibitor 和 Personnel List 在 Event Access 未解锁时仍可能返回预览结果。`semantics` 会说明: + +- 当前是 `preview` 还是基础 `full` access +- 当前可见结果数量 +- 是否还有结果需要解锁 +- 对应操作和预计 Credits + +基础 Event Access 用于扩大 Exhibitor 和 Personnel 覆盖。Visitor Access 是独立的注册参会访客数据层,数据来自主办方或数据合作伙伴。 + + + `semantics.accessMode` 只描述基础 Event Access,不能证明 Visitor Access 已解锁。需要 Visitor 时,请使用 Visitor 或 Full Access action precheck。 + + +## 可能消耗 Credits 的操作 + +| 操作 | 常见成本 | 说明 | +| --- | --- | --- | +| 基础 Event Access | `2000` Credits | 展会尚未解锁且有可用人员数据时,扩大 Exhibitor/Personnel 覆盖。 | +| Visitor Access | `3000` Credits | 需要基础 Event Access、有效订阅和可用 Visitor 数据;重复解锁免费。 | +| Full Event Access | `0`–`5000` Credits | 一次补齐缺失的基础层和 Visitor 层。 | +| Contact Email Unlock | 每个可计费联系人 `15` Credits | 创建异步任务,已解锁联系人不重复计费。 | +| Contact Phone Unlock | 每个可计费联系人 `150` Credits | 创建异步任务,已解锁联系人不重复计费。 | +| Exhibitor Company Search | 非空结果 `50` Credits | 空结果不消耗 Credits。 | +| Exhibitor Event Search | 非空结果 `50` Credits | 空结果不消耗 Credits。 | + +价格可能随套餐或产品政策调整。接口响应和商业协议是最终计费依据。 + +## 安全集成模式 + + + + 向用户展示即将解锁或搜索的展会、企业或联系人。 + + + 调用 `GET /external/credits/balance`。 + + + 对访问相关操作执行 precheck,并显示返回的 Credits。 + + + 只有用户确认后才调用付费接口。 + + + 操作完成后重新获取余额、访问状态和目标数据。 + + + +## 最终计费核对 + +Precheck 和界面估算不是最终账单。付费操作后应刷新 Credits Balance 和目标资源,特别是以下情况: + +- 展会或联系人可能已经解锁 +- 异步任务包含成功、失败和不符合条件的混合结果 +- 请求超时后需要判断是否真的执行成功 + +## 处理 `402 Payment Required` + +- 停止自动重试 +- 展示所需 Credits 或余额不足提示 +- 让用户选择增加 Credits、缩小范围或取消 +- 避免对同一个解锁意图重复创建任务 + +## 相关文档 + +- [参会人员来源类型](/zh-Hans/concepts/attendee-source-types) +- [查找并解锁展会](/zh-Hans/guides/find-and-unlock-event) +- [解锁联系人邮箱](/zh-Hans/guides/unlock-contact-emails) +- [Credits Balance(英文)](/api-reference/credits/get-credits-balance) diff --git a/zh-Hans/guides/build-attendee-intelligence.mdx b/zh-Hans/guides/build-attendee-intelligence.mdx new file mode 100644 index 0000000..89a91b5 --- /dev/null +++ b/zh-Hans/guides/build-attendee-intelligence.mdx @@ -0,0 +1,121 @@ +--- +title: "构建参会人员洞察" +description: "使用 Exhibitor、Social Signals 和 Visitor 来源标签构建活动营销、ABM 和销售触达工作流。" +--- + +本指南介绍如何围绕展会参会人员构建 Field Marketing、Account-Based Event Planning 和 Sales Engagement 工作流。 + +Lensmor Attendees 包含三种来源标签: + +- **Exhibitor**(`exhibitor`)— 与参展企业相关的参会人员。 +- **Social Signals**(`social`)— 通过 LinkedIn 相关信号识别出的展会相关人员。 +- **Visitor**(`visitors`)— 通过主办方或数据合作伙伴获得的注册参会访客。 + +一个人可以同时拥有多个标签。完整规则请参阅[参会人员来源类型](/zh-Hans/concepts/attendee-source-types)。 + +## 推荐流程 + + + + 搜索展会目录、进行展会排序或使用 Profile Matching。调用人员接口前,先获取并确认目标展会的 `eventId`。 + + + 调用 `GET /external/personnel/list`,同时读取人员的 `sourceType` 数组和响应级 `semantics` 对象。 + + + 调用 Visitor 或 Full Access 的 action precheck。只有部分展会提供 Visitor 数据。 + + + 基础 Event Access 用于扩大 Exhibitor/Personnel 覆盖;Visitor Access 用于注册访客;Full Access 可一次解锁两个缺失的访问层。 + + + 在客户端按来源分类,筛选与业务目标相关的人员,只对最终选中的 Personnel ID 解锁邮箱或电话。 + + + +## 1. 获取展会人员 + +```bash +curl "https://platform.lensmor.com/external/personnel/list?event_id=139574&page=1&pageSize=50" \ + -H "Authorization: Bearer $LENSMOR_API_KEY" +``` + +每个人员记录都可能包含多个 `sourceType`: + +```json +{ + "id": "789", + "fullName": "Jane Smith", + "title": "VP of Partnerships", + "companyName": "Acme Retail Systems", + "sourceType": ["exhibitor", "social"], + "contactUnlockStatus": "locked" +} +``` + +需要判断某个来源与当前展会的关系时,应使用 Personnel List。Personnel Profile 和 Contact Search 可能聚合该人员在多个关联展会中的来源标签。 + +## 2. 在客户端分类 + +Personnel List 当前没有来源筛选参数。请保留重叠标签,并在应用中分类: + +```js +const bySource = { + exhibitor: items.filter((person) => person.sourceType?.includes("exhibitor")), + social: items.filter((person) => person.sourceType?.includes("social")), + visitors: items.filter((person) => person.sourceType?.includes("visitors")), +}; +``` + +不要把三个分类数量直接相加作为唯一人员总数,因为同一个人可能属于多个分类。 + +## 3. 检查 Visitor 可用性和访问状态 + +Visitor 是独立的数据访问层。向用户展示解锁确认前,应先执行 precheck: + +```bash +curl -X POST "https://platform.lensmor.com/external/actions/precheck" \ + -H "Authorization: Bearer $LENSMOR_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "action_type": "unlock_event_visitors", + "call_source": "api", + "params": { + "event_id": "139574" + } + }' +``` + +读取 `allowed`、`credits`、`reason` 和 `detail.visitor_data_available`。如果基础 Event Access 仍未解锁,应改用 Full Access precheck,或先解锁基础 Event Access。 + + + Personnel List 中的 `semantics.accessMode: "full"` 只表示基础 Event Access。需要注册 Visitor 数据时,必须另外检查 Visitor precheck 状态。 + + +## 4. 只补全最终选中的人员 + +完成参会人员优先级判断后,收集目标人员的 ID,调用邮箱或电话解锁工作流。这些操作可能消耗 Credits,并可能异步执行,因此应先展示选中范围和预计成本,再保存任务 ID 并轮询结果。 + +## 常见 Use Cases + +### Field Marketing + +比较 Exhibitor、Social Signals 和 Visitor 数据,理解当前可访问的展会受众,并优先选择注册 Visitor 或重点参展企业人员。 + +### Account-Based Event Planning + +结合 `GET /external/exhibitors/list` 与展会 Personnel List,识别正在参展的目标客户,并分析相关人员的来源、职位和部门。 + +### Sales Engagement + +根据来源标签、职位、部门和职级筛选参会人员,只对用户最终确认的触达名单解锁联系方式。 + +### CRM 数据补全 + +在客户自己的集成中保存 Person ID、Event ID、完整 `sourceType` 数组和解锁状态。保留展会上下文,避免把聚合来源误解成当前展会的注册状态。 + +## 当前限制 + +- Event List 和 Event Detail 暂未公开 `hasVisitors` 字段,已知展会应通过 Visitor action precheck 判断。 +- Personnel List 暂不支持来源筛选参数。 +- Visitor 覆盖因展会而异,不能通过展会类别、规模或地点推断。 diff --git a/zh-Hans/guides/find-and-unlock-event.mdx b/zh-Hans/guides/find-and-unlock-event.mdx new file mode 100644 index 0000000..d9dd51c --- /dev/null +++ b/zh-Hans/guides/find-and-unlock-event.mdx @@ -0,0 +1,124 @@ +--- +title: "查找并解锁展会" +description: "发现目标展会、检查 Preview 数据,并通过 credit-safe precheck 解锁基础 Event Access、Visitor Access 或 Full Access。" +--- + +当集成需要从展会发现进入完整数据访问时,请使用本指南。 + +Lensmor 允许先查看 Exhibitor 和 Personnel 预览,再选择实际需要的访问层。Visitor 是通过主办方或数据合作伙伴获得的注册参会访客,只有部分展会提供。 + +## 推荐流程 + + + + 搜索展会目录、对展会排序,或使用 Profile Matching 生成候选清单。 + + + 获取 Event Detail,核对名称、日期、场地、地区和来源 URL。 + + + 调用展会范围列表接口;展会未解锁时,读取 `semantics` 理解预览限制。 + + + 基础 Event Access 用于扩大 Exhibitor/Personnel 覆盖;Visitor Access 用于注册访客;Full Access 用于同时补齐两个访问层。付费操作前必须 precheck。 + + + +## 1. 搜索展会 + +```bash +curl "https://platform.lensmor.com/external/events/list?keyword=retail&page=1&pageSize=20" \ + -H "Authorization: Bearer $LENSMOR_API_KEY" +``` + +## 2. 获取展会详情 + +```bash +curl "https://platform.lensmor.com/external/events/139574" \ + -H "Authorization: Bearer $LENSMOR_API_KEY" +``` + +解锁前请确认 `name`、`dateStart`、`dateEnd`、`venue`、`country` 和 `url`。 + +## 3. 查看展会范围人员 + +```bash +curl "https://platform.lensmor.com/external/personnel/list?event_id=139574&page=1&pageSize=20" \ + -H "Authorization: Bearer $LENSMOR_API_KEY" +``` + +示例响应中的人员可以带有来源标签: + +```json +{ + "items": [ + { + "id": "789", + "fullName": "Jane Doe", + "title": "VP of Partnerships", + "companyName": "Example Retail Co", + "sourceType": ["exhibitor", "social"], + "email": null, + "contactUnlockStatus": "locked" + } + ], + "semantics": { + "accessMode": "preview", + "previewLimit": 50, + "unlock": { + "requiredForMoreResults": true, + "actionType": "unlock_event_personnel", + "credits": 2000 + } + } +} +``` + +`semantics.accessMode` 只描述基础 Event Access。即使它为 `"full"`,也不能据此判断 Visitor Access 已解锁。 + +## 4. 解锁基础 Event Access + +```bash +curl -X POST "https://platform.lensmor.com/external/events/139574/unlock" \ + -H "Authorization: Bearer $LENSMOR_API_KEY" \ + -H "x-call-source: api" +``` + +第一次成功解锁通常消耗 `2000` Credits;重复解锁不重复收费。以接口响应和商业协议为最终计费依据。 + +## 5. 增加 Visitor Access 或解锁 Full Access + +- `POST /external/events/:id/visitors/unlock`:在基础 Event Access 已存在、账号有有效订阅且展会有 Visitor 数据时,第一次成功解锁消耗 `3000` Credits。 +- `POST /external/events/:id/full-access/unlock`:一次性补齐缺失访问层,动态消耗 `0`、`2000`、`3000` 或 `5000` Credits。 + +执行前调用 precheck: + +```bash +curl -X POST "https://platform.lensmor.com/external/actions/precheck" \ + -H "Authorization: Bearer $LENSMOR_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "action_type": "unlock_event_full_access", + "call_source": "api", + "params": { + "event_id": "139574" + } + }' +``` + +只有 `allowed` 为 `true` 时才继续,并向用户展示返回的 `credits`。通过 `detail.visitor_data_available` 判断 Visitor 数据是否可用。如果 Full Access precheck 因没有 Visitor 数据返回 `no_contacts_available`,但仍需要 Exhibitor/Personnel 覆盖,可以改用基础 Event Access。 + +## 常见错误 + +- 未检查 Preview 内容就直接解锁。 +- 把 `semantics.accessMode: "full"` 当作 Visitor Access 已解锁。 +- 把 Social Signals 当作主办方正式注册证明;当前只有 Visitor 标签代表注册参会访客。 +- Visitor 解锁前没有先获得基础 Event Access。 +- 对付费操作自动重试,导致用户难以核对最终状态。 + +## 相关文档 + +- [参会人员来源类型](/zh-Hans/concepts/attendee-source-types) +- [Credits 与访问权限](/zh-Hans/concepts/credits-and-access) +- [Visitor Unlock(英文)](/api-reference/events/unlock-event-visitor-access) +- [Full Event Access(英文)](/api-reference/events/unlock-full-event-access) diff --git a/zh-Hans/guides/quickstart.mdx b/zh-Hans/guides/quickstart.mdx new file mode 100644 index 0000000..f1553b0 --- /dev/null +++ b/zh-Hans/guides/quickstart.mdx @@ -0,0 +1,97 @@ +--- +title: "快速开始" +description: "完成第一个 Lensmor API 请求,搜索展会、查看参展商和参会人员来源,并安全处理访问解锁。" +--- + +本指南介绍多数 Lensmor 集成都会使用的基础流程: + +1. 从企业 Profile、目标客户描述、关键词或市场范围开始。 +2. 发现相关展会。 +3. 查看参展商和参会人员,包括 Exhibitor、Social Signals 与 Visitor 来源标签。 +4. 只在数据可行动时解锁基础 Event Access、Visitor Access、Full Access 或联系人字段。 + +## 开始前准备 + +你需要有效的用户 API Key 和能够发送 HTTPS 请求的环境。 + +```bash +export LENSMOR_API_KEY="sk_your_api_key" +``` + +## 1. 检查 Credits 余额 + +```bash +curl "https://platform.lensmor.com/external/credits/balance" \ + -H "Authorization: Bearer $LENSMOR_API_KEY" +``` + +该响应包含订阅 Credits、Add-On Credits、Gift Credits、总余额和可用的重置时间。API 与 Lensmor SaaS 共用同一 Credits 余额。 + +## 2. 搜索展会 + +```bash +curl "https://platform.lensmor.com/external/events/list?keyword=retail&country=United%20States&page=1&pageSize=20" \ + -H "Authorization: Bearer $LENSMOR_API_KEY" +``` + +使用响应中的 `eventId` 调用后续展会范围接口。 + +## 3. 获取展会详情 + +```bash +curl "https://platform.lensmor.com/external/events/139574" \ + -H "Authorization: Bearer $LENSMOR_API_KEY" +``` + +在查看人员或进行解锁前,先确认展会名称、日期、场地、地区和来源 URL。 + +## 4. 查看 Exhibitors 或 Personnel + +```bash +curl "https://platform.lensmor.com/external/personnel/list?event_id=139574&page=1&pageSize=20" \ + -H "Authorization: Bearer $LENSMOR_API_KEY" +``` + +Personnel 记录可能包含多值 `sourceType`: + +```json +{ + "id": "789", + "fullName": "Jane Smith", + "companyName": "Acme Retail Systems", + "sourceType": ["exhibitor", "social"] +} +``` + +映射关系为: + +- Exhibitor → `exhibitor` +- Social Signals → `social` +- Visitor → `visitors` + +一个人可以拥有多个标签。完整说明见[参会人员来源类型](/zh-Hans/concepts/attendee-source-types)。 + +当响应包含 `semantics.accessMode: "preview"` 时,应读取 `semantics.counts.visibleTotal` 和 `semantics.unlock.requiredForMoreResults`。这些字段描述基础 Event Access。 + +Visitor 是独立的注册参会访客数据层。执行 Visitor 或 Full Access 解锁前,调用 `POST /external/actions/precheck`,分别使用 `unlock_event_visitors` 或 `unlock_event_full_access`,并检查 Visitor 数据是否可用以及预计消耗的 Credits。 + +## 5. 处理错误和限流 + +- `401 Unauthorized`:API Key 缺失或无效。 +- `402 Payment Required`:余额或访问状态不足以完成付费操作。 +- `404 Not Found`:目标展会、企业、人员或任务不存在。 +- `429 Too Many Requests`:应退避后重试。 + +## 下一步 + + + + 使用三类来源标签构建 Field Marketing、ABM 和销售触达工作流。 + + + 理解 Preview、基础 Event Access、Visitor Access 和 Full Access。 + + + 发起异步邮箱解锁任务并轮询结果。 + + diff --git a/zh-Hans/guides/unlock-contact-emails.mdx b/zh-Hans/guides/unlock-contact-emails.mdx new file mode 100644 index 0000000..f802e2c --- /dev/null +++ b/zh-Hans/guides/unlock-contact-emails.mdx @@ -0,0 +1,102 @@ +--- +title: "解锁联系人邮箱" +description: "通过 Lensmor 异步任务解锁联系人邮箱,轮询任务状态、处理 Credits,并将已确认结果同步到自己的系统。" +--- + +当集成已经识别出值得补全的参会人员,并需要邮箱用于销售触达或 CRM 数据补全时,请使用本工作流。 + +邮箱解锁是异步操作:创建请求会校验批次并启动任务,集成随后轮询任务接口直到完成。 + +## 何时使用 + +常见输入来自: + +- [Personnel List(英文)](/api-reference/personnel/list-event-personnel) +- [Personnel Profile(英文)](/api-reference/personnel/get-personnel-profile) +- [Contact Search(英文)](/api-reference/contacts/search-contacts) + + + 不要把邮箱解锁当作盲目批量导出。只提交用户选中或评分流程确认值得补全的人员。 + + +## 1. 收集 Personnel ID + +```json +{ + "id": "789", + "fullName": "Jane Doe", + "title": "VP of Partnerships", + "companyName": "Example Retail Co", + "sourceType": ["exhibitor", "visitors"], + "email": null, + "contactUnlockStatus": "locked" +} +``` + +将人员带入补全流程时,应保留完整 `sourceType` 数组和 Event ID。只提交仍处于锁定状态的人员。 + +## 2. 创建解锁任务 + +```bash +curl -X POST "https://platform.lensmor.com/external/contacts/unlock" \ + -H "Authorization: Bearer $LENSMOR_API_KEY" \ + -H "Content-Type: application/json" \ + -H "x-call-source: api" \ + -d '{ + "event_id": "139574", + "personnel_ids": ["789", "790"] + }' +``` + +每次最多接受 `100` 个 Personnel ID。 + +```json +{ + "status": "accepted", + "task_id": "321", + "job_id": "321" +} +``` + +保存 `task_id`,后续轮询需要使用该值。 + +## 3. 轮询任务 + +```bash +curl "https://platform.lensmor.com/external/contacts/unlock-tasks/321" \ + -H "Authorization: Bearer $LENSMOR_API_KEY" +``` + +使用退避策略轮询,不要进行紧密循环。 + +## 4. 处理结果 + +- 任务仍在进行:继续按退避策略轮询。 +- 任务完成:检查每一项结果。只有状态已解锁且确实返回邮箱时,才计为交付成功。 +- 任务失败:展示错误,让用户决定是否重试。 +- `404 Not Found`:任务 ID 无效或当前 API Key 无权查看。 + +一个任务可能同时包含成功、失败、不符合条件和未解析的联系人,应分别展示。 + +## Credits + +邮箱解锁当前对每个可计费联系人消耗 `15` Credits: + +- 已解锁联系人不会重复计费。 +- 超过 `100` 个 Personnel ID 的批次会被拒绝。 +- 余额不足返回 `402 Payment Required`。 +- 接口响应和商业协议是最终计费依据。 + +## 推荐集成行为 + +- 创建任务前展示锁定联系人数量。 +- 大批次前调用 `GET /external/credits/balance`。 +- 保存任务 ID,让轮询可以在中断后恢复。 +- 对 `429 Too Many Requests` 使用退避。 +- 任务完成后按需重新获取余额和 Personnel/Contact 状态。 + +## 相关文档 + +- [参会人员来源类型](/zh-Hans/concepts/attendee-source-types) +- [Credits 与访问权限](/zh-Hans/concepts/credits-and-access) +- [Contact Unlock Task(英文)](/api-reference/contacts/get-contact-unlock-task) diff --git a/zh-Hans/index.mdx b/zh-Hans/index.mdx new file mode 100644 index 0000000..8b2e6c0 --- /dev/null +++ b/zh-Hans/index.mdx @@ -0,0 +1,88 @@ +--- +title: "Lensmor API 文档" +description: "使用 Lensmor API 构建展会与参会人员洞察、参展商研究、注册 Visitor 访问和联系人补全工作流。" +--- + +使用 Lensmor API 构建展会与参会人员洞察工作流。你可以发现展会、评估展会匹配度、查看参展商和参会人员来源,在数据可用时访问注册 Visitor,并在需要行动时解锁联系方式。 + +当前文档版本:`v0.24.1` + +## Base URL + +`https://platform.lensmor.com` + +本文档中的接口路径都基于这个地址。例如,`GET /external/events/list` 的完整地址是 `GET https://platform.lensmor.com/external/events/list`。 + +## 获取 API Key + +在 [app.lensmor.com](https://app.lensmor.com) 创建账号并升级到付费订阅,然后进入 **Settings → API Keys** 创建用户 API Key。 + +```http +Authorization: Bearer sk_your_api_key +``` + +## 可以构建什么 + + + + 根据关键词、地区、类别、质量和 Profile Fit 搜索与排序展会。 + + + 区分 Exhibitor、Social Signals 和注册 Visitor,同时保留一个人的多个来源标签。 + + + 从预览数据进入基础 Event Access、Visitor Access,或一次解锁两个访问层。 + + + 为选中的人员发起异步邮箱解锁任务,并轮询到结果完成。 + + + +## 应该从哪个接口开始 + +| 已知信息或目标 | 建议接口 | 说明 | +| --- | --- | --- | +| 关键词、地区或日期范围 | [Events List(英文)](/api-reference/events/list-events) | 搜索展会目录。 | +| 企业网站或目标客户描述 | [Apply Profile(英文)](/api-reference/profile-matching/apply-profile-and-get-recommended-events) | 基于 Profile 返回排序后的展会。 | +| 已知 Event ID | [Exhibitors List(英文)](/api-reference/exhibitors/list-event-exhibitors) 或 [Personnel List(英文)](/api-reference/personnel/list-event-personnel) | 获取展会范围内的企业和人员;人员记录可能带有三类来源标签。 | +| 需要基础数据和 Visitor 数据 | [Full Event Access(英文)](/api-reference/events/unlock-full-event-access) | 先 precheck,再按缺失访问层动态消耗 `0`–`5000` Credits。 | +| 已知 Personnel ID,需要邮箱 | [Unlock Contact Emails(英文)](/api-reference/contacts/unlock-contact-emails) | 发起异步邮箱解锁任务。 | + +## 推荐集成流程 + + + + 创建用户 API Key,并通过 `Authorization: Bearer sk_your_api_key` 发送。 + + + 调用 `GET /external/credits/balance`,并对展会、Visitor 或联系方式解锁执行相应 precheck。 + + + 根据工作流选择 Events、Exhibitors、Personnel、Contacts 或 Profile Matching 接口。 + + + 将 `sourceType` 作为多值数组处理,并区分展会范围标签与跨关联展会聚合标签。 + + + 读取 `semantics`,显式处理 `402 Payment Required` 和 `429 Too Many Requests`。 + + + +## 第一个请求 + +```bash +curl "https://platform.lensmor.com/external/events/list?page=1&pageSize=20" \ + -H "Authorization: Bearer $LENSMOR_API_KEY" +``` + +请求成功后,继续阅读[快速开始](/zh-Hans/guides/quickstart)。如请求失败,请检查[身份验证](/zh-Hans/authentication)。 + +## 核心概念 + +- [参会人员来源类型](/zh-Hans/concepts/attendee-source-types) +- [Credits 与访问权限](/zh-Hans/concepts/credits-and-access) +- [英文 API Reference](/api-reference/events/list-events) + + + 当前简体中文版本覆盖核心集成与参会人员工作流。OpenAPI 驱动的 API Reference 暂时保留英文,以确保机器契约只有一个权威版本。 +