diff --git a/README.md b/README.md index 0e363e1..e1833b0 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ pnpm dlx mintlify dev ## Changelog -See `changelog.mdx` for versioned documentation updates. The current documentation version is `v0.24.3`. +See `changelog.mdx` for versioned documentation updates. The current documentation version is `v0.25.0`. --- diff --git a/api-reference-backup/actions/precheck.mdx b/api-reference-backup/actions/precheck.mdx index 52a6890..af945b0 100644 --- a/api-reference-backup/actions/precheck.mdx +++ b/api-reference-backup/actions/precheck.mdx @@ -20,7 +20,7 @@ See [Authentication](/authentication) ## Request body | Name | Required | Type | Notes | | --- | --- | --- | --- | -| `action_type` | Yes | string | Supported customer actions include `query_event_personnel`, `unlock_event_contacts`, `unlock_event_visitors`, `unlock_event_full_access`, `unlock_contact_emails`, `unlock_contact_phones`, `search_exhibitor_events`, and `others`. | +| `action_type` | Yes | string | Supported customer actions include `query_event_personnel`, `unlock_event_contacts`, `unlock_event_visitors`, `unlock_event_full_access`, `unlock_contact_emails`, `unlock_contact_phones`, `search_exhibitor_events`, `search_personnel_events_by_name`, and `others`. | | `params` | Yes | object | Action-specific inputs, such as `{ "event_id": "26855" }`. | | `call_source` | No | string | Source label such as `api` or `agent`. | | `locale` | No | string | Optional locale, such as `en-US`. | @@ -99,6 +99,7 @@ curl -X POST "https://platform.lensmor.com/external/actions/precheck" \ ## Notes - Precheck is read-only. It does not unlock records, create tasks, or consume credits. - `query_event_personnel` is useful before calling [Personnel list](/api-reference/personnel/list-event-personnel). +- `search_personnel_events_by_name` is useful before calling [Personnel events by name](/api-reference/personnel/search-personnel-related-events-by-name). Put `person_name` and optional `date_start_from` and `date_start_to` values in `params`. A valid-name precheck quotes `50` credits; execution charges only when the lookup returns events. - `unlock_event_visitors` requires base event access first. It can report `3000` expected credits, `state_conflict` when the event is still locked, `no_contacts_available` when visitor data is unavailable, or `forbidden` when the account has no active subscription. - `unlock_event_full_access` calculates only the missing access layers: `2000` for base event access plus `3000` for visitor access. It can therefore report `0`, `2000`, `3000`, or `5000` credits. - For full-access precheck, `detail` includes `event_unlocked`, `visitor_unlocked`, `visitor_data_available`, `event_access_credits`, `visitor_access_credits`, and `full_access_credits`. diff --git a/api-reference-backup/openapi.json b/api-reference-backup/openapi.json index 46f1a8e..6a3b645 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.3", + "version": "0.25.0", "description": "Lensmor Event Intelligence API for event discovery, exhibitor research, personnel lookup, credits, and profile matching.", "license": { "name": "Lensmor Terms of Service", @@ -1546,6 +1546,144 @@ } } }, + "/external/personnel/events/by-name": { + "get": { + "tags": [ + "Personnel" + ], + "summary": "Search personnel related events by name", + "description": "Return a paginated, deduplicated event list for up to 50 personnel records whose full name exactly matches the supplied name. This endpoint requires an active paid user. A non-empty result consumes 50 credits; an empty result consumes 0 credits. At most 10 requests can run concurrently for one user.", + "operationId": "searchPersonnelEventsByName", + "parameters": [ + { + "name": "person_name", + "in": "query", + "required": true, + "description": "Exact personnel full name. Matching is case-insensitive and ignores leading and trailing whitespace.", + "schema": { + "type": "string", + "minLength": 1, + "maxLength": 200 + }, + "example": "Jane Smith" + }, + { + "name": "date_start_from", + "in": "query", + "required": false, + "description": "Inclusive lower bound for the event start date. Defaults to the current date when omitted.", + "schema": { + "type": "string", + "format": "date" + }, + "example": "2026-08-10" + }, + { + "name": "date_start_to", + "in": "query", + "required": false, + "description": "Inclusive upper bound for the event start date. Omit for no upper bound.", + "schema": { + "type": "string", + "format": "date" + }, + "example": "2026-12-31" + }, + { + "$ref": "#/components/parameters/Page" + }, + { + "$ref": "#/components/parameters/PageSize" + }, + { + "$ref": "#/components/parameters/CallSource" + } + ], + "responses": { + "200": { + "description": "Paginated events, or a business-error envelope when the per-user concurrency limit is exceeded", + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/EventPage" + }, + { + "$ref": "#/components/schemas/ConcurrencyLimitBusinessError" + } + ] + }, + "examples": { + "success": { + "value": { + "items": [ + { + "id": "501", + "eventId": "139574", + "name": "Retail Technology Expo 2026", + "nickname": null, + "description": "Retail technology event", + "url": "https://example.com/events/retail-technology-expo-2026", + "dateStart": "2026-10-01", + "dateEnd": "2026-10-03", + "venue": "Las Vegas Convention Center", + "city": "Las Vegas", + "region": "NV", + "country": "United States", + "exhibitorCount": 950, + "hasVisitors": true, + "sponsorMatchStarred": 0, + "image": null, + "dataSource": "Lensmor" + } + ], + "total": 1, + "page": 1, + "pageSize": 20, + "totalPages": 1, + "hasMore": false + } + }, + "concurrencyLimitExceeded": { + "value": { + "code": 429, + "message": "Too many concurrent requests for this endpoint", + "errorKey": "USER_CONCURRENCY_LIMIT_EXCEEDED", + "data": null, + "details": null, + "traceId": "trace-123" + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "402": { + "$ref": "#/components/responses/PaymentRequired" + }, + "403": { + "description": "Active paid subscription required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "429": { + "$ref": "#/components/responses/RateLimited" + } + } + } + }, "/external/personnel/unlock-linkedin-activity": { "post": { "tags": [ @@ -2714,6 +2852,40 @@ } } }, + "ConcurrencyLimitBusinessError": { + "type": "object", + "required": [ + "code", + "message", + "errorKey", + "data", + "details", + "traceId" + ], + "properties": { + "code": { + "type": "integer", + "const": 429 + }, + "message": { + "type": "string" + }, + "errorKey": { + "type": "string", + "const": "USER_CONCURRENCY_LIMIT_EXCEEDED" + }, + "data": { + "type": "null" + }, + "details": { + "type": "null" + }, + "traceId": { + "type": "string" + } + }, + "additionalProperties": false + }, "CreditBalance": { "type": "object", "required": [ @@ -4332,6 +4504,7 @@ "unlock_contact_emails", "unlock_contact_phones", "search_exhibitor_events", + "search_personnel_events_by_name", "others" ] }, diff --git a/api-reference-backup/personnel/events-by-name.mdx b/api-reference-backup/personnel/events-by-name.mdx new file mode 100644 index 0000000..b3c191d --- /dev/null +++ b/api-reference-backup/personnel/events-by-name.mdx @@ -0,0 +1,116 @@ +--- +title: "Personnel events by name" +description: "Find upcoming or date-filtered Lensmor events associated with personnel records by exact full-name matching." +openapi: "openapi.json GET /external/personnel/events/by-name" +--- + +Find events associated with a person when you know their full name but do not have a Lensmor `personnel_id` or LinkedIn URL. + +This endpoint returns the combined, deduplicated events for exact-name personnel matches. The response is a paginated event list; it does not include a separate `personnel` object. + +## Endpoint + +`GET /external/personnel/events/by-name` + +## Authentication and access + +See [Authentication](/authentication). The API-key owner must have an active paid subscription. + +## Success status code + +`200 OK` + +## Query parameters + +| Name | Required | Type | Notes | +| --- | --- | --- | --- | +| `person_name` | Yes | string | Exact full name, length `1` to `200`. Matching is case-insensitive and leading/trailing whitespace is ignored. Partial and fuzzy matching are not used. | +| `date_start_from` | No | date | Inclusive lower bound on event start date. Defaults to the current date, so the default result contains upcoming events. | +| `date_start_to` | No | date | Inclusive upper bound on event start date. Omit for no upper bound. | +| `page` | No | integer | Defaults to `1`. | +| `pageSize` | No | integer | Defaults to `20`; maximum `100`. This paginates events, not personnel candidates. | +| `x-call-source` | No | header | Usage source, `api` or `agent`; defaults to `api`. | + +## Request example + +```bash +curl "https://platform.lensmor.com/external/personnel/events/by-name?person_name=Jane%20Smith&date_start_from=2026-08-10&date_start_to=2026-12-31&page=1&pageSize=20" \ + -H "Authorization: Bearer $LENSMOR_API_KEY" \ + -H "x-call-source: api" +``` + +## Response example + +```json +{ + "items": [ + { + "id": "501", + "eventId": "139574", + "name": "Retail Technology Expo 2026", + "nickname": null, + "description": "Retail technology event", + "url": "https://example.com/events/retail-technology-expo-2026", + "dateStart": "2026-10-01", + "dateEnd": "2026-10-03", + "venue": "Las Vegas Convention Center", + "city": "Las Vegas", + "region": "NV", + "country": "United States", + "exhibitorCount": 950, + "hasVisitors": true, + "sponsorMatchStarred": 0, + "image": null, + "dataSource": "Lensmor" + } + ], + "total": 1, + "page": 1, + "pageSize": 20, + "totalPages": 1, + "hasMore": false +} +``` + +## Matching and result behavior + +- The server considers up to `50` personnel records with the exact full name. This candidate window is fixed and independent of event `pageSize`. +- Events from those exact-name records are combined and deduplicated, then ordered by `dateStart` ascending. +- Both date bounds apply inclusively to `dateStart`. Set an earlier `date_start_from` to include historical events. +- No personnel match or no qualifying event returns `200 OK` with `items: []`, `total: 0`, `totalPages: 0`, and `hasMore: false`. + +## Credits and precheck + +A non-empty event result consumes `50` credits. An empty result consumes `0` credits. If the result is non-empty but the balance is insufficient, the API returns `402 Payment Required` instead of the event page. + +Call [Actions precheck](/api-reference/actions/precheck-an-external-action) first with `action_type: "search_personnel_events_by_name"`. Put `person_name` and any date bounds in `params`. Precheck quotes `50` credits for a valid name because it does not execute the lookup; the execution endpoint charges only for a non-empty result. + +## Concurrency limit + +Each user can run up to `10` calls to this endpoint concurrently. When that limit is exceeded, the current Business API contract returns HTTP `200` with a business-error body: + +```json +{ + "code": 429, + "message": "Too many concurrent requests for this endpoint", + "errorKey": "USER_CONCURRENCY_LIMIT_EXCEEDED", + "data": null, + "details": null, + "traceId": "trace-123" +} +``` + +Treat this body as an error and retry after one or more in-flight requests finish. This differs from the ordinary HTTP `429 Too Many Requests` rate-limit response. + +## Error responses + +- `400 Bad Request` for a missing, blank, overlong, or invalid query value +- `401 Unauthorized` +- `402 Payment Required` for insufficient credits on a non-empty lookup +- `403 Forbidden` when the API-key owner has no active paid subscription +- `429 Too Many Requests` for ordinary rate limiting + +## Notes + +- For the most precise identity lookup, use [Personnel related events](/api-reference/personnel/list-personnel-related-events) when you already have a `personnel_id`, or [Personnel events by LinkedIn](/api-reference/personnel/list-personnel-related-events-by-linkedin-url) when you have a LinkedIn URL. +- Event items use the standard public event shape. `dataSource` is Always `Lensmor`; `sponsorMatchStarred` is `0` or `1`; `hasVisitors` signals Visitor-data availability and does not prove access is unlocked. diff --git a/api-reference/openapi.json b/api-reference/openapi.json index 46f1a8e..6a3b645 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.3", + "version": "0.25.0", "description": "Lensmor Event Intelligence API for event discovery, exhibitor research, personnel lookup, credits, and profile matching.", "license": { "name": "Lensmor Terms of Service", @@ -1546,6 +1546,144 @@ } } }, + "/external/personnel/events/by-name": { + "get": { + "tags": [ + "Personnel" + ], + "summary": "Search personnel related events by name", + "description": "Return a paginated, deduplicated event list for up to 50 personnel records whose full name exactly matches the supplied name. This endpoint requires an active paid user. A non-empty result consumes 50 credits; an empty result consumes 0 credits. At most 10 requests can run concurrently for one user.", + "operationId": "searchPersonnelEventsByName", + "parameters": [ + { + "name": "person_name", + "in": "query", + "required": true, + "description": "Exact personnel full name. Matching is case-insensitive and ignores leading and trailing whitespace.", + "schema": { + "type": "string", + "minLength": 1, + "maxLength": 200 + }, + "example": "Jane Smith" + }, + { + "name": "date_start_from", + "in": "query", + "required": false, + "description": "Inclusive lower bound for the event start date. Defaults to the current date when omitted.", + "schema": { + "type": "string", + "format": "date" + }, + "example": "2026-08-10" + }, + { + "name": "date_start_to", + "in": "query", + "required": false, + "description": "Inclusive upper bound for the event start date. Omit for no upper bound.", + "schema": { + "type": "string", + "format": "date" + }, + "example": "2026-12-31" + }, + { + "$ref": "#/components/parameters/Page" + }, + { + "$ref": "#/components/parameters/PageSize" + }, + { + "$ref": "#/components/parameters/CallSource" + } + ], + "responses": { + "200": { + "description": "Paginated events, or a business-error envelope when the per-user concurrency limit is exceeded", + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/EventPage" + }, + { + "$ref": "#/components/schemas/ConcurrencyLimitBusinessError" + } + ] + }, + "examples": { + "success": { + "value": { + "items": [ + { + "id": "501", + "eventId": "139574", + "name": "Retail Technology Expo 2026", + "nickname": null, + "description": "Retail technology event", + "url": "https://example.com/events/retail-technology-expo-2026", + "dateStart": "2026-10-01", + "dateEnd": "2026-10-03", + "venue": "Las Vegas Convention Center", + "city": "Las Vegas", + "region": "NV", + "country": "United States", + "exhibitorCount": 950, + "hasVisitors": true, + "sponsorMatchStarred": 0, + "image": null, + "dataSource": "Lensmor" + } + ], + "total": 1, + "page": 1, + "pageSize": 20, + "totalPages": 1, + "hasMore": false + } + }, + "concurrencyLimitExceeded": { + "value": { + "code": 429, + "message": "Too many concurrent requests for this endpoint", + "errorKey": "USER_CONCURRENCY_LIMIT_EXCEEDED", + "data": null, + "details": null, + "traceId": "trace-123" + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "402": { + "$ref": "#/components/responses/PaymentRequired" + }, + "403": { + "description": "Active paid subscription required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "429": { + "$ref": "#/components/responses/RateLimited" + } + } + } + }, "/external/personnel/unlock-linkedin-activity": { "post": { "tags": [ @@ -2714,6 +2852,40 @@ } } }, + "ConcurrencyLimitBusinessError": { + "type": "object", + "required": [ + "code", + "message", + "errorKey", + "data", + "details", + "traceId" + ], + "properties": { + "code": { + "type": "integer", + "const": 429 + }, + "message": { + "type": "string" + }, + "errorKey": { + "type": "string", + "const": "USER_CONCURRENCY_LIMIT_EXCEEDED" + }, + "data": { + "type": "null" + }, + "details": { + "type": "null" + }, + "traceId": { + "type": "string" + } + }, + "additionalProperties": false + }, "CreditBalance": { "type": "object", "required": [ @@ -4332,6 +4504,7 @@ "unlock_contact_emails", "unlock_contact_phones", "search_exhibitor_events", + "search_personnel_events_by_name", "others" ] }, diff --git a/changelog.mdx b/changelog.mdx index bff1c6c..f42a7b2 100644 --- a/changelog.mdx +++ b/changelog.mdx @@ -5,6 +5,20 @@ description: "Versioned Lensmor API documentation updates, newly documented endp Track documentation updates, newly documented API capabilities, and behavior clarifications that may affect integrations. +## v0.25.0 + +Released August 10, 2026. + +### Added + +- Documented `GET /external/personnel/events/by-name` for reverse-looking up events from an exact personnel full name. +- Documented `person_name`, optional event-start date bounds, event pagination, the fixed `50`-person candidate window, active-paid-user access, credit behavior, and the per-user concurrency limit of `10`. +- Added `search_personnel_events_by_name` to the Actions precheck contract. + +### Changed + +- Updated OpenAPI metadata to version `0.25.0` and regenerated the machine-readable documentation resources. + ## v0.24.3 Released August 6, 2026. diff --git a/docs.json b/docs.json index 36774c4..75b2430 100644 --- a/docs.json +++ b/docs.json @@ -116,6 +116,7 @@ "GET /external/personnel/profile", "GET /external/personnel/events", "GET /external/personnel/events/by-linkedin", + "GET /external/personnel/events/by-name", "POST /external/personnel/unlock-linkedin-activity", "POST /external/personnel/generate-outreach-message", "GET /external/personnel/outreach" @@ -283,6 +284,11 @@ "destination": "/api-reference/personnel/list-personnel-related-events-by-linkedin-url", "permanent": true }, + { + "source": "/api-reference/personnel/events-by-name", + "destination": "/api-reference/personnel/search-personnel-related-events-by-name", + "permanent": true + }, { "source": "/api-reference/personnel/generate-outreach-message", "destination": "/api-reference/personnel/generate-outreach-messages", diff --git a/index.mdx b/index.mdx index 250a77f..5968f82 100644 --- a/index.mdx +++ b/index.mdx @@ -7,7 +7,7 @@ Build event and attendee intelligence workflows with the Lensmor API. Use it to 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.3` +Current documentation version: `v0.25.0` ## Base URL `https://platform.lensmor.com` diff --git a/llms-full.txt b/llms-full.txt index 0ce4bee..da4761a 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -11,7 +11,7 @@ Build event and attendee intelligence workflows with the Lensmor API. Use it to 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.3` +Current documentation version: `v0.25.0` ## Base URL `https://platform.lensmor.com` @@ -209,6 +209,20 @@ Source: /changelog Track documentation updates, newly documented API capabilities, and behavior clarifications that may affect integrations. +## v0.25.0 + +Released August 10, 2026. + +### Added + +- Documented `GET /external/personnel/events/by-name` for reverse-looking up events from an exact personnel full name. +- Documented `person_name`, optional event-start date bounds, event pagination, the fixed `50`-person candidate window, active-paid-user access, credit behavior, and the per-user concurrency limit of `10`. +- Added `search_personnel_events_by_name` to the Actions precheck contract. + +### Changed + +- Updated OpenAPI metadata to version `0.25.0` and regenerated the machine-readable documentation resources. + ## v0.24.3 Released August 6, 2026. @@ -1244,7 +1258,7 @@ See [Authentication](/authentication) ## Request body | Name | Required | Type | Notes | | --- | --- | --- | --- | -| `action_type` | Yes | string | Supported customer actions include `query_event_personnel`, `unlock_event_contacts`, `unlock_event_visitors`, `unlock_event_full_access`, `unlock_contact_emails`, `unlock_contact_phones`, `search_exhibitor_events`, and `others`. | +| `action_type` | Yes | string | Supported customer actions include `query_event_personnel`, `unlock_event_contacts`, `unlock_event_visitors`, `unlock_event_full_access`, `unlock_contact_emails`, `unlock_contact_phones`, `search_exhibitor_events`, `search_personnel_events_by_name`, and `others`. | | `params` | Yes | object | Action-specific inputs, such as `{ "event_id": "26855" }`. | | `call_source` | No | string | Source label such as `api` or `agent`. | | `locale` | No | string | Optional locale, such as `en-US`. | @@ -1323,6 +1337,7 @@ curl -X POST "https://platform.lensmor.com/external/actions/precheck" \ ## Notes - Precheck is read-only. It does not unlock records, create tasks, or consume credits. - `query_event_personnel` is useful before calling [Personnel list](/api-reference/personnel/list-event-personnel). +- `search_personnel_events_by_name` is useful before calling [Personnel events by name](/api-reference/personnel/search-personnel-related-events-by-name). Put `person_name` and optional `date_start_from` and `date_start_to` values in `params`. A valid-name precheck quotes `50` credits; execution charges only when the lookup returns events. - `unlock_event_visitors` requires base event access first. It can report `3000` expected credits, `state_conflict` when the event is still locked, `no_contacts_available` when visitor data is unavailable, or `forbidden` when the account has no active subscription. - `unlock_event_full_access` calculates only the missing access layers: `2000` for base event access plus `3000` for visitor access. It can therefore report `0`, `2000`, `3000`, or `5000` credits. - For full-access precheck, `detail` includes `event_unlocked`, `visitor_unlocked`, `visitor_data_available`, `event_access_credits`, `visitor_access_credits`, and `full_access_credits`. @@ -3531,6 +3546,123 @@ Recommended production behavior: --- +## Personnel events by name + +Source: /api-reference/personnel/search-personnel-related-events-by-name + +Find events associated with a person when you know their full name but do not have a Lensmor `personnel_id` or LinkedIn URL. + +This endpoint returns the combined, deduplicated events for exact-name personnel matches. The response is a paginated event list; it does not include a separate `personnel` object. + +## Endpoint + +`GET /external/personnel/events/by-name` + +## Authentication and access + +See [Authentication](/authentication). The API-key owner must have an active paid subscription. + +## Success status code + +`200 OK` + +## Query parameters + +| Name | Required | Type | Notes | +| --- | --- | --- | --- | +| `person_name` | Yes | string | Exact full name, length `1` to `200`. Matching is case-insensitive and leading/trailing whitespace is ignored. Partial and fuzzy matching are not used. | +| `date_start_from` | No | date | Inclusive lower bound on event start date. Defaults to the current date, so the default result contains upcoming events. | +| `date_start_to` | No | date | Inclusive upper bound on event start date. Omit for no upper bound. | +| `page` | No | integer | Defaults to `1`. | +| `pageSize` | No | integer | Defaults to `20`; maximum `100`. This paginates events, not personnel candidates. | +| `x-call-source` | No | header | Usage source, `api` or `agent`; defaults to `api`. | + +## Request example + +```bash +curl "https://platform.lensmor.com/external/personnel/events/by-name?person_name=Jane%20Smith&date_start_from=2026-08-10&date_start_to=2026-12-31&page=1&pageSize=20" \ + -H "Authorization: Bearer $LENSMOR_API_KEY" \ + -H "x-call-source: api" +``` + +## Response example + +```json +{ + "items": [ + { + "id": "501", + "eventId": "139574", + "name": "Retail Technology Expo 2026", + "nickname": null, + "description": "Retail technology event", + "url": "https://example.com/events/retail-technology-expo-2026", + "dateStart": "2026-10-01", + "dateEnd": "2026-10-03", + "venue": "Las Vegas Convention Center", + "city": "Las Vegas", + "region": "NV", + "country": "United States", + "exhibitorCount": 950, + "hasVisitors": true, + "sponsorMatchStarred": 0, + "image": null, + "dataSource": "Lensmor" + } + ], + "total": 1, + "page": 1, + "pageSize": 20, + "totalPages": 1, + "hasMore": false +} +``` + +## Matching and result behavior + +- The server considers up to `50` personnel records with the exact full name. This candidate window is fixed and independent of event `pageSize`. +- Events from those exact-name records are combined and deduplicated, then ordered by `dateStart` ascending. +- Both date bounds apply inclusively to `dateStart`. Set an earlier `date_start_from` to include historical events. +- No personnel match or no qualifying event returns `200 OK` with `items: []`, `total: 0`, `totalPages: 0`, and `hasMore: false`. + +## Credits and precheck + +A non-empty event result consumes `50` credits. An empty result consumes `0` credits. If the result is non-empty but the balance is insufficient, the API returns `402 Payment Required` instead of the event page. + +Call [Actions precheck](/api-reference/actions/precheck-an-external-action) first with `action_type: "search_personnel_events_by_name"`. Put `person_name` and any date bounds in `params`. Precheck quotes `50` credits for a valid name because it does not execute the lookup; the execution endpoint charges only for a non-empty result. + +## Concurrency limit + +Each user can run up to `10` calls to this endpoint concurrently. When that limit is exceeded, the current Business API contract returns HTTP `200` with a business-error body: + +```json +{ + "code": 429, + "message": "Too many concurrent requests for this endpoint", + "errorKey": "USER_CONCURRENCY_LIMIT_EXCEEDED", + "data": null, + "details": null, + "traceId": "trace-123" +} +``` + +Treat this body as an error and retry after one or more in-flight requests finish. This differs from the ordinary HTTP `429 Too Many Requests` rate-limit response. + +## Error responses + +- `400 Bad Request` for a missing, blank, overlong, or invalid query value +- `401 Unauthorized` +- `402 Payment Required` for insufficient credits on a non-empty lookup +- `403 Forbidden` when the API-key owner has no active paid subscription +- `429 Too Many Requests` for ordinary rate limiting + +## Notes + +- For the most precise identity lookup, use [Personnel related events](/api-reference/personnel/list-personnel-related-events) when you already have a `personnel_id`, or [Personnel events by LinkedIn](/api-reference/personnel/list-personnel-related-events-by-linkedin-url) when you have a LinkedIn URL. +- Event items use the standard public event shape. `dataSource` is Always `Lensmor`; `sponsorMatchStarred` is `0` or `1`; `hasVisitors` signals Visitor-data availability and does not prove access is unlocked. + +--- + ## Unlock LinkedIn activity Source: /api-reference/personnel/unlock-linkedin-activity diff --git a/openapi.json b/openapi.json index 46f1a8e..6a3b645 100644 --- a/openapi.json +++ b/openapi.json @@ -2,7 +2,7 @@ "openapi": "3.1.0", "info": { "title": "Lensmor API", - "version": "0.24.3", + "version": "0.25.0", "description": "Lensmor Event Intelligence API for event discovery, exhibitor research, personnel lookup, credits, and profile matching.", "license": { "name": "Lensmor Terms of Service", @@ -1546,6 +1546,144 @@ } } }, + "/external/personnel/events/by-name": { + "get": { + "tags": [ + "Personnel" + ], + "summary": "Search personnel related events by name", + "description": "Return a paginated, deduplicated event list for up to 50 personnel records whose full name exactly matches the supplied name. This endpoint requires an active paid user. A non-empty result consumes 50 credits; an empty result consumes 0 credits. At most 10 requests can run concurrently for one user.", + "operationId": "searchPersonnelEventsByName", + "parameters": [ + { + "name": "person_name", + "in": "query", + "required": true, + "description": "Exact personnel full name. Matching is case-insensitive and ignores leading and trailing whitespace.", + "schema": { + "type": "string", + "minLength": 1, + "maxLength": 200 + }, + "example": "Jane Smith" + }, + { + "name": "date_start_from", + "in": "query", + "required": false, + "description": "Inclusive lower bound for the event start date. Defaults to the current date when omitted.", + "schema": { + "type": "string", + "format": "date" + }, + "example": "2026-08-10" + }, + { + "name": "date_start_to", + "in": "query", + "required": false, + "description": "Inclusive upper bound for the event start date. Omit for no upper bound.", + "schema": { + "type": "string", + "format": "date" + }, + "example": "2026-12-31" + }, + { + "$ref": "#/components/parameters/Page" + }, + { + "$ref": "#/components/parameters/PageSize" + }, + { + "$ref": "#/components/parameters/CallSource" + } + ], + "responses": { + "200": { + "description": "Paginated events, or a business-error envelope when the per-user concurrency limit is exceeded", + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/EventPage" + }, + { + "$ref": "#/components/schemas/ConcurrencyLimitBusinessError" + } + ] + }, + "examples": { + "success": { + "value": { + "items": [ + { + "id": "501", + "eventId": "139574", + "name": "Retail Technology Expo 2026", + "nickname": null, + "description": "Retail technology event", + "url": "https://example.com/events/retail-technology-expo-2026", + "dateStart": "2026-10-01", + "dateEnd": "2026-10-03", + "venue": "Las Vegas Convention Center", + "city": "Las Vegas", + "region": "NV", + "country": "United States", + "exhibitorCount": 950, + "hasVisitors": true, + "sponsorMatchStarred": 0, + "image": null, + "dataSource": "Lensmor" + } + ], + "total": 1, + "page": 1, + "pageSize": 20, + "totalPages": 1, + "hasMore": false + } + }, + "concurrencyLimitExceeded": { + "value": { + "code": 429, + "message": "Too many concurrent requests for this endpoint", + "errorKey": "USER_CONCURRENCY_LIMIT_EXCEEDED", + "data": null, + "details": null, + "traceId": "trace-123" + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "402": { + "$ref": "#/components/responses/PaymentRequired" + }, + "403": { + "description": "Active paid subscription required", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + }, + "429": { + "$ref": "#/components/responses/RateLimited" + } + } + } + }, "/external/personnel/unlock-linkedin-activity": { "post": { "tags": [ @@ -2714,6 +2852,40 @@ } } }, + "ConcurrencyLimitBusinessError": { + "type": "object", + "required": [ + "code", + "message", + "errorKey", + "data", + "details", + "traceId" + ], + "properties": { + "code": { + "type": "integer", + "const": 429 + }, + "message": { + "type": "string" + }, + "errorKey": { + "type": "string", + "const": "USER_CONCURRENCY_LIMIT_EXCEEDED" + }, + "data": { + "type": "null" + }, + "details": { + "type": "null" + }, + "traceId": { + "type": "string" + } + }, + "additionalProperties": false + }, "CreditBalance": { "type": "object", "required": [ @@ -4332,6 +4504,7 @@ "unlock_contact_emails", "unlock_contact_phones", "search_exhibitor_events", + "search_personnel_events_by_name", "others" ] }, diff --git a/scripts/test_sync_public_assets.py b/scripts/test_sync_public_assets.py index d05e782..cabdb95 100644 --- a/scripts/test_sync_public_assets.py +++ b/scripts/test_sync_public_assets.py @@ -35,6 +35,7 @@ ("GET", "/external/personnel/profile"), ("GET", "/external/personnel/events"), ("GET", "/external/personnel/events/by-linkedin"), + ("GET", "/external/personnel/events/by-name"), ("POST", "/external/personnel/unlock-linkedin-activity"), ("POST", "/external/personnel/generate-outreach-message"), ("GET", "/external/personnel/outreach"), @@ -137,7 +138,26 @@ 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.3") + self.assertEqual(spec["info"]["version"], "0.25.0") + + by_name = spec["paths"]["/external/personnel/events/by-name"]["get"] + self.assertIn("up to 50 personnel records", by_name["description"]) + self.assertIn("10 requests", by_name["description"]) + self.assertEqual( + by_name["responses"]["200"]["content"]["application/json"]["schema"]["oneOf"][0]["$ref"], + "#/components/schemas/EventPage", + ) + self.assertEqual( + by_name["responses"]["200"]["content"]["application/json"]["examples"] + ["concurrencyLimitExceeded"]["value"]["errorKey"], + "USER_CONCURRENCY_LIMIT_EXCEEDED", + ) + self.assertTrue({"400", "401", "402", "403", "429"}.issubset(by_name["responses"])) + self.assertIn( + "search_personnel_events_by_name", + spec["components"]["schemas"]["ActionPrecheckRequest"]["properties"] + ["action_type"]["enum"], + ) company_search = spec["paths"]["/external/exhibitors/search-by-company-name"]["post"] self.assertIn("non-empty", company_search["description"]) @@ -334,6 +354,7 @@ def test_event_prose_uses_the_public_event_shape(self) -> None: / "actions-apply-recommended-events-paged.mdx", ROOT / "api-reference-backup" / "personnel" / "events.mdx", ROOT / "api-reference-backup" / "personnel" / "events-by-linkedin.mdx", + ROOT / "api-reference-backup" / "personnel" / "events-by-name.mdx", ] for path in event_pages: diff --git a/zh-Hans/index.mdx b/zh-Hans/index.mdx index 919d3ea..7f628c1 100644 --- a/zh-Hans/index.mdx +++ b/zh-Hans/index.mdx @@ -5,7 +5,7 @@ description: "使用 Lensmor API 构建展会与参会人员洞察、参展商 使用 Lensmor API 构建展会与参会人员洞察工作流。你可以发现展会、评估展会匹配度、查看参展商和参会人员来源,在数据可用时访问注册 Visitor,并在需要行动时解锁联系方式。 -当前文档版本:`v0.24.3` +当前文档版本:`v0.25.0` ## Base URL