{"openapi":"3.0.0","paths":{"/api/health":{"get":{"operationId":"HealthController_check","parameters":[],"responses":{"200":{"description":"Liveness probe — process is up."}},"tags":["health"]}},"/api/health/deep":{"get":{"operationId":"HealthController_deep","parameters":[],"responses":{"200":{"description":"Readiness probe — pings Postgres + Redis."}},"tags":["health"]}},"/api/admin/users":{"get":{"operationId":"AdminController_users","parameters":[{"name":"q","required":true,"in":"query","schema":{"type":"string"}},{"name":"limit","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["admin"]}},"/api/admin/activation":{"get":{"operationId":"AdminActivationController_overview","parameters":[],"responses":{"200":{"description":""}},"tags":["admin"]}},"/api/admin/activation-letters":{"get":{"operationId":"AdminActivationLettersController_queue","parameters":[],"responses":{"200":{"description":""}},"tags":["admin"]}},"/api/admin/activation-letters/{id}/send":{"post":{"operationId":"AdminActivationLettersController_send","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivationLetterSendDto"}}}},"responses":{"200":{"description":""}},"tags":["admin"]}},"/api/admin/activation-letters/{id}/discard":{"post":{"operationId":"AdminActivationLettersController_discard","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["admin"]}},"/api/admin/monitoring/orgs":{"get":{"operationId":"AdminMonitoringController_orgs","parameters":[{"name":"from","required":true,"in":"query","schema":{"pattern":"^\\d{4}-\\d{2}-\\d{2}$","type":"string"}},{"name":"to","required":true,"in":"query","schema":{"pattern":"^\\d{4}-\\d{2}-\\d{2}$","type":"string"}}],"responses":{"200":{"description":""}},"tags":["admin"]}},"/api/admin/monitoring/trends":{"get":{"operationId":"AdminMonitoringController_trends","parameters":[{"name":"from","required":true,"in":"query","schema":{"pattern":"^\\d{4}-\\d{2}-\\d{2}$","type":"string"}},{"name":"to","required":true,"in":"query","schema":{"pattern":"^\\d{4}-\\d{2}-\\d{2}$","type":"string"}}],"responses":{"200":{"description":""}},"tags":["admin"]}},"/api/admin/monitoring/user-metrics":{"get":{"operationId":"AdminMonitoringController_userMetrics","parameters":[{"name":"from","required":true,"in":"query","schema":{"pattern":"^\\d{4}-\\d{2}-\\d{2}$","type":"string"}},{"name":"to","required":true,"in":"query","schema":{"pattern":"^\\d{4}-\\d{2}-\\d{2}$","type":"string"}}],"responses":{"200":{"description":""}},"tags":["admin"]}},"/api/admin/monitoring/orgs/{orgId}":{"patch":{"operationId":"AdminMonitoringController_setSuspended","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminOrgSuspensionDto"}}}},"responses":{"200":{"description":""}},"tags":["admin"]},"get":{"operationId":"AdminMonitoringController_drilldown","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"from","required":true,"in":"query","schema":{"pattern":"^\\d{4}-\\d{2}-\\d{2}$","type":"string"}},{"name":"to","required":true,"in":"query","schema":{"pattern":"^\\d{4}-\\d{2}-\\d{2}$","type":"string"}}],"responses":{"200":{"description":""}},"tags":["admin"]}},"/api/admin/monitoring/orgs/{orgId}/deactivate":{"post":{"operationId":"AdminMonitoringController_deactivate","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminOrgDeactivationDto"}}}},"responses":{"201":{"description":""}},"tags":["admin"]}},"/api/admin/monitoring/orgs/{orgId}/ai-balance":{"post":{"operationId":"AdminMonitoringController_grantAiBalance","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminOrgAiBalanceGrantDto"}}}},"responses":{"201":{"description":""}},"tags":["admin"]}},"/api/admin/monitoring/orgs/{orgId}/reactivate":{"post":{"operationId":"AdminMonitoringController_reactivate","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["admin"]}},"/api/admin/plans":{"get":{"operationId":"AdminPlanController_list","parameters":[],"responses":{"200":{"description":""}},"tags":["admin"]}},"/api/admin/orgs/{orgId}/plan":{"put":{"operationId":"AdminPlanController_changePlan","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlanChangeDto"}}}},"responses":{"200":{"description":""}},"tags":["admin"]}},"/api/admin/workspaces":{"post":{"operationId":"AdminPlanController_createWorkspace","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminWorkspaceCreateDto"}}}},"responses":{"201":{"description":""}},"tags":["admin"]}},"/api/admin/orgs/{orgId}/owner-invite":{"post":{"operationId":"AdminPlanController_resendOwnerInvite","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminOwnerInviteDto"}}}},"responses":{"200":{"description":""}},"tags":["admin"]}},"/api/admin/email-plan/waiting":{"get":{"operationId":"AdminEmailPlanController_waitingForWorkspace","parameters":[],"responses":{"200":{"description":""}},"tags":["admin"]}},"/api/admin/email-plan/waiting/{organizationId}/workspace":{"post":{"operationId":"AdminEmailPlanController_adopt","parameters":[{"name":"organizationId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdoptWorkspaceForOrgDto"}}}},"responses":{"201":{"description":""}},"tags":["admin"]}},"/api/admin/seat-pool/seats":{"get":{"operationId":"AdminSeatPoolController_seats","parameters":[],"responses":{"200":{"description":""}},"tags":["admin"]}},"/api/admin/seat-pool/seats/{channelAccountId}":{"patch":{"operationId":"AdminSeatPoolController_setEligibility","parameters":[{"name":"channelAccountId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SeatPoolEligibilityDto"}}}},"responses":{"200":{"description":""}},"tags":["admin"]}},"/api/admin/waitlist":{"get":{"operationId":"AdminWaitlistController_leads","parameters":[],"responses":{"200":{"description":""}},"tags":["admin"]}},"/api/admin/waitlist/{id}/notify":{"post":{"operationId":"AdminWaitlistController_notify","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaitlistNotifyDto"}}}},"responses":{"200":{"description":""}},"tags":["admin"]}},"/api/admin/waitlist/{id}/decline":{"post":{"operationId":"AdminWaitlistController_decline","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["admin"]},"delete":{"operationId":"AdminWaitlistController_restore","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["admin"]}},"/api/insights/performance":{"get":{"operationId":"InsightsController_performance","parameters":[{"name":"from","required":true,"in":"query","schema":{"pattern":"^\\d{4}-\\d{2}-\\d{2}$","type":"string"}},{"name":"to","required":true,"in":"query","schema":{"pattern":"^\\d{4}-\\d{2}-\\d{2}$","type":"string"}},{"name":"userId","required":false,"in":"query","schema":{"minLength":1,"type":"string"}}],"responses":{"200":{"description":""}},"tags":["insights"]}},"/api/insights/users":{"get":{"operationId":"InsightsController_users","parameters":[],"responses":{"200":{"description":""}},"tags":["insights"]}},"/api/connections":{"post":{"operationId":"ConnectionsController_connect","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectLinkedinDto"}}}},"responses":{"201":{"description":""}},"tags":["connections"]},"get":{"operationId":"ConnectionsController_current","parameters":[],"responses":{"200":{"description":""}},"tags":["connections"]}},"/api/connections/linkedin/cookie":{"post":{"operationId":"ConnectionsController_connectWithCookie","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectLinkedinCookieDto"}}}},"responses":{"200":{"description":""}},"tags":["connections"]}},"/api/connections/seats":{"get":{"operationId":"ConnectionsController_seats","parameters":[],"responses":{"200":{"description":""}},"tags":["connections"]}},"/api/connections/{id}/inmail-credits":{"get":{"operationId":"ConnectionsController_inmailCredits","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["connections"]}},"/api/connections/{id}":{"get":{"operationId":"ConnectionsController_getById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["connections"]},"delete":{"operationId":"ConnectionsController_disconnect","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["connections"]}},"/api/connections/{id}/checkpoint":{"post":{"operationId":"ConnectionsController_solveCheckpoint","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SolveCheckpointDto"}}}},"responses":{"201":{"description":""}},"tags":["connections"]}},"/api/connections/{id}/checkpoint/resend":{"post":{"operationId":"ConnectionsController_resendCheckpoint","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["connections"]}},"/api/connections/{id}/reconnect":{"post":{"operationId":"ConnectionsController_reconnect","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["connections"]}},"/api/channel-accounts/{id}/capture-scope":{"patch":{"operationId":"ChannelAccountsController_changeCaptureScope","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangeCaptureScopeDto"}}}},"responses":{"200":{"description":""}},"tags":["channel-accounts"]}},"/api/billing/checkout":{"post":{"operationId":"BillingController_checkout","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingCheckoutDto"}}}},"responses":{"201":{"description":""}},"tags":["billing"]}},"/api/billing/addons/cold-email":{"put":{"operationId":"BillingController_setColdEmail","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ColdEmailDto"}}}},"responses":{"200":{"description":""}},"tags":["billing"]}},"/api/billing/me":{"get":{"operationId":"BillingController_me","parameters":[],"responses":{"200":{"description":""}},"tags":["billing"]}},"/api/billing/portal":{"post":{"operationId":"BillingController_portal","parameters":[],"responses":{"200":{"description":""}},"tags":["billing"]}},"/api/billing/reconcile":{"post":{"operationId":"BillingController_reconcile","parameters":[],"responses":{"200":{"description":""}},"tags":["billing"]}},"/api/integrations/unipile-mailbox":{"get":{"operationId":"UnipileMailboxController_view","parameters":[],"responses":{"200":{"description":""}},"tags":["integrations"]},"delete":{"operationId":"UnipileMailboxController_disconnect","parameters":[],"responses":{"204":{"description":""}},"tags":["integrations"]}},"/api/integrations/unipile-mailbox/link":{"post":{"operationId":"UnipileMailboxController_link","parameters":[],"responses":{"200":{"description":""}},"tags":["integrations"]}},"/api/channel-actions/profile-fetch":{"post":{"operationId":"ChannelActionsController_profileFetch","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileFetchDto"}}}},"responses":{"200":{"description":""}},"tags":["channel-actions"]}},"/api/channel-actions/company-fetch":{"post":{"operationId":"ChannelActionsController_companyFetch","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyFetchDto"}}}},"responses":{"200":{"description":""}},"tags":["channel-actions"]}},"/api/channel-actions/profile-posts":{"post":{"operationId":"ChannelActionsController_profilePosts","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfilePostsDto"}}}},"responses":{"200":{"description":""}},"tags":["channel-actions"]}},"/api/channel-actions/profile-comments":{"post":{"operationId":"ChannelActionsController_profileComments","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileCommentsDto"}}}},"responses":{"200":{"description":""}},"tags":["channel-actions"]}},"/api/channel-actions/profile-reactions":{"post":{"operationId":"ChannelActionsController_profileReactions","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileReactionsDto"}}}},"responses":{"200":{"description":""}},"tags":["channel-actions"]}},"/api/channel-actions/search-posts":{"post":{"operationId":"ChannelActionsController_searchPosts","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchPostsDto"}}}},"responses":{"200":{"description":""}},"tags":["channel-actions"]}},"/api/channel-actions/post-reactions":{"post":{"operationId":"ChannelActionsController_postReactions","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostReactionsDto"}}}},"responses":{"200":{"description":""}},"tags":["channel-actions"]}},"/api/channel-actions/event-attendees":{"post":{"operationId":"ChannelActionsController_eventAttendees","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventAttendeesDto"}}}},"responses":{"200":{"description":""}},"tags":["channel-actions"]}},"/api/channel-actions/newsletter-subscribers":{"post":{"operationId":"ChannelActionsController_newsletterSubscribers","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewsletterSubscribersDto"}}}},"responses":{"200":{"description":""}},"tags":["channel-actions"]}},"/api/channel-actions/group-members":{"post":{"operationId":"ChannelActionsController_groupMembers","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GroupMembersDto"}}}},"responses":{"200":{"description":""}},"tags":["channel-actions"]}},"/api/channel-actions/filter-resolve":{"post":{"operationId":"ChannelActionsController_filterResolve","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FilterResolveDto"}}}},"responses":{"200":{"description":""}},"tags":["channel-actions"]}},"/api/channel-actions/filter-suggest":{"post":{"operationId":"ChannelActionsController_filterSuggest","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FilterSuggestDto"}}}},"responses":{"200":{"description":""}},"tags":["channel-actions"]}},"/api/channel-actions/people-suggest":{"post":{"operationId":"ChannelActionsController_peopleSuggest","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeopleSuggestDto"}}}},"responses":{"200":{"description":""}},"tags":["channel-actions"]}},"/api/channel-actions/search-sales-navigator":{"post":{"operationId":"ChannelActionsController_searchSalesNavigator","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchSalesNavigatorDto"}}}},"responses":{"200":{"description":""}},"tags":["channel-actions"]}},"/api/channel-actions/invite-send":{"post":{"operationId":"ChannelActionsController_inviteSend","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteSendDto"}}}},"responses":{"200":{"description":""}},"tags":["channel-actions"]}},"/api/channel-actions/message-send":{"post":{"operationId":"ChannelActionsController_messageSend","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageSendDto"}}}},"responses":{"200":{"description":""}},"tags":["channel-actions"]}},"/api/channel-actions/message-edit":{"post":{"operationId":"ChannelActionsController_messageEdit","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageEditDto"}}}},"responses":{"200":{"description":""}},"tags":["channel-actions"]}},"/api/channel-actions/message-delete":{"post":{"operationId":"ChannelActionsController_messageDelete","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageDeleteDto"}}}},"responses":{"200":{"description":""}},"tags":["channel-actions"]}},"/api/channel-actions/inmail-send":{"post":{"operationId":"ChannelActionsController_inmailSend","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InmailSendDto"}}}},"responses":{"200":{"description":""}},"tags":["channel-actions"]}},"/api/channel-actions/usage":{"get":{"operationId":"ChannelActionsController_usage","parameters":[],"responses":{"200":{"description":""}},"tags":["channel-actions"]}},"/api/channel-actions/usage/week":{"get":{"operationId":"ChannelActionsController_weeklyUsage","parameters":[],"responses":{"200":{"description":""}},"tags":["channel-actions"]}},"/api/channel-actions/limits":{"patch":{"operationId":"ChannelActionsController_setLimit","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetChannelActionLimitDto"}}}},"responses":{"200":{"description":""}},"tags":["channel-actions"]}},"/api/channel-actions/headroom":{"get":{"operationId":"ChannelActionsController_headroom","parameters":[{"name":"type","required":true,"in":"query","schema":{"type":"string","enum":["profile.fetch","company.fetch","profile.posts","profile.comments","profile.reactions","company.posts","search.people","search.companies","search.sales_navigator","search.recruiter","recruiter.saved_searches","search.posts","search.jobs","relations.list","post.fetch","post.reactions","post.comments","event.attendees","profile.viewers","newsletter.subscribers","group.members","invitations.received","company.followers","filter.resolve","invite.send","invite.cancel","message.send","message.edit","message.delete","inmail.send","post.react","post.comment","profile.view","profile.follow","relation.remove","profile.edit"]}},{"name":"continuation","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["true","false"]}]}}],"responses":{"200":{"description":""}},"tags":["channel-actions"]}},"/api/channel-actions/log":{"get":{"operationId":"ChannelActionsController_log","parameters":[{"name":"type","required":false,"in":"query","schema":{"type":"string","enum":["profile.fetch","company.fetch","profile.posts","profile.comments","profile.reactions","company.posts","search.people","search.companies","search.sales_navigator","search.recruiter","recruiter.saved_searches","search.posts","search.jobs","relations.list","post.fetch","post.reactions","post.comments","event.attendees","profile.viewers","newsletter.subscribers","group.members","invitations.received","company.followers","filter.resolve","invite.send","invite.cancel","message.send","message.edit","message.delete","inmail.send","post.react","post.comment","profile.view","profile.follow","relation.remove","profile.edit"]}},{"name":"status","required":false,"in":"query","schema":{"type":"string","enum":["ok","failed","limited"]}},{"name":"after","required":false,"in":"query","schema":{"format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$","type":"string"}},{"name":"cursor","required":false,"in":"query","schema":{"minLength":1,"maxLength":512,"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"type":"integer"}}],"responses":{"200":{"description":""}},"tags":["channel-actions"]}},"/api/usage/allowance":{"get":{"operationId":"UsageController_allowance","parameters":[],"responses":{"200":{"description":""}},"tags":["usage"]}},"/api/usage/breakdown":{"get":{"operationId":"UsageController_breakdown","parameters":[],"responses":{"200":{"description":""}},"tags":["usage"]}},"/api/usage/timeseries":{"get":{"operationId":"UsageController_timeseries","parameters":[{"name":"tz","required":true,"in":"query","schema":{"type":"string"}},{"name":"feature","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["usage"]}},"/api/usage/events":{"get":{"operationId":"UsageController_events","parameters":[{"name":"feature","required":true,"in":"query","schema":{"type":"string"}},{"name":"cursor","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["usage"]}},"/api/campaigns/{id}/qualification-runs":{"post":{"operationId":"CampaignsController_startQualification","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["campaigns"]},"get":{"operationId":"CampaignsController_qualificationRuns","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns":{"post":{"operationId":"CampaignsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignCreateDto"}}}},"responses":{"201":{"description":""}},"tags":["campaigns"]},"get":{"operationId":"CampaignsController_list","parameters":[{"name":"q","required":false,"in":"query","description":"Case-insensitive substring of the campaign's name.","x-nestjs_zod-uses-3-point-1-syntax":true,"schema":{"minLength":1,"maxLength":200,"type":"string"}},{"name":"status","required":false,"in":"query","description":"Return only campaigns in these statuses — one, or several as a comma-separated list (e.g. `draft,active,paused`). Omit for every status, including the finished and archived ones the app hides by default.","x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"initiative","required":false,"in":"query","description":"Return only campaigns serving this initiative. The literal `none` returns the campaigns serving no initiative yet — the candidates an initiative can attach (PRD-79 IN8), since a campaign serves at most one.","x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"string","const":"none"}]}},{"name":"cursor","required":false,"in":"query","description":"Opaque keyset token from the previous page's `nextCursor`. Omit for the first page.","x-nestjs_zod-uses-3-point-1-syntax":true,"schema":{"maxLength":4096,"type":"string"}},{"name":"limit","required":false,"in":"query","x-nestjs_zod-uses-3-point-1-syntax":true,"schema":{"minimum":1,"maximum":100,"default":25,"type":"integer"}},{"name":"sort","required":false,"in":"query","description":"Order the page by this column instead of the default one. The default puts the campaigns that are running first — active, then draft, then paused, then finished, then archived — and the most recent first inside each of those.","x-nestjs_zod-uses-3-point-1-syntax":true,"schema":{"type":"string","enum":["name","status","sender","updated"]}},{"name":"direction","required":false,"in":"query","description":"Which way `sort` runs. Omit it to get the column read the way the app reads it: names and senders A→Z, statuses running-first, dates newest-first.","x-nestjs_zod-uses-3-point-1-syntax":true,"schema":{"type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/audience-leads":{"post":{"operationId":"CampaignsController_audienceLeadsForLists","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignAudienceLeadsDto"}}}},"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/preview-draft":{"post":{"operationId":"CampaignsController_previewDraft","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignPreviewDraftDto"}}}},"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}":{"get":{"operationId":"CampaignsController_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["campaigns"]},"patch":{"operationId":"CampaignsController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignUpdateDto"}}}},"responses":{"200":{"description":""}},"tags":["campaigns"]},"delete":{"operationId":"CampaignsController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/initiative":{"put":{"operationId":"CampaignsController_setInitiative","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignInitiativeSetDto"}}}},"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/lists":{"get":{"operationId":"CampaignsController_boundLists","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["campaigns"]},"post":{"operationId":"CampaignsController_bindList","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignBindListDto"}}}},"responses":{"201":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/lists/{leadListId}":{"delete":{"operationId":"CampaignsController_unbindList","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"leadListId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/runs":{"get":{"operationId":"CampaignsController_runs","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"bucket","required":false,"in":"query","description":"Filter to one activity bucket: `waiting`, `didnt_accept`, `didnt_answer`, `replied`, `interested` (a subset of `replied`), `skipped` (an ICP / enrollment-filter verdict or an operator stop), or `error`. Omit for every run.","schema":{"type":"string","enum":["waiting","didnt_accept","didnt_answer","replied","skipped","error","interested"]}},{"name":"stage","required":false,"in":"query","description":"Activity states to include; several read as \"any of these\".","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"nodeKey","required":false,"in":"query","description":"Only runs that reached this step, by the node `key` the graph gave it — including runs that have since moved past it or finished. Pair it with `dateFrom`/`dateTo` to ask who completed THIS step on those days, which is the only way to tell a first message apart from a follow-up in a sequence with more than one message step.","schema":{"minLength":1,"maxLength":200,"type":"string"}},{"name":"q","required":false,"in":"query","description":"Find a person by name, headline, company or LinkedIn handle.","schema":{"minLength":1,"maxLength":200,"type":"string"}},{"name":"dateFrom","required":false,"in":"query","description":"Earliest day to include, inclusive (YYYY-MM-DD). Dates each run by its LAST event — unless `nodeKey` is also set, which dates it by that step instead.","schema":{"pattern":"^\\d{4}-\\d{2}-\\d{2}$","type":"string"}},{"name":"dateTo","required":false,"in":"query","description":"Latest day to include, inclusive (YYYY-MM-DD). Dates each run by its LAST event — unless `nodeKey` is also set, which dates it by that step instead.","schema":{"pattern":"^\\d{4}-\\d{2}-\\d{2}$","type":"string"}},{"name":"listId","required":false,"in":"query","description":"Only people enrolled from these source lists.","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"qualificationStatus","required":false,"in":"query","description":"Only people with these ICP verdicts; several read as \"any of these\".","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"funnel","required":false,"in":"query","description":"Only the people one Performance funnel card counts: `invite_sent`, `invite_accepted`, `message_sent`, `replied` or `interested`.","schema":{"type":"string","enum":["invite_sent","invite_accepted","message_sent","replied","interested"]}},{"name":"cursor","required":false,"in":"query","schema":{"maxLength":65536,"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":50,"type":"integer"}}],"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/runs/count":{"get":{"operationId":"CampaignsController_countRuns","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"bucket","required":false,"in":"query","description":"Filter to one activity bucket: `waiting`, `didnt_accept`, `didnt_answer`, `replied`, `interested` (a subset of `replied`), `skipped` (an ICP / enrollment-filter verdict or an operator stop), or `error`. Omit for every run.","schema":{"type":"string","enum":["waiting","didnt_accept","didnt_answer","replied","skipped","error","interested"]}},{"name":"stage","required":false,"in":"query","description":"Activity states to include; several read as \"any of these\".","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"nodeKey","required":false,"in":"query","description":"Only runs that reached this step, by the node `key` the graph gave it — including runs that have since moved past it or finished. Pair it with `dateFrom`/`dateTo` to ask who completed THIS step on those days, which is the only way to tell a first message apart from a follow-up in a sequence with more than one message step.","schema":{"minLength":1,"maxLength":200,"type":"string"}},{"name":"q","required":false,"in":"query","description":"Find a person by name, headline, company or LinkedIn handle.","schema":{"minLength":1,"maxLength":200,"type":"string"}},{"name":"dateFrom","required":false,"in":"query","description":"Earliest day to include, inclusive (YYYY-MM-DD). Dates each run by its LAST event — unless `nodeKey` is also set, which dates it by that step instead.","schema":{"pattern":"^\\d{4}-\\d{2}-\\d{2}$","type":"string"}},{"name":"dateTo","required":false,"in":"query","description":"Latest day to include, inclusive (YYYY-MM-DD). Dates each run by its LAST event — unless `nodeKey` is also set, which dates it by that step instead.","schema":{"pattern":"^\\d{4}-\\d{2}-\\d{2}$","type":"string"}},{"name":"listId","required":false,"in":"query","description":"Only people enrolled from these source lists.","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"qualificationStatus","required":false,"in":"query","description":"Only people with these ICP verdicts; several read as \"any of these\".","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"funnel","required":false,"in":"query","description":"Only the people one Performance funnel card counts: `invite_sent`, `invite_accepted`, `message_sent`, `replied` or `interested`.","schema":{"type":"string","enum":["invite_sent","invite_accepted","message_sent","replied","interested"]}}],"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/activity-counts":{"get":{"operationId":"CampaignsController_activityCounts","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/node-stats":{"get":{"operationId":"CampaignsController_nodeStats","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/performance":{"get":{"operationId":"CampaignsController_performance","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"range","required":false,"in":"query","schema":{"default":"30d","type":"string","enum":["7d","30d"]}},{"name":"ahead","required":false,"in":"query","description":"Days of scheduled sends to include after today. 0 = history only.","schema":{"minimum":0,"maximum":30,"default":0,"type":"integer"}}],"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/check-accepts":{"post":{"operationId":"CampaignsController_checkAccepts","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/summary":{"get":{"operationId":"CampaignsController_summary","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/queued":{"get":{"operationId":"CampaignsController_queued","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/audience-leads":{"get":{"operationId":"CampaignsController_audienceLeads","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"q","required":false,"in":"query","schema":{"minLength":1,"maxLength":200,"type":"string"}},{"name":"cursor","required":false,"in":"query","schema":{"maxLength":65536,"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":25,"type":"integer"}}],"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/preview":{"post":{"operationId":"CampaignsController_previewMessage","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignPreviewDto"}}}},"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/rehearsal/opening":{"post":{"operationId":"CampaignsController_rehearsalOpening","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignRehearsalOpeningDto"}}}},"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/rehearsal/turn":{"post":{"operationId":"CampaignsController_rehearsalTurn","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignRehearsalTurnDto"}}}},"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/version":{"get":{"operationId":"CampaignsController_version","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/version/published":{"get":{"operationId":"CampaignsController_publishedVersion","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/versions":{"get":{"operationId":"CampaignsController_versions","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/versions/{versionNumber}":{"get":{"operationId":"CampaignsController_versionByNumber","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"versionNumber","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/versions/{versionNumber}/restore":{"post":{"operationId":"CampaignsController_restoreVersion","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"versionNumber","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/migration-preview":{"get":{"operationId":"CampaignsController_migrationPreview","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/draft":{"put":{"operationId":"CampaignsController_saveDraft","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignDraftDto"}}}},"responses":{"200":{"description":""}},"tags":["campaigns"]},"delete":{"operationId":"CampaignsController_discardDraft","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/attachments":{"post":{"operationId":"CampaignsController_uploadAttachment","parameters":[],"responses":{"201":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/publish":{"post":{"operationId":"CampaignsController_publish","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignPublishDto"}}}},"responses":{"201":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/activate":{"post":{"operationId":"CampaignsController_activate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignActivateDto"}}}},"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/pause":{"post":{"operationId":"CampaignsController_pause","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/resume":{"post":{"operationId":"CampaignsController_resume","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignActivateDto"}}}},"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/leads/{leadId}/start":{"post":{"operationId":"CampaignsController_startLeadNow","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"leadId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/runs/{runId}/send-now":{"post":{"operationId":"CampaignsController_sendNow","parameters":[{"name":"runId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/runs/{runId}/skip-wait":{"post":{"operationId":"CampaignsController_skipWait","parameters":[{"name":"runId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/runs/{runId}/skip-step":{"post":{"operationId":"CampaignsController_skipStep","parameters":[{"name":"runId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/split-review":{"get":{"operationId":"CampaignsController_splitReview","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"nodeKey","required":true,"in":"query","description":"The audience_split node to review, by the stable `key` the graph gave it.","schema":{"minLength":1,"maxLength":80,"type":"string"}}],"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/split-review/apply":{"post":{"operationId":"CampaignsController_applySplitReviewWinner","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"nodeKey","required":true,"in":"query","description":"The audience_split node to review, by the stable `key` the graph gave it.","schema":{"minLength":1,"maxLength":80,"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SplitReviewApplyDto"}}}},"responses":{"201":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/seats":{"post":{"operationId":"CampaignSeatsController_add","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignSeatAddDto"}}}},"responses":{"201":{"description":""}},"tags":["campaigns"]}},"/api/campaigns/{id}/seats/{channelAccountId}":{"patch":{"operationId":"CampaignSeatsController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"channelAccountId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignSeatUpdateDto"}}}},"responses":{"200":{"description":""}},"tags":["campaigns"]},"delete":{"operationId":"CampaignSeatsController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"channelAccountId","required":true,"in":"path","schema":{"type":"string"}},{"name":"leads","required":true,"in":"query","description":"What happens to the leads this sender is mid-sequence with. `finish`: they keep getting their follow-ups from this sender until their sequence ends. `stop`: their runs are canceled now and nothing more is sent to them from this campaign. Either way, its leads with nothing sent yet go back to the pool for the other senders. There is no default — ask the operator.","schema":{"type":"string","enum":["finish","stop"]}}],"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/leads/{leadId}/campaigns":{"get":{"operationId":"LeadCampaignsController_campaignsForLead","parameters":[{"name":"leadId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/list-campaigns":{"get":{"operationId":"ListCampaignsController_campaignsByList","parameters":[],"responses":{"200":{"description":""}},"tags":["campaigns"]}},"/api/leads/import":{"post":{"operationId":"LeadsController_import","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadImportDto"}}}},"responses":{"201":{"description":""}},"tags":["leads"]}},"/api/leads/{id}/load-profile":{"post":{"operationId":"LeadsController_resolve","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["leads"]}},"/api/leads":{"get":{"operationId":"LeadsController_list","parameters":[{"name":"q","required":false,"in":"query","schema":{"minLength":1,"maxLength":200,"type":"string"}},{"name":"companyId","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"qualificationStatus","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"cursor","required":false,"in":"query","schema":{"maxLength":65536,"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":25,"type":"integer"}},{"name":"sort","required":false,"in":"query","schema":{"type":"string","enum":["person","title","company","qualification","owner","added"]}},{"name":"direction","required":false,"in":"query","schema":{"type":"string","enum":["asc","desc"]}},{"name":"ownerId","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"tagId","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"lastContacted","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["leads"]}},"/api/leads/{id}":{"get":{"operationId":"LeadsController_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["leads"]},"delete":{"operationId":"LeadsController_delete","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["leads"]}},"/api/leads/{id}/tags":{"put":{"operationId":"LeadsController_setTags","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadTagSetDto"}}}},"responses":{"200":{"description":""}},"tags":["leads"]}},"/api/leads/{id}/owner":{"put":{"operationId":"LeadsController_setOwner","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadOwnerSetDto"}}}},"responses":{"200":{"description":""}},"tags":["leads"]}},"/api/leads/{id}/email":{"put":{"operationId":"LeadsController_setEmail","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadEmailSetDto"}}}},"responses":{"200":{"description":""}},"tags":["leads"]}},"/api/leads/{id}/phone":{"put":{"operationId":"LeadsController_setPhone","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadPhoneSetDto"}}}},"responses":{"200":{"description":""}},"tags":["leads"]}},"/api/leads/{id}/qualification":{"put":{"operationId":"LeadsController_setManualQualification","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadManualQualificationDto"}}}},"responses":{"200":{"description":""}},"tags":["leads"]}},"/api/leads/qualification":{"post":{"operationId":"LeadsController_setManualQualificationBulk","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadManualQualificationBulkDto"}}}},"responses":{"200":{"description":""}},"tags":["leads"]}},"/api/companies/{id}/load-details":{"post":{"operationId":"CompaniesController_resolve","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["companies"]}},"/api/companies":{"get":{"operationId":"CompaniesController_list","parameters":[{"name":"qualificationStatus","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"query","required":false,"in":"query","schema":{"minLength":1,"type":"string"}},{"name":"sort","required":false,"in":"query","schema":{"type":"string","enum":["company","industry","qualification","owner","added"]}},{"name":"direction","required":false,"in":"query","schema":{"type":"string","enum":["asc","desc"]}},{"name":"ownerId","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"tagId","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"cursor","required":false,"in":"query","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":25,"type":"integer"}}],"responses":{"200":{"description":""}},"tags":["companies"]}},"/api/companies/{id}/tags":{"put":{"operationId":"CompaniesController_setTags","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyTagSetDto"}}}},"responses":{"200":{"description":""}},"tags":["companies"]}},"/api/companies/{id}/owner":{"put":{"operationId":"CompaniesController_setOwner","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyOwnerSetDto"}}}},"responses":{"200":{"description":""}},"tags":["companies"]}},"/api/companies/{id}/qualification":{"put":{"operationId":"CompaniesController_setManualQualification","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyManualQualificationDto"}}}},"responses":{"200":{"description":""}},"tags":["companies"]}},"/api/companies/{id}":{"get":{"operationId":"CompaniesController_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["companies"]}},"/api/tags":{"get":{"operationId":"TagsController_list","parameters":[],"responses":{"200":{"description":""}},"tags":["tags"]},"post":{"operationId":"TagsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagCreateDto"}}}},"responses":{"201":{"description":""}},"tags":["tags"]}},"/api/tags/{id}":{"patch":{"operationId":"TagsController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagUpdateDto"}}}},"responses":{"200":{"description":""}},"tags":["tags"]},"delete":{"operationId":"TagsController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["tags"]}},"/api/tags/{id}/usage":{"get":{"operationId":"TagsController_usage","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["tags"]}},"/api/tags/{id}/subjects":{"post":{"operationId":"TagsController_bulk","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagBulkDto"}}}},"responses":{"201":{"description":""}},"tags":["tags"]}},"/api/owners":{"get":{"operationId":"OwnersController_list","parameters":[],"responses":{"200":{"description":""}},"tags":["owners"]}},"/api/owners/assign":{"post":{"operationId":"OwnersController_assign","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OwnerBulkDto"}}}},"responses":{"200":{"description":""}},"tags":["owners"]}},"/api/crm/summary":{"get":{"operationId":"CrmController_summary","parameters":[{"name":"q","required":false,"in":"query","schema":{"minLength":1,"maxLength":200,"type":"string"}},{"name":"companyId","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"qualificationStatus","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"ownerId","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"tagId","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"lastContacted","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["crm"]}},"/api/crm/cards":{"get":{"operationId":"CrmController_cards","parameters":[{"name":"q","required":false,"in":"query","schema":{"minLength":1,"maxLength":200,"type":"string"}},{"name":"companyId","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"qualificationStatus","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"ownerId","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"tagId","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"lastContacted","required":false,"in":"query","schema":{"type":"string"}},{"name":"stage","required":true,"in":"query","schema":{"type":"string","enum":["new","invite_sent","connected","contacted","replied","interested","meeting_booked","won","on_hold","lost","discarded"]}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":25,"type":"integer"}},{"name":"cursor","required":false,"in":"query","schema":{"maxLength":65536,"type":"string"}}],"responses":{"200":{"description":""}},"tags":["crm"]}},"/api/crm/leads/{id}/stage":{"put":{"operationId":"CrmController_setStage","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmStageDto"}}}},"responses":{"200":{"description":""}},"tags":["crm"]}},"/api/crm/leads/stage":{"post":{"operationId":"CrmController_setStageMany","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmStageBulkDto"}}}},"responses":{"200":{"description":""}},"tags":["crm"]}},"/api/crm/companies":{"get":{"operationId":"CrmController_companies","parameters":[{"name":"q","required":false,"in":"query","schema":{"minLength":1,"maxLength":200,"type":"string"}},{"name":"companyId","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"qualificationStatus","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"ownerId","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"tagId","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"lastContacted","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["crm"]}},"/api/exclusion/people":{"get":{"operationId":"ExclusionController_listPeople","parameters":[],"responses":{"200":{"description":""}},"tags":["exclusion"]},"post":{"operationId":"ExclusionController_addPeople","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExclusionPeopleAddDto"}}}},"responses":{"201":{"description":""}},"tags":["exclusion"]}},"/api/exclusion/people/{id}":{"delete":{"operationId":"ExclusionController_removePerson","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["exclusion"]}},"/api/exclusion/companies":{"get":{"operationId":"ExclusionController_listCompanies","parameters":[],"responses":{"200":{"description":""}},"tags":["exclusion"]},"post":{"operationId":"ExclusionController_addCompanies","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExclusionCompaniesAddDto"}}}},"responses":{"201":{"description":""}},"tags":["exclusion"]}},"/api/exclusion/companies/{id}":{"patch":{"operationId":"ExclusionController_updateCompany","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExclusionCompanyUpdateDto"}}}},"responses":{"200":{"description":""}},"tags":["exclusion"]},"delete":{"operationId":"ExclusionController_removeCompany","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["exclusion"]}},"/api/webhook-endpoints":{"get":{"operationId":"WebhooksController_list","parameters":[],"responses":{"200":{"description":""}},"tags":["webhooks"]},"post":{"operationId":"WebhooksController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointCreateDto"}}}},"responses":{"201":{"description":""}},"tags":["webhooks"]}},"/api/webhook-endpoints/{id}":{"get":{"operationId":"WebhooksController_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["webhooks"]},"patch":{"operationId":"WebhooksController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointUpdateDto"}}}},"responses":{"200":{"description":""}},"tags":["webhooks"]},"delete":{"operationId":"WebhooksController_delete","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["webhooks"]}},"/api/webhook-endpoints/{id}/secret":{"post":{"operationId":"WebhooksController_regenerateSecret","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["webhooks"]}},"/api/webhook-endpoints/{id}/test":{"post":{"operationId":"WebhooksController_sendTest","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["webhooks"]}},"/api/webhook-endpoints/{id}/deliveries":{"get":{"operationId":"WebhooksController_deliveries","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["webhooks"]}},"/api/webhook-deliveries/{id}":{"get":{"operationId":"WebhookDeliveriesController_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["webhooks"]}},"/api/webhook-deliveries/{id}/replay":{"post":{"operationId":"WebhookDeliveriesController_replay","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["webhooks"]}},"/api/integrations/crm":{"get":{"operationId":"CrmSyncController_get","parameters":[],"responses":{"200":{"description":""}},"tags":["crm"]},"delete":{"operationId":"CrmSyncController_disconnect","parameters":[],"responses":{"204":{"description":""}},"tags":["crm"]}},"/api/integrations/crm/{provider}/connect":{"post":{"operationId":"CrmSyncController_connect","parameters":[{"name":"provider","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["crm"]}},"/api/integrations/crm/{provider}/callback":{"post":{"operationId":"CrmSyncController_callback","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmCallbackDto"}}}},"responses":{"200":{"description":""}},"tags":["crm"]}},"/api/integrations/crm/fields":{"get":{"operationId":"CrmSyncController_fields","parameters":[],"responses":{"200":{"description":""}},"tags":["crm"]}},"/api/integrations/crm/settings":{"put":{"operationId":"CrmSyncController_saveSettings","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmSettingsDto"}}}},"responses":{"200":{"description":""}},"tags":["crm"]}},"/api/integrations/crm/push":{"post":{"operationId":"CrmSyncController_push","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrmPushDto"}}}},"responses":{"200":{"description":""}},"tags":["crm"]}},"/api/integrations/crm/syncs":{"get":{"operationId":"CrmSyncController_syncs","parameters":[],"responses":{"200":{"description":""}},"tags":["crm"]}},"/api/integrations/crm/leads/{leadId}":{"get":{"operationId":"CrmSyncController_leadStatus","parameters":[{"name":"leadId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["crm"]}},"/api/settings/value-proposition":{"get":{"operationId":"SettingsController_getValueProposition","parameters":[],"responses":{"200":{"description":""}},"tags":["settings"]},"put":{"operationId":"SettingsController_setValueProposition","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValuePropositionInputDto"}}}},"responses":{"200":{"description":""}},"tags":["settings"]}},"/api/settings/lead-magnet":{"get":{"operationId":"SettingsController_getLeadMagnet","parameters":[],"responses":{"200":{"description":""}},"tags":["settings"]},"put":{"operationId":"SettingsController_setLeadMagnet","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadMagnetInputDto"}}}},"responses":{"200":{"description":""}},"tags":["settings"]}},"/api/settings/learnings":{"get":{"operationId":"SettingsController_getLearnings","parameters":[],"responses":{"200":{"description":""}},"tags":["settings"]},"put":{"operationId":"SettingsController_setLearnings","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LearningsInputDto"}}}},"responses":{"200":{"description":""}},"tags":["settings"]}},"/api/settings/setup":{"get":{"operationId":"SettingsController_getSetup","parameters":[],"responses":{"200":{"description":""}},"tags":["settings"]},"put":{"operationId":"SettingsController_completeSetup","parameters":[],"responses":{"200":{"description":""}},"tags":["settings"]}},"/api/settings/timezone":{"put":{"operationId":"SettingsController_setTimezone","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserTimezoneInputDto"}}}},"responses":{"200":{"description":""}},"tags":["settings"]}},"/api/settings/locale":{"put":{"operationId":"SettingsController_setLocale","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserLocaleInputDto"}}}},"responses":{"200":{"description":""}},"tags":["settings"]}},"/api/settings/whatsapp":{"put":{"operationId":"SettingsController_setWhatsappNumber","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhatsappNumberInputDto"}}}},"responses":{"200":{"description":""}},"tags":["settings"]}},"/api/settings/default-language":{"put":{"operationId":"SettingsController_setDefaultLanguage","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DefaultLanguageInputDto"}}}},"responses":{"200":{"description":""}},"tags":["settings"]}},"/api/writing-checks":{"get":{"operationId":"WritingChecksController_get","parameters":[],"responses":{"200":{"description":""}},"tags":["writing-checks"]}},"/api/writing-checks/style/comment":{"get":{"operationId":"WritingChecksController_getCommentStyle","parameters":[],"responses":{"200":{"description":""}},"tags":["writing-checks"]},"put":{"operationId":"WritingChecksController_setCommentStyle","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WritingStyleInputDto"}}}},"responses":{"200":{"description":""}},"tags":["writing-checks"]}},"/api/writing-checks/{section}":{"put":{"operationId":"WritingChecksController_setSection","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WritingChecksInputDto"}}}},"responses":{"200":{"description":""}},"tags":["writing-checks"]}},"/api/writing-checks/shared/{key}":{"put":{"operationId":"WritingChecksController_setShared","parameters":[{"name":"key","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SharedWritingCheckInputDto"}}}},"responses":{"200":{"description":""}},"tags":["writing-checks"]}},"/api/lists/leads/qualify":{"post":{"operationId":"QualifyController_qualifyLead","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QualifyLeadDto"}}}},"responses":{"201":{"description":""}},"tags":["lists"]}},"/api/lists/companies/qualify":{"post":{"operationId":"QualifyController_qualifyCompany","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QualifyCompanyDto"}}}},"responses":{"201":{"description":""}},"tags":["lists"]}},"/api/lists/leads/qualify-draft":{"post":{"operationId":"QualifyController_qualifyLeadDraft","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QualifyLeadDraftDto"}}}},"responses":{"201":{"description":""}},"tags":["lists"]}},"/api/lists/companies/qualify-draft":{"post":{"operationId":"QualifyController_qualifyCompanyDraft","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QualifyCompanyDraftDto"}}}},"responses":{"201":{"description":""}},"tags":["lists"]}},"/api/lead-lists/{listId}/qualification-runs":{"post":{"operationId":"LeadQualificationRunsController_create","parameters":[{"name":"listId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QualificationRunCreateDto"}}}},"responses":{"201":{"description":""}},"tags":["lead-lists"]},"get":{"operationId":"LeadQualificationRunsController_recent","parameters":[{"name":"listId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["lead-lists"]}},"/api/lead-lists/{listId}/qualification-runs/latest":{"get":{"operationId":"LeadQualificationRunsController_newest","parameters":[{"name":"listId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["lead-lists"]}},"/api/lead-lists/{listId}/qualification-runs/{runId}/items":{"get":{"operationId":"LeadQualificationRunsController_items","parameters":[{"name":"listId","required":true,"in":"path","schema":{"type":"string"}},{"name":"runId","required":true,"in":"path","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","x-nestjs_zod-uses-3-point-1-syntax":true,"schema":{"maximum":200,"exclusiveMinimum":0,"default":50,"type":"integer"}},{"name":"offset","required":false,"in":"query","x-nestjs_zod-uses-3-point-1-syntax":true,"schema":{"minimum":0,"maximum":9007199254740991,"default":0,"type":"integer"}}],"responses":{"200":{"description":""}},"tags":["lead-lists"]}},"/api/lead-lists/{listId}/qualification-runs/{runId}/breakdown":{"get":{"operationId":"LeadQualificationRunsController_breakdown","parameters":[{"name":"listId","required":true,"in":"path","schema":{"type":"string"}},{"name":"runId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["lead-lists"]}},"/api/lead-lists/{listId}/qualification-runs/{runId}":{"get":{"operationId":"LeadQualificationRunsController_get","parameters":[{"name":"listId","required":true,"in":"path","schema":{"type":"string"}},{"name":"runId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["lead-lists"]}},"/api/lead-lists/{listId}/qualification-runs/{runId}/rerun":{"post":{"operationId":"LeadQualificationRunsController_rerun","parameters":[{"name":"listId","required":true,"in":"path","schema":{"type":"string"}},{"name":"runId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QualificationRunRerunDto"}}}},"responses":{"200":{"description":""}},"tags":["lead-lists"]}},"/api/lead-lists/{listId}/qualification-runs/{runId}/cancel":{"post":{"operationId":"LeadQualificationRunsController_cancel","parameters":[{"name":"listId","required":true,"in":"path","schema":{"type":"string"}},{"name":"runId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["lead-lists"]}},"/api/company-lists/{listId}/qualification-runs":{"post":{"operationId":"CompanyQualificationRunsController_create","parameters":[{"name":"listId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QualificationRunCreateDto"}}}},"responses":{"201":{"description":""}},"tags":["company-lists"]},"get":{"operationId":"CompanyQualificationRunsController_recent","parameters":[{"name":"listId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["company-lists"]}},"/api/company-lists/{listId}/qualification-runs/latest":{"get":{"operationId":"CompanyQualificationRunsController_newest","parameters":[{"name":"listId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["company-lists"]}},"/api/company-lists/{listId}/qualification-runs/{runId}/items":{"get":{"operationId":"CompanyQualificationRunsController_items","parameters":[{"name":"listId","required":true,"in":"path","schema":{"type":"string"}},{"name":"runId","required":true,"in":"path","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","x-nestjs_zod-uses-3-point-1-syntax":true,"schema":{"maximum":200,"exclusiveMinimum":0,"default":50,"type":"integer"}},{"name":"offset","required":false,"in":"query","x-nestjs_zod-uses-3-point-1-syntax":true,"schema":{"minimum":0,"maximum":9007199254740991,"default":0,"type":"integer"}}],"responses":{"200":{"description":""}},"tags":["company-lists"]}},"/api/company-lists/{listId}/qualification-runs/{runId}/breakdown":{"get":{"operationId":"CompanyQualificationRunsController_breakdown","parameters":[{"name":"listId","required":true,"in":"path","schema":{"type":"string"}},{"name":"runId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["company-lists"]}},"/api/company-lists/{listId}/qualification-runs/{runId}":{"get":{"operationId":"CompanyQualificationRunsController_get","parameters":[{"name":"listId","required":true,"in":"path","schema":{"type":"string"}},{"name":"runId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["company-lists"]}},"/api/company-lists/{listId}/qualification-runs/{runId}/rerun":{"post":{"operationId":"CompanyQualificationRunsController_rerun","parameters":[{"name":"listId","required":true,"in":"path","schema":{"type":"string"}},{"name":"runId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QualificationRunRerunDto"}}}},"responses":{"200":{"description":""}},"tags":["company-lists"]}},"/api/company-lists/{listId}/qualification-runs/{runId}/cancel":{"post":{"operationId":"CompanyQualificationRunsController_cancel","parameters":[{"name":"listId","required":true,"in":"path","schema":{"type":"string"}},{"name":"runId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["company-lists"]}},"/api/lead-lists/audience/preview":{"post":{"operationId":"LeadListsController_previewAudience","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AudiencePreviewDto"}}}},"responses":{"200":{"description":""}},"tags":["lead-lists"]}},"/api/lead-lists":{"post":{"operationId":"LeadListsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadListCreateDto"}}}},"responses":{"201":{"description":""}},"tags":["lead-lists"]},"get":{"operationId":"LeadListsController_list","parameters":[{"name":"q","required":false,"in":"query","schema":{"minLength":1,"maxLength":200,"type":"string"}},{"name":"cursor","required":false,"in":"query","schema":{"maxLength":65536,"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":25,"type":"integer"}},{"name":"status","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}}],"responses":{"200":{"description":""}},"tags":["lead-lists"]}},"/api/lead-lists/{id}":{"get":{"operationId":"LeadListsController_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["lead-lists"]},"patch":{"operationId":"LeadListsController_rename","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadListUpdateDto"}}}},"responses":{"200":{"description":""}},"tags":["lead-lists"]},"delete":{"operationId":"LeadListsController_delete","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["lead-lists"]}},"/api/lead-lists/{id}/archived":{"put":{"operationId":"LeadListsController_setArchived","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListArchiveDto"}}}},"responses":{"200":{"description":""}},"tags":["lead-lists"]}},"/api/lead-lists/{id}/columns":{"put":{"operationId":"LeadListsController_setColumns","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListColumnsDto"}}}},"responses":{"200":{"description":""}},"tags":["lead-lists"]}},"/api/lead-lists/{id}/members/{leadId}/values":{"put":{"operationId":"LeadListsController_setMemberValues","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"leadId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListColumnValuesDto"}}}},"responses":{"200":{"description":""}},"tags":["lead-lists"]}},"/api/lead-lists/{id}/summary":{"get":{"operationId":"LeadListsController_summary","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["lead-lists"]}},"/api/lead-lists/{id}/members":{"get":{"operationId":"LeadListsController_listMembers","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"cursor","required":false,"in":"query","schema":{"maxLength":65536,"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":25,"type":"integer"}},{"name":"q","required":false,"in":"query","schema":{"minLength":1,"maxLength":200,"type":"string"}},{"name":"sort","required":false,"in":"query","schema":{"type":"string","enum":["person","title","company","email","phone","qualification","owner","added","source"]}},{"name":"direction","required":false,"in":"query","schema":{"type":"string","enum":["asc","desc"]}},{"name":"qualificationStatus","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"ownerId","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"tagId","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"addedAfter","required":false,"in":"query","schema":{"format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","type":"string"}},{"name":"addedBefore","required":false,"in":"query","schema":{"format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","type":"string"}},{"name":"hydrated","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["true","false"]}]}},{"name":"column","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{}}]}},{"name":"signalKey","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"crmStage","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"emailState","required":false,"in":"query","schema":{"type":"string","enum":["has","missing","unasked"]}},{"name":"phoneState","required":false,"in":"query","schema":{"type":"string","enum":["has","missing","unasked"]}}],"responses":{"200":{"description":""}},"tags":["lead-lists"]},"post":{"operationId":"LeadListsController_addMembers","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadListAddMembersDto"}}}},"responses":{"201":{"description":""}},"tags":["lead-lists"]}},"/api/lead-lists/{id}/members/export":{"get":{"operationId":"LeadListsController_exportMembers","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"q","required":false,"in":"query","schema":{"minLength":1,"maxLength":200,"type":"string"}},{"name":"sort","required":false,"in":"query","schema":{"type":"string","enum":["person","title","company","email","phone","qualification","owner","added","source"]}},{"name":"direction","required":false,"in":"query","schema":{"type":"string","enum":["asc","desc"]}},{"name":"qualificationStatus","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"ownerId","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"tagId","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"addedAfter","required":false,"in":"query","schema":{"format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","type":"string"}},{"name":"addedBefore","required":false,"in":"query","schema":{"format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","type":"string"}},{"name":"hydrated","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["true","false"]}]}},{"name":"column","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{}}]}},{"name":"signalKey","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"crmStage","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"emailState","required":false,"in":"query","schema":{"type":"string","enum":["has","missing","unasked"]}},{"name":"phoneState","required":false,"in":"query","schema":{"type":"string","enum":["has","missing","unasked"]}}],"responses":{"200":{"description":""}},"tags":["lead-lists"]}},"/api/lead-lists/{id}/members/keys":{"get":{"operationId":"LeadListsController_memberKeys","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"q","required":false,"in":"query","schema":{"minLength":1,"maxLength":200,"type":"string"}},{"name":"qualificationStatus","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"ownerId","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"tagId","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"addedAfter","required":false,"in":"query","schema":{"format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","type":"string"}},{"name":"addedBefore","required":false,"in":"query","schema":{"format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","type":"string"}},{"name":"hydrated","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["true","false"]}]}},{"name":"column","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{}}]}},{"name":"signalKey","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"crmStage","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"emailState","required":false,"in":"query","schema":{"type":"string","enum":["has","missing","unasked"]}},{"name":"phoneState","required":false,"in":"query","schema":{"type":"string","enum":["has","missing","unasked"]}}],"responses":{"200":{"description":""}},"tags":["lead-lists"]}},"/api/lead-lists/{id}/members/by-keys":{"get":{"operationId":"LeadListsController_membersByKeys","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"keys","required":false,"in":"query","schema":{"maxItems":100,"type":"array","items":{"type":"string","minLength":1,"maxLength":2048}}}],"responses":{"200":{"description":""}},"tags":["lead-lists"]}},"/api/lead-lists/{id}/members/remove":{"post":{"operationId":"LeadListsController_removeMembersByKeys","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadListMemberKeysActionDto"}}}},"responses":{"200":{"description":""}},"tags":["lead-lists"]}},"/api/lead-lists/{id}/members/restore":{"post":{"operationId":"LeadListsController_restoreMembersByKeys","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadListMemberKeysActionDto"}}}},"responses":{"200":{"description":""}},"tags":["lead-lists"]}},"/api/lead-lists/{id}/load-profiles":{"post":{"operationId":"LeadListsController_loadProfiles","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadListLoadProfilesDto"}}}},"responses":{"200":{"description":""}},"tags":["lead-lists"]}},"/api/lead-lists/{id}/reconcile":{"put":{"operationId":"LeadListsController_reconcile","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadListReconcileDto"}}}},"responses":{"200":{"description":""}},"tags":["lead-lists"]}},"/api/lead-lists/{id}/members/{leadId}":{"delete":{"operationId":"LeadListsController_removeMember","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"leadId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["lead-lists"]}},"/api/leads/{leadId}/lead-lists":{"get":{"operationId":"LeadMembershipsController_listsForLead","parameters":[{"name":"leadId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["lead-lists"]}},"/api/company-lists":{"post":{"operationId":"CompanyListsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyListCreateDto"}}}},"responses":{"201":{"description":""}},"tags":["company-lists"]},"get":{"operationId":"CompanyListsController_list","parameters":[{"name":"q","required":false,"in":"query","schema":{"minLength":1,"maxLength":200,"type":"string"}},{"name":"cursor","required":false,"in":"query","schema":{"maxLength":65536,"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":25,"type":"integer"}},{"name":"status","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}}],"responses":{"200":{"description":""}},"tags":["company-lists"]}},"/api/company-lists/{id}/columns":{"put":{"operationId":"CompanyListsController_setColumns","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyListColumnsDto"}}}},"responses":{"200":{"description":""}},"tags":["company-lists"]}},"/api/company-lists/{id}/members/{companyId}/values":{"put":{"operationId":"CompanyListsController_setMemberValues","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"companyId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyListColumnValuesDto"}}}},"responses":{"200":{"description":""}},"tags":["company-lists"]}},"/api/company-lists/suggest":{"get":{"operationId":"CompanyListsController_suggest","parameters":[{"name":"q","required":false,"in":"query","schema":{"maxLength":200,"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"maximum":25,"default":8,"type":"integer"}}],"responses":{"200":{"description":""}},"tags":["company-lists"]}},"/api/company-lists/{id}":{"get":{"operationId":"CompanyListsController_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["company-lists"]},"patch":{"operationId":"CompanyListsController_rename","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyListUpdateDto"}}}},"responses":{"200":{"description":""}},"tags":["company-lists"]},"delete":{"operationId":"CompanyListsController_delete","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["company-lists"]}},"/api/company-lists/{id}/archived":{"put":{"operationId":"CompanyListsController_setArchived","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyListArchiveDto"}}}},"responses":{"200":{"description":""}},"tags":["company-lists"]}},"/api/company-lists/{id}/summary":{"get":{"operationId":"CompanyListsController_summary","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["company-lists"]}},"/api/company-lists/{id}/members":{"get":{"operationId":"CompanyListsController_listMembers","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"cursor","required":false,"in":"query","schema":{"maxLength":65536,"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":25,"type":"integer"}},{"name":"q","required":false,"in":"query","schema":{"minLength":1,"maxLength":200,"type":"string"}},{"name":"sort","required":false,"in":"query","schema":{"type":"string","enum":["company","industry","qualification","owner","added"]}},{"name":"direction","required":false,"in":"query","schema":{"type":"string","enum":["asc","desc"]}},{"name":"qualificationStatus","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"ownerId","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"tagId","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"addedAfter","required":false,"in":"query","schema":{"format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","type":"string"}},{"name":"addedBefore","required":false,"in":"query","schema":{"format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","type":"string"}},{"name":"hydrated","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["true","false"]}]}},{"name":"column","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{}}]}},{"name":"employeeMin","required":false,"in":"query","schema":{"minimum":0,"maximum":9007199254740991,"type":"integer"}},{"name":"employeeMax","required":false,"in":"query","schema":{"minimum":0,"maximum":9007199254740991,"type":"integer"}},{"name":"industry","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"hqCountry","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}}],"responses":{"200":{"description":""}},"tags":["company-lists"]},"post":{"operationId":"CompanyListsController_addMembers","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyListAddMembersDto"}}}},"responses":{"201":{"description":""}},"tags":["company-lists"]},"delete":{"operationId":"CompanyListsController_removeMembers","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyListRemoveMembersDto"}}}},"responses":{"200":{"description":""}},"tags":["company-lists"]}},"/api/company-lists/{id}/members/export":{"get":{"operationId":"CompanyListsController_exportMembers","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"q","required":false,"in":"query","schema":{"minLength":1,"maxLength":200,"type":"string"}},{"name":"sort","required":false,"in":"query","schema":{"type":"string","enum":["company","industry","qualification","owner","added"]}},{"name":"direction","required":false,"in":"query","schema":{"type":"string","enum":["asc","desc"]}},{"name":"qualificationStatus","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"ownerId","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"tagId","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"addedAfter","required":false,"in":"query","schema":{"format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","type":"string"}},{"name":"addedBefore","required":false,"in":"query","schema":{"format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","type":"string"}},{"name":"hydrated","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["true","false"]}]}},{"name":"column","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{}}]}},{"name":"employeeMin","required":false,"in":"query","schema":{"minimum":0,"maximum":9007199254740991,"type":"integer"}},{"name":"employeeMax","required":false,"in":"query","schema":{"minimum":0,"maximum":9007199254740991,"type":"integer"}},{"name":"industry","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"hqCountry","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}}],"responses":{"200":{"description":""}},"tags":["company-lists"]}},"/api/company-lists/{id}/members/keys":{"get":{"operationId":"CompanyListsController_memberKeys","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"q","required":false,"in":"query","schema":{"minLength":1,"maxLength":200,"type":"string"}},{"name":"qualificationStatus","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"ownerId","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"tagId","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"addedAfter","required":false,"in":"query","schema":{"format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","type":"string"}},{"name":"addedBefore","required":false,"in":"query","schema":{"format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$","type":"string"}},{"name":"hydrated","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["true","false"]}]}},{"name":"column","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{}}]}},{"name":"employeeMin","required":false,"in":"query","schema":{"minimum":0,"maximum":9007199254740991,"type":"integer"}},{"name":"employeeMax","required":false,"in":"query","schema":{"minimum":0,"maximum":9007199254740991,"type":"integer"}},{"name":"industry","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}},{"name":"hqCountry","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]}}],"responses":{"200":{"description":""}},"tags":["company-lists"]}},"/api/company-lists/{id}/members/by-keys":{"get":{"operationId":"CompanyListsController_membersByKeys","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"keys","required":false,"in":"query","schema":{"maxItems":100,"type":"array","items":{"type":"string","minLength":1,"maxLength":2048}}}],"responses":{"200":{"description":""}},"tags":["company-lists"]}},"/api/company-lists/{id}/members/remove":{"post":{"operationId":"CompanyListsController_removeMembersByKeys","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyListMemberKeysActionDto"}}}},"responses":{"200":{"description":""}},"tags":["company-lists"]}},"/api/company-lists/{id}/members/restore":{"post":{"operationId":"CompanyListsController_restoreMembersByKeys","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyListMemberKeysActionDto"}}}},"responses":{"200":{"description":""}},"tags":["company-lists"]}},"/api/company-lists/{id}/reconcile":{"put":{"operationId":"CompanyListsController_reconcile","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyListReconcileDto"}}}},"responses":{"200":{"description":""}},"tags":["company-lists"]}},"/api/act-as/candidates":{"get":{"operationId":"ActAsController_candidates","parameters":[],"responses":{"200":{"description":""}},"tags":["act-as"]}},"/api/act-as/start":{"post":{"operationId":"ActAsController_start","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActAsStartDto"}}}},"responses":{"200":{"description":""}},"tags":["act-as"]}},"/api/act-as/stop":{"post":{"operationId":"ActAsController_stop","parameters":[],"responses":{"200":{"description":""}},"tags":["act-as"]}},"/api/onboarding/signup":{"post":{"operationId":"OnboardingController_signup","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupDto"}}}},"responses":{"201":{"description":""}},"tags":["onboarding"]}},"/api/onboarding/subscribe":{"post":{"operationId":"OnboardingController_subscribe","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FreeToolSubscribeDto"}}}},"responses":{"201":{"description":""}},"tags":["onboarding"]}},"/api/onboarding/members/invite":{"post":{"operationId":"OnboardingController_inviteMember","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteMemberDto"}}}},"responses":{"201":{"description":""}},"tags":["onboarding"]}},"/api/onboarding/members/{memberId}/role":{"patch":{"operationId":"OnboardingController_changeMemberRole","parameters":[{"name":"memberId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangeMemberRoleDto"}}}},"responses":{"200":{"description":""}},"tags":["onboarding"]}},"/api/onboarding/organization/name":{"patch":{"operationId":"OnboardingController_renameOrganization","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenameOrganizationDto"}}}},"responses":{"200":{"description":""}},"tags":["onboarding"]}},"/api/onboarding/invitations/{id}":{"get":{"operationId":"OnboardingController_invitationPreview","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["onboarding"]}},"/api/leads/{id}/booked-meeting":{"get":{"operationId":"BookedMeetingsController_bookedMeeting","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["leads"]}},"/api/lists/agent":{"post":{"operationId":"AgentListController_unifiedAgent","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentChatDto"}}}},"responses":{"201":{"description":""}},"tags":["agent-list"]}},"/api/lists/agent/search-mode":{"get":{"operationId":"AgentListController_searchModeAvailability","parameters":[],"responses":{"200":{"description":""}},"tags":["agent-list"]}},"/api/lists/leads/search-more":{"post":{"operationId":"AgentListController_leadsSearchMore","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchMoreDto"}}}},"responses":{"201":{"description":""}},"tags":["agent-list"]}},"/api/lists/companies/search-more":{"post":{"operationId":"AgentListController_companiesSearchMore","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchMoreDto"}}}},"responses":{"201":{"description":""}},"tags":["agent-list"]}},"/api/icps":{"get":{"operationId":"IcpController_list","parameters":[],"responses":{"200":{"description":""}},"tags":["icps"]},"post":{"operationId":"IcpController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIcpDto"}}}},"responses":{"201":{"description":""}},"tags":["icps"]}},"/api/icps/editor":{"get":{"operationId":"IcpController_listForEditor","parameters":[],"responses":{"200":{"description":""}},"tags":["icps"]}},"/api/icps/{id}":{"get":{"operationId":"IcpController_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["icps"]},"put":{"operationId":"IcpController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateIcpDto"}}}},"responses":{"200":{"description":""}},"tags":["icps"]},"delete":{"operationId":"IcpController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["icps"]}},"/api/icps/{id}/editor":{"get":{"operationId":"IcpController_getForEditor","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["icps"]}},"/api/icps/{id}/publish-preview":{"get":{"operationId":"IcpController_publishPreview","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["icps"]}},"/api/icps/{id}/publish":{"post":{"operationId":"IcpController_publish","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishIcpDto"}}}},"responses":{"200":{"description":""}},"tags":["icps"]}},"/api/icps/{id}/draft":{"delete":{"operationId":"IcpController_discardDraft","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["icps"]}},"/api/icps/{id}/versions/{version}/restore":{"post":{"operationId":"IcpController_restore","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"version","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"tags":["icps"]}},"/api/icps/{id}/versions":{"get":{"operationId":"IcpController_versions","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["icps"]}},"/api/icps/{id}/versions/{version}":{"get":{"operationId":"IcpController_version","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"version","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"tags":["icps"]}},"/api/icps/{id}/usage":{"get":{"operationId":"IcpController_usage","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["icps"]}},"/api/icps/agent":{"post":{"operationId":"AgentIcpController_agent","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentIcpChatDto"}}}},"responses":{"201":{"description":""}},"tags":["agent-icp"]}},"/api/settings/value-proposition/agent":{"post":{"operationId":"AgentValuePropController_agent","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentValuePropChatDto"}}}},"responses":{"201":{"description":""}},"tags":["agent-value-prop"]}},"/api/signals-agent":{"post":{"operationId":"AgentSignalsController_agent","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentSignalsChatDto"}}}},"responses":{"201":{"description":""}},"tags":["agent-signals"]}},"/api/lead-lists/{leadListId}/source":{"get":{"operationId":"SourcesController_get","parameters":[{"name":"leadListId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["sources"]},"post":{"operationId":"SourcesController_create","parameters":[{"name":"leadListId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceBodyDto"}}}},"responses":{"201":{"description":""}},"tags":["sources"]},"put":{"operationId":"SourcesController_set","parameters":[{"name":"leadListId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetSourceBodyDto"}}}},"responses":{"200":{"description":""}},"tags":["sources"]},"patch":{"operationId":"SourcesController_update","parameters":[{"name":"leadListId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSourceBodyDto"}}}},"responses":{"200":{"description":""}},"tags":["sources"]},"delete":{"operationId":"SourcesController_delete","parameters":[{"name":"leadListId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["sources"]}},"/api/lead-lists/{leadListId}/source/signals":{"post":{"operationId":"SourcesController_addSignal","parameters":[{"name":"leadListId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddSignalBodyDto"}}}},"responses":{"201":{"description":""}},"tags":["sources"]}},"/api/lead-lists/{leadListId}/source/signals/{signalId}":{"patch":{"operationId":"SourcesController_editSignal","parameters":[{"name":"leadListId","required":true,"in":"path","schema":{"type":"string"}},{"name":"signalId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EditSignalConfigBodyDto"}}}},"responses":{"200":{"description":""}},"tags":["sources"]},"delete":{"operationId":"SourcesController_removeSignal","parameters":[{"name":"leadListId","required":true,"in":"path","schema":{"type":"string"}},{"name":"signalId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["sources"]}},"/api/lead-lists/{leadListId}/source/run":{"post":{"operationId":"SourcesController_runNow","parameters":[{"name":"leadListId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["sources"]}},"/api/lead-lists/{leadListId}/source/runs":{"get":{"operationId":"SourcesController_listRuns","parameters":[{"name":"leadListId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["sources"]}},"/api/lead-lists/{leadListId}/source/runs/{runId}/items":{"get":{"operationId":"SourcesController_listRunItems","parameters":[{"name":"leadListId","required":true,"in":"path","schema":{"type":"string"}},{"name":"runId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["sources"]}},"/api/lead-lists/{leadListId}/source/runs/{runId}/requalify":{"post":{"operationId":"SourcesController_requalifyRun","parameters":[{"name":"leadListId","required":true,"in":"path","schema":{"type":"string"}},{"name":"runId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequalifyRunBodyDto"}}}},"responses":{"200":{"description":""}},"tags":["sources"]}},"/api/source-preview":{"post":{"operationId":"SourcePreviewController_run","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourcePreviewBodyDto"}}}},"responses":{"200":{"description":""}},"tags":["sources"]}},"/api/growing-list-usage":{"get":{"operationId":"GrowingListUsageController_usage","parameters":[],"responses":{"200":{"description":""}},"tags":["sources"]}},"/api/source-health":{"get":{"operationId":"SourceHealthController_health","parameters":[],"responses":{"200":{"description":""}},"tags":["sources"]}},"/api/leads/{leadId}/signals":{"get":{"operationId":"LeadSignalsController_list","parameters":[{"name":"leadId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["sources"]}},"/api/agent":{"post":{"operationId":"AgentGuideController_agent","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentChatDto"}}}},"responses":{"201":{"description":""}},"tags":["agent-guide"]}},"/api/campaigns/agent":{"post":{"operationId":"AgentCampaignController_agent","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentCampaignChatDto"}}}},"responses":{"201":{"description":""}},"tags":["agent-campaign"]}},"/api/inbox/seats":{"get":{"operationId":"InboxController_seats","parameters":[],"responses":{"200":{"description":""}},"tags":["inbox"]}},"/api/inbox/mailboxes":{"get":{"operationId":"InboxController_mailboxes","parameters":[],"responses":{"200":{"description":""}},"tags":["inbox"]}},"/api/inbox/unread-count":{"get":{"operationId":"InboxController_unreadCount","parameters":[],"responses":{"200":{"description":""}},"tags":["inbox"]}},"/api/inbox/needs-human-count":{"get":{"operationId":"InboxController_needsHumanCount","parameters":[],"responses":{"200":{"description":""}},"tags":["inbox"]}},"/api/inbox/interested-unanswered-count":{"get":{"operationId":"InboxController_interestedUnansweredCount","parameters":[],"responses":{"200":{"description":""}},"tags":["inbox"]}},"/api/inbox/resolve-chat":{"get":{"operationId":"InboxController_resolveChat","parameters":[{"name":"providerChatId","required":true,"in":"query","schema":{"type":"string"}},{"name":"seatId","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["inbox"]}},"/api/inbox/sync":{"post":{"operationId":"InboxController_syncNow","parameters":[],"responses":{"202":{"description":""}},"tags":["inbox"]}},"/api/inbox/chats":{"get":{"operationId":"InboxController_listChats","parameters":[{"name":"seatId","required":false,"in":"query","schema":{"maxLength":64,"type":"string"}},{"name":"channel","required":false,"in":"query","schema":{"type":"string","enum":["linkedin","email"]}},{"name":"mailbox","required":false,"in":"query","schema":{"maxLength":320,"type":"string"}},{"name":"leadId","required":false,"in":"query","schema":{"maxLength":64,"type":"string"}},{"name":"campaignId","required":false,"in":"query","schema":{"maxLength":64,"type":"string"}},{"name":"unread","required":false,"in":"query","description":"True returns only chats with unread messages.","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["0","1","true","false"]}]}},{"name":"answered","required":false,"in":"query","description":"'no' returns chats waiting on a reply from you (they spoke last); 'yes' returns the ones you already answered. Chats whose history has not been loaded yet match neither.","schema":{"type":"string","enum":["yes","no"]}},{"name":"leadsOnly","required":false,"in":"query","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["0","1","true","false"]}]}},{"name":"needsHuman","required":false,"in":"query","description":"True returns only chats where Kairon stepped back and is waiting on you.","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["0","1","true","false"]}]}},{"name":"classification","required":false,"in":"query","description":"What their last inbound message meant: interested, objection, neutral, or not_interested. Combine with answered=no for the pile you have not replied to.","schema":{"type":"string","enum":["interested","objection","neutral","not_interested"]}},{"name":"seen","required":false,"in":"query","description":"True returns LinkedIn chats where they saw your last message and have not replied. Checks LinkedIn live for up to 50 chats first, so the first call can take up to a minute; calling again works through the rest. On normal (non-Sales Navigator) chats many people hide read receipts, so a chat missing here may still have been read. It already means your message is the last one: do not combine it with answered.","x-nestjs_zod-empty-type":true,"schema":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["0","1","true","false"]}]}},{"name":"q","required":false,"in":"query","schema":{"maxLength":200,"type":"string"}},{"name":"cursor","required":false,"in":"query","schema":{"maxLength":65536,"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":30,"type":"integer"}}],"responses":{"200":{"description":""}},"tags":["inbox"]}},"/api/inbox/chats/{chatId}":{"get":{"operationId":"InboxController_getChat","parameters":[{"name":"chatId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["inbox"]}},"/api/inbox/chats/{chatId}/template-vars":{"get":{"operationId":"InboxController_getTemplateVars","parameters":[{"name":"chatId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["inbox"]}},"/api/inbox/chats/{chatId}/messages":{"get":{"operationId":"InboxController_getThread","parameters":[{"name":"chatId","required":true,"in":"path","schema":{"type":"string"}},{"name":"cursor","required":false,"in":"query","schema":{"maxLength":65536,"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":30,"type":"integer"}}],"responses":{"200":{"description":""}},"tags":["inbox"]},"post":{"operationId":"InboxController_reply","parameters":[{"name":"chatId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InboxReplyDto"}}}},"responses":{"201":{"description":""}},"tags":["inbox"]}},"/api/inbox/chats/{chatId}/messages/{messageId}/attachments/{index}":{"get":{"operationId":"InboxController_attachment","parameters":[{"name":"chatId","required":true,"in":"path","schema":{"type":"string"}},{"name":"messageId","required":true,"in":"path","schema":{"type":"string"}},{"name":"index","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["inbox"]}},"/api/inbox/chats/{chatId}/messages/suggest":{"post":{"operationId":"InboxController_suggest","parameters":[{"name":"chatId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["inbox"]}},"/api/inbox/chats/{chatId}/messages/{messageId}":{"patch":{"operationId":"InboxController_editMessage","parameters":[{"name":"chatId","required":true,"in":"path","schema":{"type":"string"}},{"name":"messageId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InboxEditDto"}}}},"responses":{"200":{"description":""}},"tags":["inbox"]},"delete":{"operationId":"InboxController_deleteMessage","parameters":[{"name":"chatId","required":true,"in":"path","schema":{"type":"string"}},{"name":"messageId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["inbox"]}},"/api/inbox/chats/{chatId}/read":{"post":{"operationId":"InboxController_markRead","parameters":[{"name":"chatId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["inbox"]}},"/api/inbox/chats/{chatId}/unread":{"post":{"operationId":"InboxController_markUnread","parameters":[{"name":"chatId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["inbox"]}},"/api/inbox/chats/{chatId}/lead":{"post":{"operationId":"InboxController_addAsLead","parameters":[{"name":"chatId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["inbox"]}},"/api/snippets":{"get":{"operationId":"SnippetsController_list","parameters":[],"responses":{"200":{"description":""}},"tags":["snippets"]},"post":{"operationId":"SnippetsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SnippetCreateDto"}}}},"responses":{"201":{"description":""}},"tags":["snippets"]}},"/api/snippets/{id}":{"patch":{"operationId":"SnippetsController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SnippetUpdateDto"}}}},"responses":{"200":{"description":""}},"tags":["snippets"]},"delete":{"operationId":"SnippetsController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["snippets"]}},"/api/crm/nurture-setup":{"get":{"operationId":"NurtureController_read","parameters":[],"responses":{"200":{"description":""}},"tags":["crm"]}},"/api/profile-buttons/menus":{"get":{"operationId":"ProfileButtonsController_menus","parameters":[],"responses":{"200":{"description":""}},"tags":["profile-buttons"]}},"/api/profile-buttons/profiles/{slug}":{"get":{"operationId":"ProfileButtonsController_view","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["profile-buttons"]}},"/api/profile-buttons/profiles/{slug}/lead":{"post":{"operationId":"ProfileButtonsController_createLead","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["profile-buttons"]}},"/api/profile-buttons/leads/{leadId}/qualify":{"post":{"operationId":"ProfileButtonsController_qualify","parameters":[{"name":"leadId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileButtonsQualifyDto"}}}},"responses":{"201":{"description":""}},"tags":["profile-buttons"]}},"/api/initiatives":{"get":{"operationId":"InitiativesController_list","parameters":[{"name":"status","required":false,"in":"query","schema":{"type":"string","enum":["draft","active","completed","canceled"]}}],"responses":{"200":{"description":""}},"tags":["initiatives"]},"post":{"operationId":"InitiativesController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InitiativeCreateDto"}}}},"responses":{"201":{"description":""}},"tags":["initiatives"]}},"/api/initiatives/{id}":{"get":{"operationId":"InitiativesController_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["initiatives"]},"patch":{"operationId":"InitiativesController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InitiativeUpdateDto"}}}},"responses":{"200":{"description":""}},"tags":["initiatives"]},"delete":{"operationId":"InitiativesController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["initiatives"]}},"/api/initiatives/{id}/checkpoints":{"get":{"operationId":"InitiativesController_checkpoints","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["initiatives"]},"post":{"operationId":"InitiativesController_publishCheckpoint","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckpointPublishDto"}}}},"responses":{"201":{"description":""}},"tags":["initiatives"]}},"/api/initiatives/{id}/checkpoints/{checkpointId}":{"patch":{"operationId":"InitiativesController_updateCheckpoint","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"checkpointId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckpointUpdateDto"}}}},"responses":{"200":{"description":""}},"tags":["initiatives"]},"delete":{"operationId":"InitiativesController_removeCheckpoint","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"checkpointId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["initiatives"]}},"/api/initiatives/{id}/owner":{"put":{"operationId":"InitiativesController_setOwner","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InitiativeOwnerSetDto"}}}},"responses":{"200":{"description":""}},"tags":["initiatives"]}},"/api/partner/workspaces":{"post":{"operationId":"PartnerController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerWorkspaceCreateDto"}}}},"responses":{"201":{"description":""}},"tags":["partner"]},"get":{"operationId":"PartnerController_list","parameters":[],"responses":{"200":{"description":""}},"tags":["partner"]}},"/api/partner/workspaces/{id}/api-key":{"post":{"operationId":"PartnerController_newKey","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["partner"]}},"/api/partner/workspaces/{id}":{"delete":{"operationId":"PartnerController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["partner"]}},"/api/csv-imports/runs":{"post":{"operationId":"CsvImportController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCsvImportDto"}}}},"responses":{"201":{"description":""}},"tags":["csv-imports"]},"get":{"operationId":"CsvImportController_listActive","parameters":[],"responses":{"200":{"description":""}},"tags":["csv-imports"]}},"/api/csv-imports/runs/{id}":{"get":{"operationId":"CsvImportController_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["csv-imports"]},"delete":{"operationId":"CsvImportController_delete","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["csv-imports"]}},"/api/csv-imports/runs/{id}/rows":{"get":{"operationId":"CsvImportController_rows","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["csv-imports"]}},"/api/csv-imports/runs/{id}/resolve":{"post":{"operationId":"CsvImportController_resolve","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"202":{"description":""}},"tags":["csv-imports"]}},"/api/csv-imports/runs/{id}/complete":{"post":{"operationId":"CsvImportController_complete","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CsvImportCompleteDto"}}}},"responses":{"201":{"description":""}},"tags":["csv-imports"]}},"/api/lead-lists/{id}/email-enrichment/estimate":{"get":{"operationId":"EmailEnrichmentController_estimate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["email-enrichment"]}},"/api/lead-lists/{id}/email-enrichment/run":{"get":{"operationId":"EmailEnrichmentController_latestForList","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["email-enrichment"]}},"/api/lead-lists/{id}/email-enrichment":{"post":{"operationId":"EmailEnrichmentController_start","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartEmailEnrichmentDto"}}}},"responses":{"201":{"description":""}},"tags":["email-enrichment"]}},"/api/email-enrichment/runs":{"get":{"operationId":"EmailEnrichmentController_listActive","parameters":[],"responses":{"200":{"description":""}},"tags":["email-enrichment"]}},"/api/email-enrichment/runs/{id}":{"get":{"operationId":"EmailEnrichmentController_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["email-enrichment"]}},"/api/email-enrichment/runs/{id}/cancel":{"post":{"operationId":"EmailEnrichmentController_cancel","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["email-enrichment"]}},"/api/copilot":{"get":{"operationId":"CopilotController_feed","parameters":[],"responses":{"200":{"description":""}},"tags":["copilot"]}},"/api/copilot/runs/{runId}":{"get":{"operationId":"CopilotController_runDetail","parameters":[{"name":"runId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["copilot"]}},"/api/copilot/sends/{nodeRunId}":{"patch":{"operationId":"CopilotController_editSend","parameters":[{"name":"nodeRunId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CopilotEditSendDto"}}}},"responses":{"200":{"description":""}},"tags":["copilot"]}},"/api/copilot/sends/{nodeRunId}/regenerate":{"post":{"operationId":"CopilotController_regenerateSend","parameters":[{"name":"nodeRunId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CopilotRegenerateDto"}}}},"responses":{"201":{"description":""}},"tags":["copilot"]}},"/api/copilot/runs/{runId}/cancel":{"post":{"operationId":"CopilotController_cancelRun","parameters":[{"name":"runId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["copilot"]}},"/api/copilot/runs/{runId}/approve":{"post":{"operationId":"CopilotController_approveRun","parameters":[{"name":"runId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["copilot"]}},"/api/copilot/runs/{runId}/dismiss":{"post":{"operationId":"CopilotController_dismissRun","parameters":[{"name":"runId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["copilot"]}},"/api/copilot/runs/{runId}/retry":{"post":{"operationId":"CopilotController_retryRun","parameters":[{"name":"runId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"tags":["copilot"]}},"/api/content-settings":{"get":{"operationId":"ContentSettingsController_get","parameters":[],"responses":{"200":{"description":""}},"tags":["content-settings"]},"put":{"operationId":"ContentSettingsController_set","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentSettingsInputDto"}}}},"responses":{"200":{"description":""}},"tags":["content-settings"]}},"/api/notification-settings":{"get":{"operationId":"NotificationSettingsController_get","parameters":[],"responses":{"200":{"description":""}},"tags":["notification-settings"]},"put":{"operationId":"NotificationSettingsController_set","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationSettingsInputDto"}}}},"responses":{"200":{"description":""}},"tags":["notification-settings"]}},"/api/content/agent":{"post":{"operationId":"AgentContentController_agent","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentContentChatDto"}}}},"responses":{"201":{"description":""}},"tags":["agent-content"]}},"/api/content-settings/checks/suggest":{"post":{"operationId":"ContentCheckSuggestController_suggest","parameters":[],"responses":{"201":{"description":""}},"tags":["content-settings"]}},"/api/integrations/mcp":{"get":{"operationId":"IntegrationsController_mcpConnection","parameters":[],"responses":{"200":{"description":""}},"tags":["integrations"]}},"/api/integrations/instantly":{"get":{"operationId":"IntegrationsController_instantly","parameters":[],"responses":{"200":{"description":""}},"tags":["integrations"]},"post":{"operationId":"IntegrationsController_connectInstantly","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectInstantlyDto"}}}},"responses":{"201":{"description":""}},"tags":["integrations"]},"delete":{"operationId":"IntegrationsController_disconnectInstantly","parameters":[],"responses":{"204":{"description":""}},"tags":["integrations"]}},"/api/integrations/instantly/webhooks/repair":{"post":{"operationId":"IntegrationsController_repairInstantlyWebhooks","parameters":[],"responses":{"200":{"description":""}},"tags":["integrations"]}},"/api/integrations/instantly/kairon-workspace":{"post":{"operationId":"IntegrationsController_adoptKaironWorkspace","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdoptKaironWorkspaceDto"}}}},"responses":{"201":{"description":""}},"tags":["integrations"]},"delete":{"operationId":"IntegrationsController_releaseKaironWorkspace","parameters":[],"responses":{"204":{"description":""}},"tags":["integrations"]}},"/api/integrations/instantly/domains/search":{"post":{"operationId":"IntegrationsController_searchSendingDomain","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchSendingDomainDto"}}}},"responses":{"200":{"description":""}},"tags":["integrations"]}},"/api/integrations/instantly/domains/pre-warmed":{"get":{"operationId":"IntegrationsController_preWarmedSendingDomains","parameters":[],"responses":{"200":{"description":""}},"tags":["integrations"]}},"/api/integrations/instantly/domains/quote":{"post":{"operationId":"IntegrationsController_quoteSendingDomain","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteSendingDomainDto"}}}},"responses":{"200":{"description":""}},"tags":["integrations"]}},"/api/integrations/instantly/domains":{"get":{"operationId":"IntegrationsController_listSendingDomains","parameters":[],"responses":{"200":{"description":""}},"tags":["integrations"]}},"/api/integrations/instantly/domains/buy":{"post":{"operationId":"IntegrationsController_buySendingDomain","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuySendingDomainDto"}}}},"responses":{"200":{"description":""}},"tags":["integrations"]}},"/api/integrations/instantly/domains/{domain}/mailboxes":{"get":{"operationId":"IntegrationsController_provisionedMailboxes","parameters":[{"name":"domain","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["integrations"]}},"/api/integrations/instantly/domains/{domain}/attach":{"post":{"operationId":"IntegrationsController_attachSendingDomain","parameters":[{"name":"domain","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["integrations"]}},"/api/integrations/instantly/plan":{"get":{"operationId":"IntegrationsController_emailPlan","parameters":[],"responses":{"200":{"description":""}},"tags":["integrations"]}},"/api/integrations/instantly/plan/requests":{"post":{"operationId":"IntegrationsController_requestEmailPlan","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailPlanRequestDto"}}}},"responses":{"200":{"description":""}},"tags":["integrations"]}},"/api/integrations/instantly/mailboxes":{"post":{"operationId":"IntegrationsController_addOwnedMailbox","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddOwnedMailboxDto"}}}},"responses":{"200":{"description":""}},"tags":["integrations"]}},"/api/integrations/instantly/mailboxes/oauth":{"post":{"operationId":"IntegrationsController_startMailboxOauth","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartMailboxOauthDto"}}}},"responses":{"200":{"description":""}},"tags":["integrations"]}},"/api/integrations/instantly/mailboxes/oauth/status":{"post":{"operationId":"IntegrationsController_mailboxOauthStatus","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MailboxOauthStatusDto"}}}},"responses":{"200":{"description":""}},"tags":["integrations"]}},"/api/integrations/instantly/domains/{domain}/check":{"post":{"operationId":"IntegrationsController_checkSendingDomain","parameters":[{"name":"domain","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["integrations"]}},"/api/integrations/instantly/domains/{domain}/warmup":{"post":{"operationId":"IntegrationsController_startSendingDomainWarmup","parameters":[{"name":"domain","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["integrations"]}},"/api/integrations/instantly/campaigns":{"get":{"operationId":"IntegrationsController_instantlyCampaigns","parameters":[],"responses":{"200":{"description":""}},"tags":["integrations"]}},"/api/skills":{"get":{"operationId":"SkillsController_list","parameters":[],"responses":{"200":{"description":""}},"tags":["skills"]}},"/api/skills/{name}":{"get":{"operationId":"SkillsController_get","parameters":[{"name":"name","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["skills"]}},"/api/models":{"get":{"operationId":"GatewayModelsController_list","parameters":[],"responses":{"200":{"description":""}},"tags":["models"]}},"/api/learn-progress":{"get":{"operationId":"LearnProgressController_get","parameters":[],"responses":{"200":{"description":""}},"tags":["learn"]}},"/api/learn-progress/lessons/{slug}":{"put":{"operationId":"LearnProgressController_setLesson","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LearnLessonProgressDto"}}}},"responses":{"200":{"description":""}},"tags":["learn"]}}},"info":{"title":"Kairon API","description":"B2B agentic go-to-market platform","version":"0.0.0","contact":{}},"tags":[],"servers":[],"components":{"securitySchemes":{"api-key":{"type":"apiKey","in":"header","name":"x-api-key","description":"A Kairon API key (Settings → Integrations → API access), sent as `x-api-key`. NOT an `Authorization: Bearer` token — that header belongs to the separate /mcp door and is ignored here."},"session":{"type":"apiKey","in":"cookie","name":"better-auth.session_token"}},"schemas":{"ActivationLetterSendDto":{"type":"object","properties":{"subject":{"type":"string","minLength":1,"maxLength":200},"body":{"type":"string","minLength":1,"maxLength":8000}},"required":["subject","body"]},"AdminOrgSuspensionDto":{"type":"object","properties":{"suspended":{"type":"boolean"},"partner":{"type":"boolean"}}},"AdminOrgDeactivationDto":{"type":"object","properties":{"reason":{"type":"string","minLength":1,"maxLength":200}},"required":["reason"]},"AdminOrgAiBalanceGrantDto":{"type":"object","properties":{"amountUsd":{"type":"number","minimum":1,"maximum":100},"reason":{"type":"string","maxLength":200}},"required":["amountUsd"]},"AdminPlanChangeDto":{"type":"object","properties":{"kind":{"type":"string","enum":["starter","custom","free"]},"terms":{"type":"","x-nestjs_zod-empty-type":true}},"required":["kind"]},"AdminWorkspaceCreateDto":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"x-nestjs_zod-uses-3-point-1-syntax":true},"ownerEmail":{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$","x-nestjs_zod-uses-3-point-1-syntax":true},"plan":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"custom"},"terms":{"type":"object","properties":{"monthlyPriceUsd":{"type":"number","minimum":0},"allowanceUsd":{"type":"number","minimum":0},"includedSeats":{"type":"integer","minimum":0,"maximum":9007199254740991},"includedMailboxes":{"type":"integer","minimum":0,"maximum":9007199254740991},"extraSeatUsd":{"type":"number","minimum":0},"extraMailboxUsd":{"type":"number","minimum":0},"includedGrowingLists":{"type":"integer","minimum":0,"maximum":9007199254740991},"extraGrowingListUsd":{"type":"number","minimum":0}},"required":["monthlyPriceUsd","allowanceUsd","includedSeats","includedMailboxes","extraSeatUsd","extraMailboxUsd","includedGrowingLists","extraGrowingListUsd"]}},"required":["kind","terms"]},{"type":"object","properties":{"kind":{"type":"string","const":"free"},"terms":{"type":"object","properties":{"includedSeats":{"type":"integer","minimum":0,"maximum":9007199254740991},"includedMailboxes":{"type":"integer","minimum":0,"maximum":9007199254740991},"includedGrowingLists":{"default":2,"type":"integer","minimum":0,"maximum":9007199254740991},"monthlyPriceUsd":{"type":"number","const":0},"allowanceUsd":{"type":"null"},"extraSeatUsd":{"type":"null"},"extraMailboxUsd":{"type":"null"},"extraGrowingListUsd":{"type":"null"}},"required":["includedSeats","includedMailboxes"]}},"required":["kind","terms"]}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true}},"required":["name","ownerEmail","plan"]},"AdminOwnerInviteDto":{"type":"object","properties":{"ownerEmail":{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"required":["ownerEmail"]},"AdoptWorkspaceForOrgDto":{"type":"object","properties":{"kaironWorkspaceId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"timeZone":{"type":"string","maxLength":100}},"required":["kaironWorkspaceId"]},"SeatPoolEligibilityDto":{"type":"object","properties":{"poolEligible":{"type":"boolean"}},"required":["poolEligible"]},"WaitlistNotifyDto":{"type":"object","properties":{"locale":{"type":"string","enum":["en","es"]}},"required":["locale"]},"ConnectLinkedinDto":{"type":"object","properties":{"username":{"type":"string","minLength":1,"maxLength":256},"password":{"type":"string","minLength":1,"maxLength":512},"totpSecret":{"type":"string","minLength":1,"maxLength":256},"captureScope":{"type":"string","enum":["full","future_only","leads_and_platform"]},"backfillMonths":{"type":"integer","minimum":1,"maximum":12},"country":{"type":"string"}},"required":["username","password","captureScope"]},"ConnectLinkedinCookieDto":{"type":"object","properties":{"accessToken":{"type":"string","minLength":1,"maxLength":2048},"premiumToken":{"type":"string","minLength":1,"maxLength":2048},"userAgent":{"type":"string","minLength":1,"maxLength":512},"country":{"type":"string"},"captureScope":{"type":"string","enum":["full","future_only","leads_and_platform"]},"backfillMonths":{"type":"integer","minimum":1,"maximum":12}},"required":["accessToken","userAgent"]},"SolveCheckpointDto":{"type":"object","properties":{"code":{"type":"string","minLength":1,"maxLength":64}},"required":["code"]},"ChangeCaptureScopeDto":{"type":"object","properties":{"scope":{"type":"string","enum":["full","future_only","leads_and_platform"]},"confirmDeletion":{"type":"boolean"}},"required":["scope"]},"BillingCheckoutDto":{"type":"object","properties":{"plan":{"type":"string","const":"starter","x-nestjs_zod-uses-3-point-1-syntax":true}},"required":["plan"]},"ColdEmailDto":{"type":"object","properties":{"tier":{"anyOf":[{"type":"string","enum":["cold_email_1k","cold_email_25k"]},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true}},"required":["tier"]},"ProfileFetchDto":{"type":"object","properties":{"target":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"url","description":"Which form `value` takes. Exactly one form per call — pick the one you actually have rather than reshaping it."},"value":{"type":"string","minLength":1,"maxLength":512,"description":"A LinkedIn profile or company URL."},"kind":{"description":"What `value` names, when already known — set for you on targets read off a list row. Leave unset when addressing something by hand; `linkedin_fetch`'s own `kind` overrides it. Ignored on a URL, which already says what it points at.","type":"string","enum":["profile","company"]}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","const":"public_identifier","description":"Which form `value` takes. Exactly one form per call — pick the one you actually have rather than reshaping it."},"value":{"type":"string","minLength":1,"maxLength":512,"description":"The vanity slug (e.g. \"jane-doe\") or company universal name."},"kind":{"description":"What `value` names, when already known — set for you on targets read off a list row. Leave unset when addressing something by hand; `linkedin_fetch`'s own `kind` overrides it. Ignored on a URL, which already says what it points at.","type":"string","enum":["profile","company"]}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","const":"provider_id","description":"Which form `value` takes. Exactly one form per call — pick the one you actually have rather than reshaping it."},"value":{"type":"string","minLength":1,"maxLength":512,"description":"Unipile/LinkedIn internal id (e.g. \"ACoAAB…\" or the Sales-Nav \"ACwAAB…\")."},"kind":{"description":"What `value` names, when already known — set for you on targets read off a list row. Leave unset when addressing something by hand; `linkedin_fetch`'s own `kind` overrides it. Ignored on a URL, which already says what it points at.","type":"string","enum":["profile","company"]}},"required":["type","value"]}],"description":"Who this acts on — one LinkedIn person or company, named by URL, vanity slug, or provider id.","x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"refresh":{"description":"True bypasses the cache and re-fetches from LinkedIn. Slower, and it spends a lookup.","type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true},"withRecommendations":{"description":"True also returns who recommended this person (and who they recommended), with each recommender identified. Warm-intro paths. Always spends a live lookup — never served from cache.","type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true}},"required":["target"]},"CompanyFetchDto":{"type":"object","properties":{"target":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"url","description":"Which form `value` takes. Exactly one form per call — pick the one you actually have rather than reshaping it."},"value":{"type":"string","minLength":1,"maxLength":512,"description":"A LinkedIn profile or company URL."},"kind":{"description":"What `value` names, when already known — set for you on targets read off a list row. Leave unset when addressing something by hand; `linkedin_fetch`'s own `kind` overrides it. Ignored on a URL, which already says what it points at.","type":"string","enum":["profile","company"]}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","const":"public_identifier","description":"Which form `value` takes. Exactly one form per call — pick the one you actually have rather than reshaping it."},"value":{"type":"string","minLength":1,"maxLength":512,"description":"The vanity slug (e.g. \"jane-doe\") or company universal name."},"kind":{"description":"What `value` names, when already known — set for you on targets read off a list row. Leave unset when addressing something by hand; `linkedin_fetch`'s own `kind` overrides it. Ignored on a URL, which already says what it points at.","type":"string","enum":["profile","company"]}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","const":"provider_id","description":"Which form `value` takes. Exactly one form per call — pick the one you actually have rather than reshaping it."},"value":{"type":"string","minLength":1,"maxLength":512,"description":"Unipile/LinkedIn internal id (e.g. \"ACoAAB…\" or the Sales-Nav \"ACwAAB…\")."},"kind":{"description":"What `value` names, when already known — set for you on targets read off a list row. Leave unset when addressing something by hand; `linkedin_fetch`'s own `kind` overrides it. Ignored on a URL, which already says what it points at.","type":"string","enum":["profile","company"]}},"required":["type","value"]}],"description":"Who this acts on — one LinkedIn person or company, named by URL, vanity slug, or provider id.","x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"refresh":{"type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true}},"required":["target"]},"ProfilePostsDto":{"type":"object","properties":{"target":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"url","description":"Which form `value` takes. Exactly one form per call — pick the one you actually have rather than reshaping it."},"value":{"type":"string","minLength":1,"maxLength":512,"description":"A LinkedIn profile or company URL."},"kind":{"description":"What `value` names, when already known — set for you on targets read off a list row. Leave unset when addressing something by hand; `linkedin_fetch`'s own `kind` overrides it. Ignored on a URL, which already says what it points at.","type":"string","enum":["profile","company"]}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","const":"public_identifier","description":"Which form `value` takes. Exactly one form per call — pick the one you actually have rather than reshaping it."},"value":{"type":"string","minLength":1,"maxLength":512,"description":"The vanity slug (e.g. \"jane-doe\") or company universal name."},"kind":{"description":"What `value` names, when already known — set for you on targets read off a list row. Leave unset when addressing something by hand; `linkedin_fetch`'s own `kind` overrides it. Ignored on a URL, which already says what it points at.","type":"string","enum":["profile","company"]}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","const":"provider_id","description":"Which form `value` takes. Exactly one form per call — pick the one you actually have rather than reshaping it."},"value":{"type":"string","minLength":1,"maxLength":512,"description":"Unipile/LinkedIn internal id (e.g. \"ACoAAB…\" or the Sales-Nav \"ACwAAB…\")."},"kind":{"description":"What `value` names, when already known — set for you on targets read off a list row. Leave unset when addressing something by hand; `linkedin_fetch`'s own `kind` overrides it. Ignored on a URL, which already says what it points at.","type":"string","enum":["profile","company"]}},"required":["type","value"]}],"description":"Who this acts on — one LinkedIn person or company, named by URL, vanity slug, or provider id.","x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"cursor":{"type":"string","maxLength":65536,"x-nestjs_zod-uses-3-point-1-syntax":true}},"required":["target"]},"ProfileCommentsDto":{"type":"object","properties":{"target":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"url","description":"Which form `value` takes. Exactly one form per call — pick the one you actually have rather than reshaping it."},"value":{"type":"string","minLength":1,"maxLength":512,"description":"A LinkedIn profile or company URL."},"kind":{"description":"What `value` names, when already known — set for you on targets read off a list row. Leave unset when addressing something by hand; `linkedin_fetch`'s own `kind` overrides it. Ignored on a URL, which already says what it points at.","type":"string","enum":["profile","company"]}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","const":"public_identifier","description":"Which form `value` takes. Exactly one form per call — pick the one you actually have rather than reshaping it."},"value":{"type":"string","minLength":1,"maxLength":512,"description":"The vanity slug (e.g. \"jane-doe\") or company universal name."},"kind":{"description":"What `value` names, when already known — set for you on targets read off a list row. Leave unset when addressing something by hand; `linkedin_fetch`'s own `kind` overrides it. Ignored on a URL, which already says what it points at.","type":"string","enum":["profile","company"]}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","const":"provider_id","description":"Which form `value` takes. Exactly one form per call — pick the one you actually have rather than reshaping it."},"value":{"type":"string","minLength":1,"maxLength":512,"description":"Unipile/LinkedIn internal id (e.g. \"ACoAAB…\" or the Sales-Nav \"ACwAAB…\")."},"kind":{"description":"What `value` names, when already known — set for you on targets read off a list row. Leave unset when addressing something by hand; `linkedin_fetch`'s own `kind` overrides it. Ignored on a URL, which already says what it points at.","type":"string","enum":["profile","company"]}},"required":["type","value"]}],"description":"Who this acts on — one LinkedIn person or company, named by URL, vanity slug, or provider id.","x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"cursor":{"type":"string","maxLength":65536,"x-nestjs_zod-uses-3-point-1-syntax":true}},"required":["target"]},"ProfileReactionsDto":{"type":"object","properties":{"target":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"url","description":"Which form `value` takes. Exactly one form per call — pick the one you actually have rather than reshaping it."},"value":{"type":"string","minLength":1,"maxLength":512,"description":"A LinkedIn profile or company URL."},"kind":{"description":"What `value` names, when already known — set for you on targets read off a list row. Leave unset when addressing something by hand; `linkedin_fetch`'s own `kind` overrides it. Ignored on a URL, which already says what it points at.","type":"string","enum":["profile","company"]}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","const":"public_identifier","description":"Which form `value` takes. Exactly one form per call — pick the one you actually have rather than reshaping it."},"value":{"type":"string","minLength":1,"maxLength":512,"description":"The vanity slug (e.g. \"jane-doe\") or company universal name."},"kind":{"description":"What `value` names, when already known — set for you on targets read off a list row. Leave unset when addressing something by hand; `linkedin_fetch`'s own `kind` overrides it. Ignored on a URL, which already says what it points at.","type":"string","enum":["profile","company"]}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","const":"provider_id","description":"Which form `value` takes. Exactly one form per call — pick the one you actually have rather than reshaping it."},"value":{"type":"string","minLength":1,"maxLength":512,"description":"Unipile/LinkedIn internal id (e.g. \"ACoAAB…\" or the Sales-Nav \"ACwAAB…\")."},"kind":{"description":"What `value` names, when already known — set for you on targets read off a list row. Leave unset when addressing something by hand; `linkedin_fetch`'s own `kind` overrides it. Ignored on a URL, which already says what it points at.","type":"string","enum":["profile","company"]}},"required":["type","value"]}],"description":"Who this acts on — one LinkedIn person or company, named by URL, vanity slug, or provider id.","x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"cursor":{"type":"string","maxLength":65536,"x-nestjs_zod-uses-3-point-1-syntax":true}},"required":["target"]},"SearchPostsDto":{"type":"object","properties":{"datePosted":{"description":"One of LinkedIn's own recency windows.","type":"string","enum":["past-24h","past-week","past-month"]},"sortBy":{"description":"Result order. Defaults to relevance.","type":"string","enum":["relevance","date"]},"contentType":{"description":"Only posts carrying this kind of attachment.","type":"string","enum":["videos","images","live_videos","collaborative_articles","documents"]},"firstDegreeOnly":{"description":"Only posts by the seat's 1st-degree connections.","type":"boolean"},"postedByMe":{"description":"Only the seat's own posts.","type":"boolean"},"postedByFollowed":{"description":"Only posts by people the seat follows.","type":"boolean"},"fromMember":{"description":"Author NAMES — only posts written by these people.","minItems":1,"maxItems":10,"type":"array","items":{"type":"string","minLength":1,"maxLength":256}},"fromCompany":{"description":"Company NAMES — only posts published by these pages.","minItems":1,"maxItems":10,"type":"array","items":{"type":"string","minLength":1,"maxLength":256}},"mentioningMember":{"description":"Only posts that @-mention these people, by NAME.","minItems":1,"maxItems":10,"type":"array","items":{"type":"string","minLength":1,"maxLength":256}},"mentioningCompany":{"description":"Only posts that @-mention these companies, by NAME.","minItems":1,"maxItems":10,"type":"array","items":{"type":"string","minLength":1,"maxLength":256}},"authorIndustry":{"description":"Industry NAMES — only posts whose AUTHOR works in one of them.","minItems":1,"maxItems":10,"type":"array","items":{"type":"string","minLength":1,"maxLength":256}},"authorCompany":{"description":"Company NAMES — only posts whose AUTHOR works at one of them.","minItems":1,"maxItems":10,"type":"array","items":{"type":"string","minLength":1,"maxLength":256}},"authorKeywords":{"description":"Free text matched against the AUTHOR's profile, e.g. a job title.","type":"string","minLength":1,"maxLength":256},"keywords":{"type":"string","minLength":1,"maxLength":4096,"description":"Text matched against the post body. Boolean OR/AND/NOT allowed."},"cursor":{"type":"string","maxLength":65536}},"required":["keywords"]},"PostReactionsDto":{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":2048},"cursor":{"type":"string","maxLength":65536}},"required":["url"]},"EventAttendeesDto":{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":2048},"cursor":{"type":"string","maxLength":65536}},"required":["url"]},"NewsletterSubscribersDto":{"type":"object","properties":{"newsletter":{"type":"string","minLength":1,"maxLength":2048,"description":"The newsletter, as its URL (https://www.linkedin.com/newsletters/<name>-<id>/) or its bare numeric id. It must be a newsletter the connected seat OWNS — LinkedIn serves this list to the author only."},"cursor":{"description":"Continue from a previous page. Omit for the first page.","type":"string","maxLength":65536},"count":{"description":"Subscribers per page (default 50, max 100). LinkedIn refuses anything higher — asking for 250 fails the whole call, it does not clamp.","type":"integer","minimum":1,"maximum":100}},"required":["newsletter"]},"GroupMembersDto":{"type":"object","properties":{"group":{"type":"string","minLength":1,"maxLength":2048,"description":"The group, as its URL (https://www.linkedin.com/groups/<id>/) or its bare numeric id. Read on your own seat: a public group needs no membership and no Sales Navigator; a members-only group needs your seat to have joined it."},"cursor":{"description":"Continue from a previous page. Omit for the first page.","type":"string","maxLength":65536},"count":{"description":"Members per page (default 50, max 100). LinkedIn refuses anything higher.","type":"integer","minimum":1,"maximum":100}},"required":["group"]},"FilterResolveDto":{"type":"object","properties":{"type":{"type":"string","enum":["location","industry","function","current_company","past_company","company_location","school","past_role","groups","persona","technologies","account_lists","lead_lists","postal_code"],"description":"Which Sales Navigator dimension the name belongs to."},"query":{"type":"string","minLength":1,"maxLength":256,"description":"The human-readable NAME to resolve, e.g. \"San Francisco Bay Area\". Never a LinkedIn id — resolving one is what this is for, and the canonical label comes back so a wrong match is visible."}},"required":["type","query"]},"FilterSuggestDto":{"type":"object","properties":{"type":{"anyOf":[{"type":"string","enum":["location","industry","function","current_company","past_company","company_location","school","past_role","groups","persona","technologies","account_lists","lead_lists","postal_code"]},{"type":"string","enum":["from_member","from_company","mentioning_member","mentioning_company","author_industry","author_company"]},{"type":"string","enum":["job_region","job_title","job_function","job_industry"]}],"x-nestjs_zod-empty-type":true},"query":{"type":"string","minLength":1,"maxLength":256}},"required":["type","query"]},"PeopleSuggestDto":{"type":"object","properties":{"query":{"type":"string","minLength":1,"maxLength":256}},"required":["query"]},"SearchSalesNavigatorDto":{"type":"object","properties":{"category":{"default":"people","description":"Search people (default) or companies. Some fields are valid for only one category.","type":"string","enum":["people","companies"],"x-nestjs_zod-uses-3-point-1-syntax":true},"keywords":{"description":"LAST resort — matches noisily across all text. Prefer a structured filter for any title/industry/geography/size intent; use keywords only for a concept no filter captures. This is a BOOLEAN query, not a phrase: bare space-separated words are AND-ed (ALL must appear), so \"fintech payments neobank\" requires all three together and usually returns ZERO. For ALTERNATIVES, OR them, quote each, and ALWAYS wrap the OR group in parentheses: `(\"fintech\" OR \"payments\" OR \"neobank\")`. The parentheses are MANDATORY — LinkedIn silently mis-parses an unparenthesized OR of 4+ terms and returns ~0. Quote multi-word phrases; combine groups with AND/NOT (e.g. `(\"fintech\" OR \"neobank\") AND \"payments\"`). Operators must be UPPERCASE.","type":"string","minLength":1,"maxLength":2000,"x-nestjs_zod-uses-3-point-1-syntax":true},"filters":{"description":"Id-resolved dimensions (location, industry, company, …). Same dimension repeated = OR; different dimensions = AND (each narrows the results).","maxItems":40,"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["location","industry","function","current_company","past_company","company_location","school","past_role","groups","persona","technologies","account_lists","lead_lists","postal_code"],"description":"Which id-resolved dimension. People: location, industry, function, current_company, past_company, company_location, school, past_role, groups, persona, account_lists, lead_lists, postal_code. Companies: location, industry, technologies, account_lists, postal_code — the rest are people-only and are REFUSED here rather than quietly ignored. On a companies search the company IS the subject, so its location is plain `location` (`company_location` is accepted as a synonym for it, and means the EMPLOYER’s location only on a people search). `groups` is measured from YOU, like the saved lists: LinkedIn only knows the groups your own account has JOINED, so it works only on your OWN Sales Navigator seat and is otherwise refused, rather than answered about a different audience. To reach the people in a group, use `group_members` instead — it reads the group’s own member list on your own seat: any public group, or a members-only one your seat has joined."},"query":{"type":"string","minLength":1,"maxLength":256,"description":"The value as a human-readable NAME (never an id). Phrase it the way LinkedIn names things — canonical industry names (\"Financial Services\", not \"fintech\"), real place names (\"Greater Madrid Metropolitan Area\" or the country). Resolution takes the best single typeahead match and echoes the resolved label back."},"mode":{"description":"\"include\" (default) requires the value; \"exclude\" filters it out.","type":"string","enum":["include","exclude"]}},"required":["type","query"]},"x-nestjs_zod-uses-3-point-1-syntax":true},"cursor":{"description":"Pass the cursor from a prior result to page. It continues only the exact search that made it: send it with the SAME category and filters as the first page, or it is refused.","type":"string","maxLength":65536,"x-nestjs_zod-uses-3-point-1-syntax":true},"limit":{"description":"Page size (max 100 for Sales Nav; default 10). One page costs one metered action WHATEVER its size, so raise it when you are filling a list rather than sampling.","type":"integer","minimum":1,"maximum":100,"x-nestjs_zod-uses-3-point-1-syntax":true},"firstName":{"type":"string","minLength":1,"maxLength":128,"x-nestjs_zod-uses-3-point-1-syntax":true},"lastName":{"type":"string","minLength":1,"maxLength":128,"x-nestjs_zod-uses-3-point-1-syntax":true},"role":{"description":"Current job-TITLE keywords (include/exclude) — the primary people filter. Use it for ALL title intent, NOT `keywords` and NOT `seniority`. Each include entry is a separate Boolean title clause LinkedIn ORs. Two kinds: (1) single-title pills — exact exec titles + founder, one entry per variant (e.g. \"CEO\",\"Chief Executive Officer\",\"Founder\",\"Fundador\"); (2) ONE seniority-block pill for broad leadership roles: a marker AND a parenthesized OR-list of role synonyms, e.g. `<<SENIORITY_BLOCK_EN>> AND (\"growth\" OR \"demand generation\")`. The marker (one of <<SENIORITY_BLOCK_EN>> / <<SENIORITY_BLOCK_ES_EN>> / <<SENIORITY_BLOCK_PT_EN>>, by language) expands server-side to a broad leadership OR-block so you recall heads/VPs/directors/managers without enumerating titles. See the playbook for the full recipe. MATCHING: a pill matches a SET OF WORDS, not a phrase, and it matches a person across ALL of their CURRENT jobs. When you also scope by company, only their position AT THAT COMPANY is returned — so a hit whose shown title does not match your pills is usually a CORRECT match through a side venture, not a broken filter. `Founder`/`Co-Founder`/`Owner`/`CEO` anchored to a company list therefore mean \"anyone there who founded or owns anything, anywhere\"; to find who RUNS a company use `Gerente General`/`Director General`/`Managing Director`/`Country Manager`, and `linkedin_fetch` to check one odd hit.","type":"object","properties":{"include":{"type":"array","items":{"type":"string","minLength":1}},"exclude":{"type":"array","items":{"type":"string","minLength":1}}},"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-self-required":false},"seniority":{"description":"LinkedIn's coarse seniority ladder (cxo, vice_president, director, senior, …) — NOT job titles. Use only when you mean a seniority level; pair with `role` for \"VP-level whose title contains X\".","type":"object","properties":{"include":{"type":"array","items":{"type":"string","enum":["owner/partner","cxo","vice_president","director","experienced_manager","entry_level_manager","strategic","senior","entry_level","in_training"]}},"exclude":{"type":"array","items":{"type":"string","enum":["owner/partner","cxo","vice_president","director","experienced_manager","entry_level_manager","strategic","senior","entry_level","in_training"]}}},"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-self-required":false},"tenure":{"description":"Years at the current company in their current role, as {min,max} ranges. Years MUST be LinkedIn bucket breakpoints — valid min: 0, 1, 3, 6, 10; valid max: 1, 2, 5, 10 (buckets <1, 1-2, 3-5, 6-10, 10+). Any other value (e.g. min:5 or min:2) is rejected. So \"5+ years\" → {min:6}; \"3+ years\" → {min:3}; \"3 to 5 years\" → {min:3,max:5}.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}},"x-nestjs_zod-uses-3-point-1-syntax":true},"tenureAtCompany":{"description":"Total years at the current company, as {min,max} ranges. Years MUST be LinkedIn bucket breakpoints — valid min: 0, 1, 3, 6, 10; valid max: 1, 2, 5, 10 (buckets <1, 1-2, 3-5, 6-10, 10+). Any other value (e.g. min:5 or min:2) is rejected. So \"5+ years\" → {min:6}; \"3+ years\" → {min:3}; \"3 to 5 years\" → {min:3,max:5}.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}},"x-nestjs_zod-uses-3-point-1-syntax":true},"tenureAtRole":{"description":"Years in the current role, as {min,max} ranges. Years MUST be LinkedIn bucket breakpoints — valid min: 0, 1, 3, 6, 10; valid max: 1, 2, 5, 10 (buckets <1, 1-2, 3-5, 6-10, 10+). Any other value (e.g. min:5 or min:2) is rejected. So \"5+ years\" → {min:6}; \"3+ years\" → {min:3}; \"3 to 5 years\" → {min:3,max:5}.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}},"x-nestjs_zod-uses-3-point-1-syntax":true},"companyHeadcount":{"description":"Size band of the person's current employer (people search). For a company's OWN size use `headcount`. Approximate \"startup\" with small buckets ([\"1-10\",\"11-50\",\"51-200\"]).","type":"array","items":{"type":"string","enum":["1-10","11-50","51-200","201-500","501-1000","1001-5000","5001-10000","10001+"]},"x-nestjs_zod-uses-3-point-1-syntax":true},"companyType":{"description":"Ownership type of the person's current employer (people search; e.g. privately_held, public_company). A companies search has no company-type facet.","type":"array","items":{"type":"string","enum":["public_company","privately_held","non_profit","educational_institution","partnership","self_employed","self_owned","government_agency"]},"x-nestjs_zod-uses-3-point-1-syntax":true},"profileLanguage":{"description":"Profile languages as 2-letter ISO codes (e.g. [\"en\",\"es\"]).","type":"array","items":{"type":"string","minLength":2,"maxLength":2},"x-nestjs_zod-uses-3-point-1-syntax":true},"networkDistance":{"description":"Connection degree from the operator: 1 / 2 / 3 — valid for BOTH people and companies. The \"GROUP\" value (shared group) is PEOPLE only; do not use it on a companies search. Answered only on the operator's OWN Sales Navigator seat. A degree IS a structured filter, so with the org's OWN Sales Navigator seat this is the right place to ask for \"my 1st-degree X\" — you keep the `role` / `seniority` precision classic search cannot express. Do NOT downgrade to `search_people` for it. `identity_get` says whether it can be answered here (`capabilities.viewerRelativeFilters`) — but do not gate the SEARCH on it: every other filter runs either way, so drop this one and keep the rest rather than leaving. When it cannot be answered the search says so and refuses THIS filter only; classic `search_people` with `networkDistance` is then the route, because it always runs on the operator's own seat. Never treat a Sales-Nav hit as connected: confirm before building a campaign that sends a direct message.","type":"array","items":{"anyOf":[{"type":"number","const":1},{"type":"number","const":2},{"type":"number","const":3},{"type":"string","const":"GROUP"}]},"x-nestjs_zod-uses-3-point-1-syntax":true},"connectionsOf":{"description":"LinkedIn provider ids (`ACoAA…`, from people.suggest — NOT numeric member ids) whose connections to search within. Aimed at someone you are NOT connected to, this returns your MUTUAL connections with them — the people who could introduce you — matching the `shared_connections_count` on their profile. `networkDistance` defaults to [1] and must STAY [1] for such a target: at any other degree Sales Navigator silently discards this filter and answers with your entire 2nd-degree network, which looks like a real result. The one exception is a target you ARE connected to, where [2] validly returns everyone they know that you do not. Looking for an introduction to someone? Read the `warm-intro` skill first — this filter is one step of it, and the rest decides which of the people it returns can actually help. Like `networkDistance` this is relative to the SEAT, and works here whenever `identity_get`'s `capabilities.viewerRelativeFilters` is true. When it is not, the search refuses THIS filter and nothing else — classic `search_people` is the route for the introduction hunt, while every other Sales Navigator filter still runs here.","type":"array","items":{"type":"string"},"x-nestjs_zod-uses-3-point-1-syntax":true},"changedJobs":{"description":"Spotlight: only people who recently changed jobs.","type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true},"postedOnLinkedin":{"type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true},"mentionedInNews":{"type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true},"followingYourCompany":{"type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true},"pastColleague":{"description":"Spotlight, relative to YOU: only people you actually worked with. Combined with `connectionsOf` it answers \"which of this person's connections are my own former colleagues\" — the shortest warm path there is. Expect a very small result; that is the point, not a misfire.","type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true},"sharedExperiences":{"description":"Spotlight, relative to YOU: only people who share a school, employer or group with you. The wider net beneath `pastColleague`, and the same combination with `connectionsOf` applies. The response never says WHICH experience is shared — membership in the result is the signal; load a profile to name the overlap.","type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true},"viewedYourProfileRecently":{"type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true},"viewedProfileRecently":{"type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true},"messagedRecently":{"type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true},"includeSavedLeads":{"type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true},"includeSavedAccounts":{"type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true},"hasJobOffers":{"description":"Company search: only companies currently hiring.","type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true},"headcount":{"description":"The company's OWN size band (companies search; the analog of people-search `companyHeadcount`). Approximate \"startup\" with small buckets ([\"1-10\",\"11-50\",\"51-200\"]).","type":"array","items":{"type":"string","enum":["1-10","11-50","51-200","201-500","501-1000","1001-5000","5001-10000","10001+"]},"x-nestjs_zod-uses-3-point-1-syntax":true},"headcountGrowth":{"description":"Company headcount growth rate as a {min,max} percentage range.","type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}},"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-self-required":false},"annualRevenue":{"description":"Company annual revenue {currency (ISO 4217), min, max} in millions. Both min AND max are required and MUST be breakpoints: 0, 0.2, 1, 2.5, 5, 10, 20, 50, 100, 500, 1000, 1001.","type":"object","properties":{"currency":{"type":"string","minLength":3,"maxLength":3},"min":{"type":"number"},"max":{"type":"number"}},"required":["currency","min","max"],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-self-required":false},"followersCount":{"description":"COMPANY followers only — a companies search. Search has no filter for a PERSON's followers; check that with the ICP. {min,max} ranges. Breakpoints — min: 1, 51, 101, 1001, 5001; max: 50, 100, 1000, 5000.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}},"x-nestjs_zod-uses-3-point-1-syntax":true},"fortune":{"description":"Fortune ranking {min,max} ranges (e.g. Fortune 500). Breakpoints — min: 0, 51, 101, 251; max: 50, 100, 250, 500.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}},"x-nestjs_zod-uses-3-point-1-syntax":true},"recentActivities":{"description":"Company signals: senior_leadership_changes and/or funding_events.","type":"array","items":{"type":"string","enum":["senior_leadership_changes","funding_events"]},"x-nestjs_zod-uses-3-point-1-syntax":true},"departmentHeadcount":{"type":"object","properties":{"department":{"type":"array","items":{"type":"string"}},"min":{"type":"number"},"max":{"type":"number"}},"required":["department"],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-self-required":false},"departmentHeadcountGrowth":{"type":"object","properties":{"department":{"type":"array","items":{"type":"string"}},"min":{"type":"number"},"max":{"type":"number"}},"required":["department"],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-self-required":false},"savedAccounts":{"type":"array","items":{"type":"string"},"x-nestjs_zod-uses-3-point-1-syntax":true},"savedSearchId":{"type":"string","pattern":"^\\d+$","x-nestjs_zod-uses-3-point-1-syntax":true},"recentSearchId":{"type":"string","pattern":"^\\d+$","x-nestjs_zod-uses-3-point-1-syntax":true},"lastViewedAt":{"type":"number","x-nestjs_zod-uses-3-point-1-syntax":true},"withinArea":{"type":"number","x-nestjs_zod-uses-3-point-1-syntax":true}}},"InviteSendDto":{"type":"object","properties":{"target":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"url","description":"Which form `value` takes. Exactly one form per call — pick the one you actually have rather than reshaping it."},"value":{"type":"string","minLength":1,"maxLength":512,"description":"A LinkedIn profile or company URL."},"kind":{"description":"What `value` names, when already known — set for you on targets read off a list row. Leave unset when addressing something by hand; `linkedin_fetch`'s own `kind` overrides it. Ignored on a URL, which already says what it points at.","type":"string","enum":["profile","company"]}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","const":"public_identifier","description":"Which form `value` takes. Exactly one form per call — pick the one you actually have rather than reshaping it."},"value":{"type":"string","minLength":1,"maxLength":512,"description":"The vanity slug (e.g. \"jane-doe\") or company universal name."},"kind":{"description":"What `value` names, when already known — set for you on targets read off a list row. Leave unset when addressing something by hand; `linkedin_fetch`'s own `kind` overrides it. Ignored on a URL, which already says what it points at.","type":"string","enum":["profile","company"]}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","const":"provider_id","description":"Which form `value` takes. Exactly one form per call — pick the one you actually have rather than reshaping it."},"value":{"type":"string","minLength":1,"maxLength":512,"description":"Unipile/LinkedIn internal id (e.g. \"ACoAAB…\" or the Sales-Nav \"ACwAAB…\")."},"kind":{"description":"What `value` names, when already known — set for you on targets read off a list row. Leave unset when addressing something by hand; `linkedin_fetch`'s own `kind` overrides it. Ignored on a URL, which already says what it points at.","type":"string","enum":["profile","company"]}},"required":["type","value"]}],"description":"Who this acts on — one LinkedIn person or company, named by URL, vanity slug, or provider id.","x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"note":{"description":"The connection-request note, up to 300 characters. Omit it entirely for a note-less invite, which is valid and often accepts better.","type":"string","maxLength":300,"x-nestjs_zod-uses-3-point-1-syntax":true}},"required":["target"]},"MessageSendDto":{"type":"object","properties":{"target":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"url","description":"Which form `value` takes. Exactly one form per call — pick the one you actually have rather than reshaping it."},"value":{"type":"string","minLength":1,"maxLength":512,"description":"A LinkedIn profile or company URL."},"kind":{"description":"What `value` names, when already known — set for you on targets read off a list row. Leave unset when addressing something by hand; `linkedin_fetch`'s own `kind` overrides it. Ignored on a URL, which already says what it points at.","type":"string","enum":["profile","company"]}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","const":"public_identifier","description":"Which form `value` takes. Exactly one form per call — pick the one you actually have rather than reshaping it."},"value":{"type":"string","minLength":1,"maxLength":512,"description":"The vanity slug (e.g. \"jane-doe\") or company universal name."},"kind":{"description":"What `value` names, when already known — set for you on targets read off a list row. Leave unset when addressing something by hand; `linkedin_fetch`'s own `kind` overrides it. Ignored on a URL, which already says what it points at.","type":"string","enum":["profile","company"]}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","const":"provider_id","description":"Which form `value` takes. Exactly one form per call — pick the one you actually have rather than reshaping it."},"value":{"type":"string","minLength":1,"maxLength":512,"description":"Unipile/LinkedIn internal id (e.g. \"ACoAAB…\" or the Sales-Nav \"ACwAAB…\")."},"kind":{"description":"What `value` names, when already known — set for you on targets read off a list row. Leave unset when addressing something by hand; `linkedin_fetch`'s own `kind` overrides it. Ignored on a URL, which already says what it points at.","type":"string","enum":["profile","company"]}},"required":["type","value"]}],"description":"Who this acts on — one LinkedIn person or company, named by URL, vanity slug, or provider id.","x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"text":{"type":"string","minLength":1,"maxLength":8000,"description":"The message body, exactly as it will be sent. Nothing rewrites it — and nothing splits it either: a line of `---` goes out as those characters, not as a bubble break. Bubbles are a CAMPAIGN message step; this tool sends one message.","x-nestjs_zod-uses-3-point-1-syntax":true},"attachments":{"maxItems":5,"type":"array","items":{"anyOf":[{"type":"object","properties":{"fileName":{"type":"string","minLength":1,"maxLength":255,"description":"The file name, with its extension — what the recipient sees."},"mimeType":{"type":"string","minLength":1,"maxLength":255,"description":"The file's MIME type, e.g. `image/png` or `application/pdf`."},"dataBase64":{"type":"string","minLength":1,"maxLength":4194304,"description":"The file itself, base64-encoded. Use this OR `url`, never both."}},"required":["fileName","mimeType","dataBase64"],"additionalProperties":false},{"type":"object","properties":{"fileName":{"type":"string","minLength":1,"maxLength":255,"description":"The file name, with its extension — what the recipient sees."},"mimeType":{"type":"string","minLength":1,"maxLength":255,"description":"The file's MIME type, e.g. `image/png` or `application/pdf`."},"url":{"type":"string","minLength":1,"maxLength":2048,"format":"uri","description":"An https address we fetch server-side. Use this OR `dataBase64`, never both. Reach for it when you cannot produce base64."}},"required":["fileName","mimeType","url"],"additionalProperties":false}]},"x-nestjs_zod-uses-3-point-1-syntax":true}},"required":["target","text"]},"MessageEditDto":{"type":"object","properties":{"messageId":{"type":"string","minLength":1,"maxLength":512},"text":{"type":"string","minLength":1,"maxLength":8000,"description":"The replacement body. It overwrites the message for the recipient too."}},"required":["messageId","text"]},"MessageDeleteDto":{"type":"object","properties":{"messageId":{"type":"string","minLength":1,"maxLength":512}},"required":["messageId"]},"InmailSendDto":{"type":"object","properties":{"target":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"url","description":"Which form `value` takes. Exactly one form per call — pick the one you actually have rather than reshaping it."},"value":{"type":"string","minLength":1,"maxLength":512,"description":"A LinkedIn profile or company URL."},"kind":{"description":"What `value` names, when already known — set for you on targets read off a list row. Leave unset when addressing something by hand; `linkedin_fetch`'s own `kind` overrides it. Ignored on a URL, which already says what it points at.","type":"string","enum":["profile","company"]}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","const":"public_identifier","description":"Which form `value` takes. Exactly one form per call — pick the one you actually have rather than reshaping it."},"value":{"type":"string","minLength":1,"maxLength":512,"description":"The vanity slug (e.g. \"jane-doe\") or company universal name."},"kind":{"description":"What `value` names, when already known — set for you on targets read off a list row. Leave unset when addressing something by hand; `linkedin_fetch`'s own `kind` overrides it. Ignored on a URL, which already says what it points at.","type":"string","enum":["profile","company"]}},"required":["type","value"]},{"type":"object","properties":{"type":{"type":"string","const":"provider_id","description":"Which form `value` takes. Exactly one form per call — pick the one you actually have rather than reshaping it."},"value":{"type":"string","minLength":1,"maxLength":512,"description":"Unipile/LinkedIn internal id (e.g. \"ACoAAB…\" or the Sales-Nav \"ACwAAB…\")."},"kind":{"description":"What `value` names, when already known — set for you on targets read off a list row. Leave unset when addressing something by hand; `linkedin_fetch`'s own `kind` overrides it. Ignored on a URL, which already says what it points at.","type":"string","enum":["profile","company"]}},"required":["type","value"]}],"description":"Who this acts on — one LinkedIn person or company, named by URL, vanity slug, or provider id.","x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"subject":{"description":"The InMail subject line — the one thing that decides whether it is opened.","type":"string","maxLength":200,"x-nestjs_zod-uses-3-point-1-syntax":true},"text":{"type":"string","minLength":1,"maxLength":8000,"description":"The InMail body, as it will be sent. Over MCP, em dashes and curly quotes become plain punctuation; nothing else rewrites it.","x-nestjs_zod-uses-3-point-1-syntax":true},"attachments":{"maxItems":5,"type":"array","items":{"anyOf":[{"type":"object","properties":{"fileName":{"type":"string","minLength":1,"maxLength":255,"description":"The file name, with its extension — what the recipient sees."},"mimeType":{"type":"string","minLength":1,"maxLength":255,"description":"The file's MIME type, e.g. `image/png` or `application/pdf`."},"dataBase64":{"type":"string","minLength":1,"maxLength":4194304,"description":"The file itself, base64-encoded. Use this OR `url`, never both."}},"required":["fileName","mimeType","dataBase64"],"additionalProperties":false},{"type":"object","properties":{"fileName":{"type":"string","minLength":1,"maxLength":255,"description":"The file name, with its extension — what the recipient sees."},"mimeType":{"type":"string","minLength":1,"maxLength":255,"description":"The file's MIME type, e.g. `image/png` or `application/pdf`."},"url":{"type":"string","minLength":1,"maxLength":2048,"format":"uri","description":"An https address we fetch server-side. Use this OR `dataBase64`, never both. Reach for it when you cannot produce base64."}},"required":["fileName","mimeType","url"],"additionalProperties":false}]},"x-nestjs_zod-uses-3-point-1-syntax":true}},"required":["target","text"]},"SetChannelActionLimitDto":{"type":"object","properties":{"type":{"type":"string","enum":["profile.fetch","company.fetch","profile.posts","profile.comments","profile.reactions","company.posts","search.people","search.companies","search.sales_navigator","search.recruiter","recruiter.saved_searches","search.posts","search.jobs","relations.list","post.fetch","post.reactions","post.comments","event.attendees","profile.viewers","newsletter.subscribers","group.members","invitations.received","company.followers","filter.resolve","invite.send","invite.cancel","message.send","message.edit","message.delete","inmail.send","post.react","post.comment","profile.view","profile.follow","relation.remove","profile.edit"],"x-nestjs_zod-uses-3-point-1-syntax":true},"limit":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true}},"required":["type","limit"]},"CampaignCreateDto":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200,"description":"The campaign's name, for the operator to recognise it in a list. Not seen by any lead."},"channelAccountIds":{"minItems":1,"type":"array","items":{"type":"string","minLength":1},"description":"The sending seats — connected LinkedIn accounts in this org, one or more. Each new lead goes to one of them and hears from that seat for the whole sequence; every seat enrolls up to the campaign's `dailyEnrollmentLimit` a day, so the campaign's daily volume grows with each seat. Duplicates collapse. Get the ids from `seat_list` — the seats that can send right now. (`identity_get`'s `seatId` names your own account even when it is not sendable, so a campaign built on it is created, publishes fine, and is then refused by `campaign_activate` with `sender_not_connected`.)"},"icpId":{"description":"The ICP to gate enrollment on. There is no default and nothing is selected for you: omitting this creates an UNGATED campaign. ASK the operator before calling, every time — never decide it for them and never leave it unasked. Show them their ICPs (`icp_list`) and say in one line what each answer means: gated, and only people who qualify for that ICP are contacted while everyone else on their lists is skipped and never messaged; ungated, and everyone on their lists is contacted, except the people its Enrollment Filter skips (a new campaign skips anyone your seats are already in touch with: a conversation, or an invitation, message or comment a campaign sent). \"No gate\" is a fine answer, but it has to be one they gave.","type":"string","minLength":1}},"required":["name","channelAccountIds"]},"CampaignAudienceLeadsDto":{"type":"object","properties":{"leadListIds":{"minItems":1,"maxItems":50,"type":"array","items":{"type":"string","minLength":1}},"q":{"type":"string","minLength":1,"maxLength":200},"cursor":{"type":"string","maxLength":65536},"limit":{"default":25,"type":"integer","minimum":1,"maximum":100}},"required":["leadListIds"]},"CampaignPreviewDraftDto":{"type":"object","properties":{"leadIds":{"minItems":1,"maxItems":5,"type":"array","items":{"type":"string","minLength":1},"x-nestjs_zod-uses-3-point-1-syntax":true},"nodeType":{"type":"string","enum":["send_invite","send_message","send_inmail","comment_on_post"],"x-nestjs_zod-uses-3-point-1-syntax":true},"config":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-self-required":true},"channelAccountId":{"type":"string","minLength":1,"x-nestjs_zod-uses-3-point-1-syntax":true},"leadListIds":{"minItems":1,"maxItems":50,"type":"array","items":{"type":"string","minLength":1},"x-nestjs_zod-uses-3-point-1-syntax":true}},"required":["leadIds","nodeType","config","channelAccountId","leadListIds"]},"CampaignUpdateDto":{"type":"object","properties":{"name":{"description":"The campaign's name, for the operator to recognise it. Not seen by any lead.","type":"string","minLength":1,"maxLength":200,"x-nestjs_zod-uses-3-point-1-syntax":true},"sendWindow":{"description":"When sends may fire. The ONE piece of configuration with no default — `campaign_activate` is blocked with `no_send_window` until it exists. Monday-Friday 12:00-18:00 in the operator's own zone is a sane start.","type":"object","properties":{"days":{"minItems":1,"maxItems":7,"type":"array","items":{"type":"integer","minimum":0,"maximum":6},"description":"Weekdays sends may fire, 0 = Sunday to 6 = Saturday. At least one, no duplicates."},"startHour":{"type":"integer","minimum":0,"maximum":23,"description":"First hour sends may fire, 0-23, in `timeZone`. Must be before `endHour`."},"endHour":{"type":"integer","minimum":0,"maximum":23,"description":"Last hour sends may fire, 0-23, in `timeZone`. Must be after `startHour`."},"timeZone":{"description":"IANA zone the hours are read in, e.g. `America/Argentina/Buenos_Aires`. ASK the operator rather than assuming: a valid zone that is not theirs is accepted silently and sends at the wrong hour every day, with nothing to flag it.","type":"string","minLength":1,"maxLength":64}},"required":["days","startHour","endHour","timeZone"],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-self-required":false},"autonomy":{"description":"`autopilot` (the default) fires each send on schedule. `manual` parks EVERY send for the operator to approve first, so a manual campaign looks active and sends nothing until someone works the queue.","type":"string","enum":["manual","autopilot"],"x-nestjs_zod-uses-3-point-1-syntax":true},"allowsReEntry":{"description":"May a person enter this campaign more than once? `false` (the default) means someone who finished it never comes back — the rule every campaign has always had. `true` lets them re-enter later, which is what a nurture campaign is for. It never permits two messages at once: one live run per person, always, whatever this says.","type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true},"sendFromOwner":{"description":"With several sending seats: send each lead from its OWNER's seat. `true` means a lead whose owner has a working seat in this campaign is contacted from that seat only (it waits for that seat's daily room); a lead with no owner, or whose owner's seat is disconnected, removed or gone, goes to whichever seat has room. `false` (the default) ignores owners: every seat takes the oldest leads. No effect with one seat.","type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true},"status":{"description":"Only `draft` or `archived`. To start or stop a campaign use `campaign_activate` / `campaign_pause`, which check the preconditions this does not.","type":"string","enum":["draft","archived"],"x-nestjs_zod-uses-3-point-1-syntax":true},"dailyEnrollmentLimit":{"description":"The DEFAULT new leads per day, per sender, 1-200 (default 25): every sender without a limit of its own enrolls up to this many a day, so the campaign's day is the sum over its senders. Caps the START of new runs, not sends — the org's own per-seat limits still apply on top. Senders are added, removed and given their own limit with `campaign_seat_add` / `campaign_seat_remove` / `campaign_seat_update`.","type":"integer","minimum":1,"maximum":200,"x-nestjs_zod-uses-3-point-1-syntax":true},"priority":{"description":"Which campaign this LinkedIn account serves first when two of them are due on the same day. 0 is highest. Lower sorts first, matching every other priority in Kairon. `null` clears it — no priority, served after Low; omitted leaves it unchanged. It is an ORDER, never an allowance: it does not change how many leads any campaign enrols (`dailyEnrollmentLimit` does that), and it never moves a send that is already scheduled.","anyOf":[{"type":"integer","minimum":0,"maximum":3},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"endsOn":{"description":"The day this campaign stops, `YYYY-MM-DD`, in its send window's time zone. On that day it pauses itself (reason `ended`) and nothing more goes out — no new leads, no follow-ups. Today counts: setting today or an earlier day on a running campaign pauses it AT ONCE, so to make today the last sending day, pass tomorrow. Use it for a campaign tied to a dated event. `null` clears it; omitted leaves it unchanged. To run it again after it ended, move the date later or clear it, then resume.","anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"enrollmentFilter":{"description":"Which prior-contact history may enroll, and whose. A new campaign starts on `new` across the `org`: it skips anyone who already has a conversation with any seat of this org, whoever wrote first, and anyone a Kairon campaign already sent a message, a comment or an invitation WITH a note to (a note-less invitation said nothing, so someone who accepts one stays `new`). Widen it only for a campaign meant for people already contacted: add `unanswered` for a re-engagement; add `in_conversation` only when every message is written for someone already talking to you, never under a fixed opening line (that greets them as a stranger). A narrowed filter SKIPS the people it excludes rather than queueing them, so it is a common reason a big audience enrolls almost nobody.","type":"object","properties":{"buckets":{"minItems":1,"type":"array","items":{"type":"string","enum":["new","unanswered","in_conversation"]},"description":"Which contact-history buckets may enroll: `new` (no conversation either way, and nothing a Kairon campaign sent), `unanswered` (we messaged, no reply), `in_conversation` (they wrote to us). Unique, at least one. All three means enroll everyone. Anyone outside the selected buckets is skipped, not queued, so a narrow set is why a large audience enrolls almost nobody."},"scope":{"type":"string","enum":["seat","org"],"description":"Whose prior-contact history is read: `seat` (this campaign's sending seat) or `org` (every LinkedIn seat). Copying a `seat` filter onto a DIFFERENT seat changes what it means — the new seat's history is empty, so people the original filter excluded now enroll."}},"required":["buckets","scope"],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-self-required":false},"icpId":{"description":"The ICP that gates enrollment. `null` clears it (no ICP check); omitted leaves it unchanged. Must be an ICP in this org. Leads that fail it are marked Skipped, never messaged.","anyOf":[{"type":"string","minLength":1},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"stopOnReply":{"description":"Default `true` — a reply halts that person's run so nothing follows a real conversation. `false` keeps the sequence going after they answer; set it only when the operator asked.","type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true},"connectionDegree":{"description":"Whether the sender's existing LinkedIn connection matters. `any` (the default) ignores it. `only_first` enrolls ONLY people the sender is already connected to. `exclude_first` enrolls only people they are NOT connected to — the usual choice for cold outreach that opens with an invite. Anything but `any` costs one extra LinkedIn read per candidate, and skips the people it excludes rather than queueing them.","type":"string","enum":["any","only_first","exclude_first"],"x-nestjs_zod-uses-3-point-1-syntax":true},"stopOnCompanyReply":{"description":"Whether one person answering stops their colleagues. `off` (the default) works every lead on their own merits. `any_reply` stops the rest of a company once anyone there answers THIS campaign. `interested` stops it only when the answer was an interested one, so a colleague's \"no thanks\" leaves the others working. Colleagues are matched on their LinkedIn employer, so someone whose employer Kairon has never seen is never stopped by it. It stops people waiting to enter AND people already inside — but never someone who has written to you, whose conversation always continues.","type":"string","enum":["off","any_reply","interested"],"x-nestjs_zod-uses-3-point-1-syntax":true},"confirmCancelRuns":{"description":"Required to archive a campaign that still has active runs — it CANCELS every one of them. Archiving is refused without it.","type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true}}},"CampaignInitiativeSetDto":{"type":"object","properties":{"initiativeId":{"anyOf":[{"type":"string"},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true}},"required":["initiativeId"]},"CampaignBindListDto":{"type":"object","properties":{"leadListId":{"type":"string","minLength":1}},"required":["leadListId"]},"CampaignPreviewDto":{"type":"object","properties":{"leadIds":{"minItems":1,"maxItems":5,"type":"array","items":{"type":"string","minLength":1},"x-nestjs_zod-uses-3-point-1-syntax":true},"nodeType":{"type":"string","enum":["send_invite","send_message","send_inmail","comment_on_post"],"x-nestjs_zod-uses-3-point-1-syntax":true},"config":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-self-required":true}},"required":["leadIds","nodeType","config"]},"CampaignRehearsalOpeningDto":{"type":"object","properties":{"nodeKey":{"type":"string","minLength":1},"leadId":{"type":"string","minLength":1},"graph":{"default":"draft","type":"string","enum":["published","draft"]}},"required":["nodeKey","leadId"]},"CampaignRehearsalTurnDto":{"type":"object","properties":{"nodeKey":{"type":"string","minLength":1,"x-nestjs_zod-uses-3-point-1-syntax":true},"graph":{"default":"draft","type":"string","enum":["published","draft"],"x-nestjs_zod-uses-3-point-1-syntax":true},"transcript":{"minItems":1,"maxItems":60,"type":"array","items":{"type":"object","properties":{"from":{"type":"string","enum":["them","us"]},"text":{"type":"string","minLength":1,"maxLength":8000},"files":{"maxItems":5,"type":"array","items":{"type":"object","properties":{"storageKey":{"type":"string","maxLength":512,"pattern":"^step-attachments\\/.*"},"fileName":{"type":"string","minLength":1,"maxLength":255},"mimeType":{"type":"string","minLength":1,"maxLength":255},"byteSize":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["storageKey","fileName","mimeType","byteSize"],"additionalProperties":false}}},"required":["from","text"]},"x-nestjs_zod-uses-3-point-1-syntax":true}},"required":["nodeKey","transcript"]},"CampaignDraftDto":{"type":"object","properties":{"nodes":{"maxItems":100,"type":"array","items":{"oneOf":[{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80,"description":"A stable id you choose for this step; edges reference it by this name. Unique within the graph. Reuse the same key on a later `campaign_set_graph` and the step keeps its position and any config field you do not mention."},"type":{"type":"string","const":"send_invite","description":"Which kind of step this is. It decides the shape of `config`, and which outcome edges the step may route on."},"config":{"type":"object","properties":{"note":{"default":"","description":"Invite note, and the seed when `draftMode` is `ai_template`. In `ai_template` this seed is authoritative: the writer reproduces it word for word and adds nothing, so EVERY per-lead detail must sit inside a `{{...}}` slot written here. A seed with no slots sends the identical message to every lead. A slot holds a description of the fact to write there, phrased as a clause — e.g. `{{one short clause, 8-14 words, on what their company does}}`. Custom list columns reach a message two ways: `{{@columnName}}` sends that column's value word for word, and a normal AI slot that mentions a column can use it as a fact, written in the writer's own words. At publish it must be ≤300 characters, or ≤250 once it contains any `{{token}}` (the braces count), leaving room for what the token expands to. Over that, publish fails with `invite_note_too_long`. A note needs a sender with LinkedIn Premium or Sales Navigator (`canSendInviteNote` on `seat_list`); on any other seat leave it empty — `campaign_set_graph` refuses a note there.","type":"string","maxLength":2000},"draftMode":{"description":"How the copy is produced. `template`: sent as written — only allowlisted `{{variables}}` and per-lead `{{@slots}}` are substituted, no AI. `ai_template`: the AI personalizes YOUR seed, filling its `{{described slots}}` and nothing else. Absent means `template`.","type":"string","enum":["template","ai_template"]},"instruction":{"description":"Optional note on tone and register, layered on the seed — NOT where the copy comes from. It reaches the writer AFTER the rule that says to keep the seed as written, so anything it asks for that the seed has no `{{slot}}` for is silently ignored: \"personalize the opening with their company\" does nothing unless a slot sits there. Write the copy in the seed.","type":"string","maxLength":4000},"language":{"description":"Force every message on this step into one language, or set 'auto' so each lead is written to in their OWN language, translating your seed faithfully. OMIT IT and the step uses the default language the sender chose in their settings, or 'auto' when they chose none — which is usually what you want. This rule outranks the seed's original language.","anyOf":[{"type":"string","const":"auto"},{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"]}]},"localization":{"description":"The seed translated into other languages, one per ISO 639-1 code, each keeping every `{{…}}` slot byte-exact and every `---` line. Kairon writes a language here the first time it drafts a lead in it; you may edit any entry and it is then used as written for every later lead in that language. Leave it out to let Kairon translate.","type":"object","properties":{"seedHash":{"type":"string","minLength":1,"description":"Hash of the seed text these translations were made for. Kairon sets it; when the seed changes, the whole object goes stale and is rebuilt. Copy it through unchanged."},"seedLanguage":{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"],"description":"The ISO 639-1 code of the language the seed itself is written in, detected once by Kairon."},"translations":{"type":"object","propertyNames":{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"]},"additionalProperties":{"type":"string","minLength":1},"description":"One translated seed per ISO 639-1 code. Each must keep every `{{…}}` slot byte-exact and in order, and the same number of `---` lines, or publish refuses it."}},"required":["seedHash","seedLanguage","translations"]},"reviewBeforeSend":{"description":"Default false. True holds every send this step drafts for the operator to approve, even when the campaign is on autopilot. Nothing is scheduled until they approve it.","type":"boolean"},"verifyBeforeSend":{"description":"DEPRECATED, and accepted only so campaigns published before the rename still parse. Set `reviewBeforeSend` instead; if both are present the new one wins.","type":"boolean"},"adaptToCulture":{"description":"Retired: accepted for old steps and ignored. Do not send it.","type":"boolean"}},"additionalProperties":false,"description":"Settings for this step type. The fields differ per `type`."},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80,"description":"A stable id you choose for this step; edges reference it by this name. Unique within the graph. Reuse the same key on a later `campaign_set_graph` and the step keeps its position and any config field you do not mention."},"type":{"type":"string","const":"wait_connection_accepted","description":"Which kind of step this is. It decides the shape of `config`, and which outcome edges the step may route on."},"config":{"type":"object","properties":{"timeoutDays":{"type":"integer","minimum":1,"maximum":7,"description":"How many whole days to wait for the invite to be accepted, 1-7. On expiry the run leaves by the `timeout` edge; wire one or those leads stop here."},"withdrawOnTimeout":{"description":"Withdraw the pending invite when the wait times out. Default true — it reclaims LinkedIn pending-invite quota, which is capped. Set false to leave the invite standing, so someone who accepts weeks later still lands on the `accepted` edge of a later wait.","type":"boolean"}},"required":["timeoutDays"],"additionalProperties":false,"description":"Settings for this step type. The fields differ per `type`."},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80,"description":"A stable id you choose for this step; edges reference it by this name. Unique within the graph. Reuse the same key on a later `campaign_set_graph` and the step keeps its position and any config field you do not mention."},"type":{"type":"string","const":"delay","description":"Which kind of step this is. It decides the shape of `config`, and which outcome edges the step may route on."},"config":{"type":"object","properties":{"value":{"type":"integer","minimum":1,"maximum":10080,"description":"How long to pause before the next step, counted in `unit`. The total may not exceed 7 days."},"unit":{"type":"string","enum":["minutes","hours","days"],"description":"The unit `value` is counted in. Use `minutes`/`hours` for the hot follow-up right after an invite is accepted, `days` for a nurture gap. Counted in real time, not send windows — the next step then waits for the window to open."}},"required":["value","unit"],"additionalProperties":false,"description":"Settings for this step type. The fields differ per `type`."},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80,"description":"A stable id you choose for this step; edges reference it by this name. Unique within the graph. Reuse the same key on a later `campaign_set_graph` and the step keeps its position and any config field you do not mention."},"type":{"type":"string","const":"wait_reply","description":"Which kind of step this is. It decides the shape of `config`, and which outcome edges the step may route on."},"config":{"type":"object","properties":{"value":{"type":"integer","minimum":1,"maximum":10080,"description":"How long to wait for the lead to reply, counted in `unit`. The total may not exceed 7 days."},"unit":{"type":"string","enum":["minutes","hours","days"],"description":"The unit `value` is counted in. `minutes`/`hours` for a same-day nudge, `days` for a normal follow-up gap."}},"required":["value","unit"],"additionalProperties":false,"description":"Settings for this step type. The fields differ per `type`."},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80,"description":"A stable id you choose for this step; edges reference it by this name. Unique within the graph. Reuse the same key on a later `campaign_set_graph` and the step keeps its position and any config field you do not mention."},"type":{"type":"string","const":"agentic_reply","description":"Which kind of step this is. It decides the shape of `config`, and which outcome edges the step may route on."},"config":{"type":"object","properties":{"instruction":{"type":"string","minLength":1,"maxLength":8000,"description":"REQUIRED. The goal — what the operator wants out of this conversation, in one line. E.g. \"Get them to book a call with me.\" or \"Find out if they own hiring, or who does.\" This is the only field the step needs: the agent chooses its own wording and works out for itself when the conversation is finished. It does NOT invent substance — anything it cannot answer straight from this goal and `additionalInstructions` is handed to a human instead, so the more `additionalInstructions` says, the fewer turns come back to the operator."},"additionalInstructions":{"default":"","description":"Optional, and it decides how much the agent can answer on its own: it hands a turn to a human whenever the answer is not straightforward from the goal plus this field. Put here the facts it may use (dates, prices, links — STATE EVERY ONE, it must never state a fact you did not give it), when to treat the conversation as finished, what to hand straight to a human whatever it knows, how to answer an objection you expect, and any other steering. E.g. \"The event is Tuesday 12 March, 6pm, at our office. If they ask who else is going, hand it to me. If they say it is too far, offer the recording.\"","type":"string","maxLength":8000},"silence":{"default":{"value":7,"unit":"days"},"description":"How long the agent keeps listening — for her FIRST reply, and after each of its own answers. She goes quiet past this and the step leaves by `no_reply`, so a follow-up can still chase her.","type":"object","properties":{"value":{"type":"integer","minimum":1,"maximum":10080,"description":"How long to keep listening for her next message, counted in `unit`. The total may not exceed 7 days."},"unit":{"type":"string","enum":["minutes","hours","days"],"description":"The unit `value` is counted in."}},"required":["value","unit"]},"maxTurns":{"description":"How many times the agent may answer before it hands off for good and the run ends. Defaults to 10.","type":"integer","minimum":1,"maximum":20},"attachments":{"description":"Files the agent may send with an answer when they fit the conversation — each at most once per conversation. Say in the instruction when to send which. Images and PDFs; on LinkedIn also one voice note and one video.","maxItems":5,"type":"array","items":{"type":"object","properties":{"storageKey":{"type":"string","maxLength":512,"pattern":"^step-attachments\\/.*"},"fileName":{"type":"string","minLength":1,"maxLength":255},"mimeType":{"type":"string","minLength":1,"maxLength":255},"byteSize":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["storageKey","fileName","mimeType","byteSize"],"additionalProperties":false}}},"required":["instruction"],"additionalProperties":false,"description":"Settings for this step type. The fields differ per `type`."},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80,"description":"A stable id you choose for this step; edges reference it by this name. Unique within the graph. Reuse the same key on a later `campaign_set_graph` and the step keeps its position and any config field you do not mention."},"type":{"type":"string","const":"send_message","description":"Which kind of step this is. It decides the shape of `config`, and which outcome edges the step may route on."},"config":{"type":"object","properties":{"body":{"default":"","description":"The message. In `ai_template` this seed is authoritative: the writer reproduces it word for word and adds nothing, so EVERY per-lead detail must sit inside a `{{...}}` slot written here. A seed with no slots sends the identical message to every lead. A slot holds a description of the fact to write there, phrased as a clause — e.g. `{{one short clause, 8-14 words, on what their company does}}`. Custom list columns reach a message two ways: `{{@columnName}}` sends that column's value word for word, and a normal AI slot that mentions a column can use it as a fact, written in the writer's own words. To send this as SEVERAL messages rather than one, separate them with a line containing only `---`. Each part arrives as its own LinkedIn message a couple of seconds later, in the same conversation — what a person does when they type a short opener and then the reason they wrote. The whole thing still counts as ONE send against the daily limit. This is the same thing the \"Add bubble\" button does in the campaign editor.","type":"string","maxLength":8000},"draftMode":{"description":"How the copy is produced. `template`: sent as written — only allowlisted `{{variables}}` and per-lead `{{@slots}}` are substituted, no AI. `ai_template`: the AI personalizes YOUR seed, filling its `{{described slots}}` and nothing else. Absent means `template`.","type":"string","enum":["template","ai_template"]},"instruction":{"description":"Optional note on tone and register, layered on the seed — NOT where the copy comes from. It reaches the writer AFTER the rule that says to keep the seed as written, so anything it asks for that the seed has no `{{slot}}` for is silently ignored: \"personalize the opening with their company\" does nothing unless a slot sits there. Write the copy in the seed.","type":"string","maxLength":4000},"language":{"description":"Force every message on this step into one language, or set 'auto' so each lead is written to in their OWN language, translating your seed faithfully. OMIT IT and the step uses the default language the sender chose in their settings, or 'auto' when they chose none — which is usually what you want. This rule outranks the seed's original language.","anyOf":[{"type":"string","const":"auto"},{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"]}]},"localization":{"description":"The seed translated into other languages, one per ISO 639-1 code, each keeping every `{{…}}` slot byte-exact and every `---` line. Kairon writes a language here the first time it drafts a lead in it; you may edit any entry and it is then used as written for every later lead in that language. Leave it out to let Kairon translate.","type":"object","properties":{"seedHash":{"type":"string","minLength":1,"description":"Hash of the seed text these translations were made for. Kairon sets it; when the seed changes, the whole object goes stale and is rebuilt. Copy it through unchanged."},"seedLanguage":{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"],"description":"The ISO 639-1 code of the language the seed itself is written in, detected once by Kairon."},"translations":{"type":"object","propertyNames":{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"]},"additionalProperties":{"type":"string","minLength":1},"description":"One translated seed per ISO 639-1 code. Each must keep every `{{…}}` slot byte-exact and in order, and the same number of `---` lines, or publish refuses it."}},"required":["seedHash","seedLanguage","translations"]},"reviewBeforeSend":{"description":"Default false. True holds every send this step drafts for the operator to approve, even when the campaign is on autopilot. Nothing is scheduled until they approve it.","type":"boolean"},"verifyBeforeSend":{"description":"DEPRECATED, and accepted only so campaigns published before the rename still parse. Set `reviewBeforeSend` instead; if both are present the new one wins.","type":"boolean"},"adaptToCulture":{"description":"Retired: accepted for old steps and ignored. Do not send it.","type":"boolean"},"condition":{"description":"Only send when one of their own recent posts meets this test - e.g. \"a new job or a promotion\". The newest post that meets it becomes what the message refers to; a post that is bad news for its author never meets it. When none does, the step is SKIPPED and the lead moves on; nothing is sent. Omit it and the message sends as usual.","type":"string","maxLength":1000},"maxPostAgeDays":{"description":"With a condition: Only consider their own posts from the last this-many days, 1-90. Defaults to 90. In a loop, the step also only considers posts published after it last acted on a post, or last checked and found none that met its condition.","type":"integer","minimum":1,"maximum":90},"bySender":{"description":"Optional per-sender text, keyed by the sender's user id (`seat_list` → `ownerUserId`). A lead sent by that sender gets this version; every other sender gets the step's own `body`. Same draft mode and language as the step.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"object","properties":{"body":{"type":"string","maxLength":8000,"description":"This sender's message, in place of the step's `body`. In `ai_template` this seed is authoritative: the writer reproduces it word for word and adds nothing, so EVERY per-lead detail must sit inside a `{{...}}` slot written here. A seed with no slots sends the identical message to every lead. A slot holds a description of the fact to write there, phrased as a clause — e.g. `{{one short clause, 8-14 words, on what their company does}}`."},"instruction":{"description":"This sender's note, in place of the step's `instruction`. Optional note on tone and register, layered on the seed — NOT where the copy comes from. It reaches the writer AFTER the rule that says to keep the seed as written, so anything it asks for that the seed has no `{{slot}}` for is silently ignored: \"personalize the opening with their company\" does nothing unless a slot sits there. Write the copy in the seed.","type":"string","maxLength":4000},"localization":{"description":"The seed translated into other languages, one per ISO 639-1 code, each keeping every `{{…}}` slot byte-exact and every `---` line. Kairon writes a language here the first time it drafts a lead in it; you may edit any entry and it is then used as written for every later lead in that language. Leave it out to let Kairon translate.","type":"object","properties":{"seedHash":{"type":"string","minLength":1,"description":"Hash of the seed text these translations were made for. Kairon sets it; when the seed changes, the whole object goes stale and is rebuilt. Copy it through unchanged."},"seedLanguage":{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"],"description":"The ISO 639-1 code of the language the seed itself is written in, detected once by Kairon."},"translations":{"type":"object","propertyNames":{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"]},"additionalProperties":{"type":"string","minLength":1},"description":"One translated seed per ISO 639-1 code. Each must keep every `{{…}}` slot byte-exact and in order, and the same number of `---` lines, or publish refuses it."}},"required":["seedHash","seedLanguage","translations"]}},"required":["body"]}},"attachments":{"description":"Files sent with this step to every lead it reaches: images and PDFs, plus one voice note and one video on a LinkedIn message.","maxItems":5,"type":"array","items":{"type":"object","properties":{"storageKey":{"type":"string","maxLength":512,"pattern":"^step-attachments\\/.*"},"fileName":{"type":"string","minLength":1,"maxLength":255},"mimeType":{"type":"string","minLength":1,"maxLength":255},"byteSize":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["storageKey","fileName","mimeType","byteSize"],"additionalProperties":false}},"attachmentsBySender":{"description":"Optional per-sender files, keyed by the sender's user id (`seat_list` → `ownerUserId`): that sender's leads get these files instead of the step's `attachments` (an empty list sends none). Read-only notes — add files through `attachments` first.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"maxItems":5,"type":"array","items":{"type":"object","properties":{"storageKey":{"type":"string","maxLength":512,"pattern":"^step-attachments\\/.*"},"fileName":{"type":"string","minLength":1,"maxLength":255},"mimeType":{"type":"string","minLength":1,"maxLength":255},"byteSize":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["storageKey","fileName","mimeType","byteSize"],"additionalProperties":false}}}},"additionalProperties":false,"description":"Settings for this step type. The fields differ per `type`."},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80,"description":"A stable id you choose for this step; edges reference it by this name. Unique within the graph. Reuse the same key on a later `campaign_set_graph` and the step keeps its position and any config field you do not mention."},"type":{"type":"string","const":"send_inmail","description":"Which kind of step this is. It decides the shape of `config`, and which outcome edges the step may route on."},"config":{"type":"object","properties":{"subject":{"default":"","description":"Required. The InMail subject line — fixed text you write, never AI-written, in every draftMode. The only tokens allowed are template variables (firstName, lastName, companyName, jobTitle, location, headline, companyIndustry); a described slot or a per-lead {{@slot}} is refused. Empty is refused at save and at publish.","type":"string","maxLength":200},"body":{"default":"","description":"The InMail body. In `ai_template` this seed is authoritative: the writer reproduces it word for word and adds nothing, so EVERY per-lead detail must sit inside a `{{...}}` slot written here. A seed with no slots sends the identical message to every lead. A slot holds a description of the fact to write there, phrased as a clause — e.g. `{{one short clause, 8-14 words, on what their company does}}`. Custom list columns reach a message two ways: `{{@columnName}}` sends that column's value word for word, and a normal AI slot that mentions a column can use it as a fact, written in the writer's own words.","type":"string","maxLength":8000},"draftMode":{"description":"How the copy is produced. `template`: sent as written — only allowlisted `{{variables}}` and per-lead `{{@slots}}` are substituted, no AI. `ai_template`: the AI personalizes YOUR seed, filling its `{{described slots}}` and nothing else. Absent means `template`.","type":"string","enum":["template","ai_template"]},"instruction":{"description":"Optional note on tone and register, layered on the seed — NOT where the copy comes from. It reaches the writer AFTER the rule that says to keep the seed as written, so anything it asks for that the seed has no `{{slot}}` for is silently ignored: \"personalize the opening with their company\" does nothing unless a slot sits there. Write the copy in the seed.","type":"string","maxLength":4000},"language":{"description":"Force every message on this step into one language, or set 'auto' so each lead is written to in their OWN language, translating your seed faithfully. OMIT IT and the step uses the default language the sender chose in their settings, or 'auto' when they chose none — which is usually what you want. This rule outranks the seed's original language.","anyOf":[{"type":"string","const":"auto"},{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"]}]},"localization":{"description":"The seed translated into other languages, one per ISO 639-1 code, each keeping every `{{…}}` slot byte-exact and every `---` line. Kairon writes a language here the first time it drafts a lead in it; you may edit any entry and it is then used as written for every later lead in that language. Leave it out to let Kairon translate.","type":"object","properties":{"seedHash":{"type":"string","minLength":1,"description":"Hash of the seed text these translations were made for. Kairon sets it; when the seed changes, the whole object goes stale and is rebuilt. Copy it through unchanged."},"seedLanguage":{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"],"description":"The ISO 639-1 code of the language the seed itself is written in, detected once by Kairon."},"translations":{"type":"object","propertyNames":{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"]},"additionalProperties":{"type":"string","minLength":1},"description":"One translated seed per ISO 639-1 code. Each must keep every `{{…}}` slot byte-exact and in order, and the same number of `---` lines, or publish refuses it."}},"required":["seedHash","seedLanguage","translations"]},"reviewBeforeSend":{"description":"Default false. True holds every send this step drafts for the operator to approve, even when the campaign is on autopilot. Nothing is scheduled until they approve it.","type":"boolean"},"verifyBeforeSend":{"description":"DEPRECATED, and accepted only so campaigns published before the rename still parse. Set `reviewBeforeSend` instead; if both are present the new one wins.","type":"boolean"},"adaptToCulture":{"description":"Retired: accepted for old steps and ignored. Do not send it.","type":"boolean"},"attachments":{"description":"Files sent with this step to every lead it reaches: images and PDFs, plus one voice note and one video on a LinkedIn message.","maxItems":5,"type":"array","items":{"type":"object","properties":{"storageKey":{"type":"string","maxLength":512,"pattern":"^step-attachments\\/.*"},"fileName":{"type":"string","minLength":1,"maxLength":255},"mimeType":{"type":"string","minLength":1,"maxLength":255},"byteSize":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["storageKey","fileName","mimeType","byteSize"],"additionalProperties":false}}},"additionalProperties":false,"description":"Settings for this step type. The fields differ per `type`."},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80,"description":"A stable id you choose for this step; edges reference it by this name. Unique within the graph. Reuse the same key on a later `campaign_set_graph` and the step keeps its position and any config field you do not mention."},"type":{"type":"string","const":"like_last_post","description":"Which kind of step this is. It decides the shape of `config`, and which outcome edges the step may route on."},"config":{"type":"object","properties":{"reaction":{"default":"like","description":"Which reaction to leave on the lead's latest own post. 'auto' reads the post and picks the fitting one of the six; a named value always leaves that one. Defaults to 'like', which is what every campaign saved before this field existed does.","type":"string","enum":["like","celebrate","support","love","insightful","funny","auto"]},"maxPostAgeDays":{"description":"Only react when the lead's latest own post is at most this many days old, 1-3650. When it is older, the step is SKIPPED and the lead moves on; nothing is liked. Defaults to 90 — a like on a years-old post, right before an invite, reads as automation.","type":"integer","minimum":1,"maximum":3650}},"additionalProperties":false,"description":"Settings for this step type. The fields differ per `type`."},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80,"description":"A stable id you choose for this step; edges reference it by this name. Unique within the graph. Reuse the same key on a later `campaign_set_graph` and the step keeps its position and any config field you do not mention."},"type":{"type":"string","const":"visit_profile","description":"Which kind of step this is. It decides the shape of `config`, and which outcome edges the step may route on."},"config":{"type":"object","properties":{},"additionalProperties":false,"description":"Settings for this step type. The fields differ per `type`."},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80,"description":"A stable id you choose for this step; edges reference it by this name. Unique within the graph. Reuse the same key on a later `campaign_set_graph` and the step keeps its position and any config field you do not mention."},"type":{"type":"string","const":"follow_profile","description":"Which kind of step this is. It decides the shape of `config`, and which outcome edges the step may route on."},"config":{"type":"object","properties":{},"additionalProperties":false,"description":"Settings for this step type. The fields differ per `type`."},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80,"description":"A stable id you choose for this step; edges reference it by this name. Unique within the graph. Reuse the same key on a later `campaign_set_graph` and the step keeps its position and any config field you do not mention."},"type":{"type":"string","const":"remove_relation","description":"Which kind of step this is. It decides the shape of `config`, and which outcome edges the step may route on."},"config":{"type":"object","properties":{},"additionalProperties":false,"description":"Settings for this step type. The fields differ per `type`."},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80,"description":"A stable id you choose for this step; edges reference it by this name. Unique within the graph. Reuse the same key on a later `campaign_set_graph` and the step keeps its position and any config field you do not mention."},"type":{"type":"string","const":"comment_on_post","description":"Which kind of step this is. It decides the shape of `config`, and which outcome edges the step may route on."},"config":{"type":"object","properties":{"instruction":{"description":"What the comment should say. UNLIKE a send step, this IS the whole brief: a comment has no operator template to personalize, so the guidance carries the intent alone.","type":"string","maxLength":4000},"condition":{"description":"Only comment when one of their own recent posts meets this test — e.g. \"the post is about AI\". The newest post that meets it is the one commented on; a post that is bad news for its author never meets it. When none does, the step is SKIPPED and the lead moves on to the next step; nothing is posted. Omit it and every eligible post qualifies.","type":"string","maxLength":1000},"maxLength":{"description":"Character ceiling for the comment, up to 1250. Omit and the cap is used.","type":"integer","minimum":1,"maximum":1250},"maxPostAgeDays":{"description":"Only consider their own posts from the last this-many days, 1-90. Defaults to 90. In a loop, the step also only considers posts published after it last acted on a post, or last checked and found none that met its condition.","type":"integer","minimum":1,"maximum":90},"language":{"description":"Force every message on this step into one language, or set 'auto' so each lead is written to in their OWN language, translating your seed faithfully. OMIT IT and the step uses the default language the sender chose in their settings, or 'auto' when they chose none — which is usually what you want. This rule outranks the seed's original language.","anyOf":[{"type":"string","const":"auto"},{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"]}]},"reviewBeforeSend":{"description":"Default false. True holds every send this step drafts for the operator to approve, even when the campaign is on autopilot. Nothing is scheduled until they approve it.","type":"boolean"},"verifyBeforeSend":{"description":"DEPRECATED, and accepted only so campaigns published before the rename still parse. Set `reviewBeforeSend` instead; if both are present the new one wins.","type":"boolean"}},"additionalProperties":false,"description":"Settings for this step type. The fields differ per `type`."},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80,"description":"A stable id you choose for this step; edges reference it by this name. Unique within the graph. Reuse the same key on a later `campaign_set_graph` and the step keeps its position and any config field you do not mention."},"type":{"type":"string","const":"research","description":"Which kind of step this is. It decides the shape of `config`, and which outcome edges the step may route on."},"config":{"type":"object","properties":{"instructions":{"type":"string","minLength":1,"maxLength":4000,"description":"What the researcher should dig for on each lead. A research step SENDS NOTHING — it spends daily enrollment producing briefs, so place one only when the operator asked for it."}},"required":["instructions"],"additionalProperties":false,"description":"Settings for this step type. The fields differ per `type`."},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80,"description":"A stable id you choose for this step; edges reference it by this name. Unique within the graph. Reuse the same key on a later `campaign_set_graph` and the step keeps its position and any config field you do not mention."},"type":{"type":"string","const":"send_email","description":"Which kind of step this is. It decides the shape of `config`, and which outcome edges the step may route on."},"config":{"type":"object","properties":{"subject":{"default":"","description":"Required in managed mode (instantlyCampaignId empty) — fixed text you write, never AI-written, in every draftMode. Empty is refused at save and at publish. Ignored in custom mode (instantlyCampaignId set), where the operator's own Instantly campaign carries its own subject.","type":"string","maxLength":200},"body":{"default":"","description":"The email body. Unlike a LinkedIn send, this always renders as exact fixed text with `{{variables}}` substituted — `ai_template` is not implemented for email yet, so there is no seed-and-slots writing here. Required in managed mode; ignored in custom mode.","type":"string","maxLength":8000},"draftMode":{"description":"Fixed at `template` — `ai_template` is not implemented for `send_email` yet. Omit it or send 'template'; anything else is refused.","type":"string","const":"template"},"instruction":{"description":"Has no effect today: it only applies to `ai_template`, which `send_email` does not implement yet. Write the copy in `body`.","type":"string","maxLength":4000},"language":{"description":"Force every message on this step into one language, or set 'auto' so each lead is written to in their OWN language, translating your seed faithfully. OMIT IT and the step uses the default language the sender chose in their settings, or 'auto' when they chose none — which is usually what you want. This rule outranks the seed's original language.","anyOf":[{"type":"string","const":"auto"},{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"]}]},"localization":{"description":"The seed translated into other languages, one per ISO 639-1 code, each keeping every `{{…}}` slot byte-exact and every `---` line. Kairon writes a language here the first time it drafts a lead in it; you may edit any entry and it is then used as written for every later lead in that language. Leave it out to let Kairon translate.","type":"object","properties":{"seedHash":{"type":"string","minLength":1,"description":"Hash of the seed text these translations were made for. Kairon sets it; when the seed changes, the whole object goes stale and is rebuilt. Copy it through unchanged."},"seedLanguage":{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"],"description":"The ISO 639-1 code of the language the seed itself is written in, detected once by Kairon."},"translations":{"type":"object","propertyNames":{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"]},"additionalProperties":{"type":"string","minLength":1},"description":"One translated seed per ISO 639-1 code. Each must keep every `{{…}}` slot byte-exact and in order, and the same number of `---` lines, or publish refuses it."}},"required":["seedHash","seedLanguage","translations"]},"reviewBeforeSend":{"description":"Default false. True holds every send this step drafts for the operator to approve, even when the campaign is on autopilot. Nothing is scheduled until they approve it.","type":"boolean"},"verifyBeforeSend":{"description":"DEPRECATED, and accepted only so campaigns published before the rename still parse. Set `reviewBeforeSend` instead; if both are present the new one wins.","type":"boolean"},"adaptToCulture":{"description":"Retired: accepted for old steps and ignored. Do not send it.","type":"boolean"},"instantlyCampaignId":{"default":"","type":"string"},"enrichmentBudgetHours":{"description":"Hours (1-72, default 6) to keep waiting for Instantly to find and verify this lead's work email before giving up — the lead then settles as skipped rather than waiting forever, since Instantly gives no signal that an address will never be found.","type":"integer","minimum":1,"maximum":72},"attachments":{"description":"Files sent with this step to every lead it reaches: images and PDFs, plus one voice note and one video on a LinkedIn message.","maxItems":5,"type":"array","items":{"type":"object","properties":{"storageKey":{"type":"string","maxLength":512,"pattern":"^step-attachments\\/.*"},"fileName":{"type":"string","minLength":1,"maxLength":255},"mimeType":{"type":"string","minLength":1,"maxLength":255},"byteSize":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["storageKey","fileName","mimeType","byteSize"],"additionalProperties":false}}},"additionalProperties":false,"description":"Settings for this step type. The fields differ per `type`."},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80,"description":"A stable id you choose for this step; edges reference it by this name. Unique within the graph. Reuse the same key on a later `campaign_set_graph` and the step keeps its position and any config field you do not mention."},"type":{"type":"string","const":"audience_split","description":"Which kind of step this is. It decides the shape of `config`, and which outcome edges the step may route on."},"config":{"type":"object","properties":{"weightA":{"default":50,"description":"Percent of enrolling leads sent down branch A; the rest go down branch B. Use 50 for an even test — 0 or 100 turns the test off and is what applying a winner writes.","type":"integer","minimum":0,"maximum":100},"metric":{"type":"string","enum":["accept_rate","reply_rate"],"description":"What counts as a win when comparing the two branches. Read by Split Review only — it changes nothing about how the campaign runs."},"checkpoint":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","const":"calculated","description":"Work the sample size out from past results."},"minimumDetectableEffectPoints":{"type":"number","minimum":1,"maximum":50,"description":"The smallest gap worth spotting, in percentage points — 10 means \"tell me once one branch is 10 points ahead\". Smaller numbers need many more leads."}},"required":["mode","minimumDetectableEffectPoints"]},{"type":"object","properties":{"mode":{"type":"string","const":"manual","description":"State the finish line yourself."},"by":{"oneOf":[{"type":"object","properties":{"unit":{"type":"string","const":"date","description":"Finish on a calendar day."},"at":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"The day the test may be judged, `YYYY-MM-DD`, read in the campaign’s own timezone."}},"required":["unit","at"]},{"type":"object","properties":{"unit":{"type":"string","const":"count","description":"Finish on a lead count."},"leadsPerBranch":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"How many leads EACH branch must reach before a winner may be named."}},"required":["unit","leadsPerBranch"]}],"description":"Whether the finish line is a date or a per-branch lead count."}},"required":["mode","by"]}],"description":"When a winner may be declared. No winner is ever named before this point, however far ahead one branch already looks — an early peek is how an A/B test lies."}},"required":["metric","checkpoint"],"additionalProperties":false,"description":"Settings for this step type. The fields differ per `type`."},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]}]},"x-nestjs_zod-uses-3-point-1-syntax":true},"edges":{"maxItems":300,"type":"array","items":{"type":"object","properties":{"fromKey":{"type":"string","minLength":1,"maxLength":80,"description":"The `key` of the step this edge leaves."},"toKey":{"type":"string","minLength":1,"maxLength":80,"description":"The `key` of the step it routes to."},"condition":{"type":"string","minLength":1,"maxLength":40,"description":"Which OUTCOME of `fromKey` takes this edge — e.g. `sent`, `accepted`, `timeout`, `done`, `default`. Each step type emits a fixed set, and a condition it does not emit is refused. Some are REQUIRED: leave `wait_connection_accepted`'s `accepted` or a `delay`'s `default` unwired and publish fails with `required_outcome_unwired`."}},"required":["fromKey","toKey","condition"]},"x-nestjs_zod-uses-3-point-1-syntax":true},"startNodeKey":{"anyOf":[{"type":"string","minLength":1,"maxLength":80},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true}},"required":["nodes","edges","startNodeKey"]},"CampaignPublishDto":{"type":"object","properties":{"migrateInFlight":{"type":"boolean","x-nestjs_zod-parent-metadata":{"default":{}}}}},"CampaignActivateDto":{"type":"object","properties":{"startNow":{"default":true,"description":"Default true: enroll today's first batch immediately instead of waiting for the next send window to open.","type":"boolean"}}},"SplitReviewApplyDto":{"type":"object","properties":{"winner":{"type":"string","enum":["branch_a","branch_b"]}},"required":["winner"]},"CampaignSeatAddDto":{"type":"object","properties":{"channelAccountId":{"type":"string","minLength":1,"description":"The seat to add as a sender — a connected LinkedIn account in this org (`seat_list`). It takes new leads from the next enrollment; leads already running keep their own seat. Re-adding a removed sender makes it live again. Refused, naming the step, when the seat cannot run a step of the graph (an InMail step or an invite note needs Premium or Sales Navigator)."},"dailyEnrollmentLimit":{"description":"This sender's own new leads per day, 1-200. Omit to use the campaign's default (`dailyEnrollmentLimit`).","type":"integer","minimum":1,"maximum":200}},"required":["channelAccountId"]},"CampaignSeatUpdateDto":{"type":"object","properties":{"dailyEnrollmentLimit":{"anyOf":[{"type":"integer","minimum":1,"maximum":200},{"type":"null"}],"description":"This sender's own new leads per day, 1-200, or `null` to go back to the campaign's default.","x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true}},"required":["dailyEnrollmentLimit"]},"LeadImportDto":{"type":"object","properties":{"urls":{"minItems":1,"maxItems":500,"type":"array","items":{"type":"string","minLength":1,"maxLength":2048}}},"required":["urls"]},"LeadTagSetDto":{"type":"object","properties":{"tagIds":{"maxItems":25,"type":"array","items":{"type":"string"}}},"required":["tagIds"]},"LeadOwnerSetDto":{"type":"object","properties":{"userId":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true}},"required":["userId"]},"LeadEmailSetDto":{"type":"object","properties":{"email":{"anyOf":[{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true}},"required":["email"]},"LeadPhoneSetDto":{"type":"object","properties":{"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true}},"required":["phone"]},"LeadManualQualificationDto":{"type":"object","properties":{"manualQualification":{"anyOf":[{"type":"string","enum":["qualified","disqualified"]},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true}},"required":["manualQualification"]},"LeadManualQualificationBulkDto":{"type":"object","properties":{"leadIds":{"minItems":1,"maxItems":500,"type":"array","items":{"type":"string"},"x-nestjs_zod-uses-3-point-1-syntax":true},"manualQualification":{"anyOf":[{"type":"string","enum":["qualified","disqualified"]},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true}},"required":["leadIds","manualQualification"]},"CompanyTagSetDto":{"type":"object","properties":{"tagIds":{"maxItems":25,"type":"array","items":{"type":"string"}}},"required":["tagIds"]},"CompanyOwnerSetDto":{"type":"object","properties":{"userId":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true}},"required":["userId"]},"CompanyManualQualificationDto":{"type":"object","properties":{"manualQualification":{"anyOf":[{"type":"string","enum":["qualified","disqualified"]},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true}},"required":["manualQualification"]},"TagCreateDto":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":30},"color":{"type":"string","enum":["stone","clay","moss","sky","plum","amber","rust","slate"]}},"required":["name"]},"TagUpdateDto":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":30},"color":{"type":"string","enum":["stone","clay","moss","sky","plum","amber","rust","slate"]}}},"TagBulkDto":{"type":"object","properties":{"asset":{"type":"string","enum":["leads","companies"]},"ids":{"minItems":1,"maxItems":500,"type":"array","items":{"type":"string"}},"op":{"type":"string","enum":["add","remove"]}},"required":["asset","ids","op"]},"OwnerBulkDto":{"type":"object","properties":{"asset":{"type":"string","enum":["leads","companies","initiatives"],"x-nestjs_zod-uses-3-point-1-syntax":true},"ids":{"minItems":1,"maxItems":500,"type":"array","items":{"type":"string"},"x-nestjs_zod-uses-3-point-1-syntax":true},"userId":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true}},"required":["asset","ids","userId"]},"CrmStageDto":{"type":"object","properties":{"stage":{"type":"string","enum":["new","invite_sent","connected","contacted","replied","interested","meeting_booked","won","on_hold","lost","discarded"]}},"required":["stage"]},"CrmStageBulkDto":{"type":"object","properties":{"ids":{"minItems":1,"maxItems":500,"type":"array","items":{"type":"string"}},"stage":{"type":"string","enum":["new","invite_sent","connected","contacted","replied","interested","meeting_booked","won","on_hold","lost","discarded"]}},"required":["ids","stage"]},"ExclusionPeopleAddDto":{"type":"object","properties":{"items":{"minItems":1,"maxItems":20000,"type":"array","items":{"type":"object","properties":{"linkedinUrl":{"type":"string","maxLength":2048},"fullName":{"type":"string","maxLength":200},"firstName":{"type":"string","maxLength":200},"lastName":{"type":"string","maxLength":200},"companyName":{"type":"string","maxLength":200},"companyUrl":{"type":"string","maxLength":2048},"companyDomain":{"type":"string","maxLength":253}}}}},"required":["items"]},"ExclusionCompaniesAddDto":{"type":"object","properties":{"items":{"minItems":1,"maxItems":20000,"type":"array","items":{"type":"object","properties":{"companyName":{"type":"string","maxLength":200},"linkedinUrl":{"type":"string","maxLength":2048},"domain":{"type":"string","maxLength":253},"matchPastEmployees":{"type":"boolean"}}}}},"required":["items"]},"ExclusionCompanyUpdateDto":{"type":"object","properties":{"matchPastEmployees":{"type":"boolean"}},"required":["matchPastEmployees"]},"WebhookEndpointCreateDto":{"type":"object","properties":{"url":{"type":"string","maxLength":2000,"format":"uri"},"description":{"type":"string","maxLength":120},"enabledEvents":{"minItems":1,"type":"array","items":{"type":"string","enum":["lead.stage.changed"]}}},"required":["url","enabledEvents"]},"WebhookEndpointUpdateDto":{"type":"object","properties":{"url":{"type":"string","maxLength":2000,"format":"uri","x-nestjs_zod-uses-3-point-1-syntax":true},"description":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"enabledEvents":{"minItems":1,"type":"array","items":{"type":"string","enum":["lead.stage.changed"]},"x-nestjs_zod-uses-3-point-1-syntax":true},"status":{"type":"string","enum":["enabled","disabled_by_user"],"x-nestjs_zod-uses-3-point-1-syntax":true}}},"CrmCallbackDto":{"type":"object","properties":{"code":{"type":"string","minLength":1,"maxLength":2000},"state":{"type":"string","minLength":1,"maxLength":4000}},"required":["code","state"]},"CrmSettingsDto":{"type":"object","properties":{"triggerStage":{"anyOf":[{"type":"string","enum":["invite_sent","connected","contacted","replied","interested","meeting_booked","won"]},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"mapping":{"maxItems":60,"type":"array","items":{"type":"object","properties":{"from":{"type":"string","enum":["first_name","last_name","full_name","headline","summary","location","linkedin_url","email","stage","tags","qualification.status","current_company.name","current_company.domain","current_company.linkedin_url","current_company.industry","current_company.employee_count","current_company.location"]},"to":{"type":"string","minLength":1,"maxLength":200,"pattern":"^[A-Za-z][A-Za-z0-9_]*$"},"defaultValue":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}]},"overwrite":{"type":"boolean"},"optional":{"type":"boolean"}},"required":["from","to","defaultValue","overwrite","optional"]},"x-nestjs_zod-uses-3-point-1-syntax":true},"leadMapping":{"maxItems":60,"type":"array","items":{"type":"object","properties":{"from":{"type":"string","enum":["first_name","last_name","full_name","headline","summary","location","linkedin_url","email","stage","tags","qualification.status","current_company.name","current_company.domain","current_company.linkedin_url","current_company.industry","current_company.employee_count","current_company.location"]},"to":{"type":"string","minLength":1,"maxLength":200,"pattern":"^[A-Za-z][A-Za-z0-9_]*$"},"defaultValue":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}]},"overwrite":{"type":"boolean"},"optional":{"type":"boolean"}},"required":["from","to","defaultValue","overwrite","optional"]},"x-nestjs_zod-uses-3-point-1-syntax":true},"pushMode":{"type":"string","enum":["salesforce_lead","contact"],"x-nestjs_zod-uses-3-point-1-syntax":true},"convertLeads":{"type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true},"source":{"type":"object","properties":{"property":{"anyOf":[{"type":"string","minLength":1,"maxLength":200,"pattern":"^[A-Za-z][A-Za-z0-9_]*$"},{"type":"null"}]},"value":{"type":"string","minLength":1,"maxLength":255}},"required":["property","value"],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-self-required":false}},"required":["triggerStage","mapping"]},"CrmPushDto":{"type":"object","properties":{"leadIds":{"minItems":1,"maxItems":1000,"type":"array","items":{"type":"string","minLength":1},"description":"The leads to send (lead ids, `lead_…`), at most 1000."}},"required":["leadIds"]},"ValuePropositionInputDto":{"type":"object","properties":{"valueProposition":{"type":"string","maxLength":5000},"expected":{"type":"string"}},"required":["valueProposition"]},"LeadMagnetInputDto":{"type":"object","properties":{"leadMagnet":{"type":"string","maxLength":5000},"expected":{"type":"string"}},"required":["leadMagnet"]},"LearningsInputDto":{"type":"object","properties":{"learnings":{"type":"string","maxLength":20000},"expected":{"type":"string"}},"required":["learnings"]},"UserTimezoneInputDto":{"type":"object","properties":{"tz":{"type":"string","minLength":1,"maxLength":64}},"required":["tz"]},"UserLocaleInputDto":{"type":"object","properties":{"locale":{"type":"string","maxLength":35}},"required":["locale"]},"WhatsappNumberInputDto":{"type":"object","properties":{"number":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"country":{"type":"string","pattern":"^[A-Z]{2}$","x-nestjs_zod-uses-3-point-1-syntax":true}},"required":["number"]},"DefaultLanguageInputDto":{"type":"object","properties":{"language":{"anyOf":[{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"]},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true}},"required":["language"]},"WritingStyleInputDto":{"type":"object","properties":{"text":{"type":"string","maxLength":8000}},"required":["text"]},"WritingChecksInputDto":{"type":"object","properties":{"checks":{"default":[],"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"description":{"type":"string","minLength":1,"maxLength":2000,"description":"The rule itself, phrased so a draft can be judged against it and either passes or does not — \"No em dashes anywhere\" works. A note about how the writing should feel gives nothing to test, so it silently never fires."}},"required":["description"]}}}},"SharedWritingCheckInputDto":{"type":"object","properties":{"enabled":{"type":"boolean"}},"required":["enabled"]},"QualifyLeadDto":{"type":"object","properties":{"profileUrl":{"type":"string","minLength":1,"maxLength":2048},"icpVersionId":{"type":"string","minLength":1}},"required":["profileUrl","icpVersionId"]},"QualifyCompanyDto":{"type":"object","properties":{"company":{"type":"object","properties":{"providerId":{"type":"string","minLength":1},"name":{"type":"string"},"publicIdentifier":{"type":"string"},"description":{"type":"string"},"profileUrl":{"type":"string"},"website":{"type":"string"},"industries":{"type":"array","items":{"type":"string"}},"employeeCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"followerCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"hqCity":{"type":"string"},"hqCountry":{"type":"string"},"logoUrl":{"type":"string"}},"required":["providerId"],"x-nestjs_zod-self-required":true},"icpVersionId":{"type":"string","minLength":1}},"required":["company","icpVersionId"]},"QualifyLeadDraftDto":{"type":"object","properties":{"profileUrl":{"type":"string","minLength":1,"maxLength":2048},"conditions":{"minItems":1,"maxItems":50,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"description":{"type":"string","minLength":1,"maxLength":2000},"webSearch":{"type":"boolean"},"siteKeywords":{"type":"object","properties":{"include":{"maxItems":32,"type":"array","items":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[^\"]*$"}},"exclude":{"maxItems":32,"type":"array","items":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[^\"]*$"}}}}},"required":["description"]}}},"required":["profileUrl","conditions"]},"QualifyCompanyDraftDto":{"type":"object","properties":{"company":{"type":"object","properties":{"providerId":{"type":"string","minLength":1},"name":{"type":"string"},"publicIdentifier":{"type":"string"},"description":{"type":"string"},"profileUrl":{"type":"string"},"website":{"type":"string"},"industries":{"type":"array","items":{"type":"string"}},"employeeCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"followerCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"hqCity":{"type":"string"},"hqCountry":{"type":"string"},"logoUrl":{"type":"string"}},"required":["providerId"],"x-nestjs_zod-self-required":true},"conditions":{"minItems":1,"maxItems":50,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"description":{"type":"string","minLength":1,"maxLength":2000},"webSearch":{"type":"boolean"},"siteKeywords":{"type":"object","properties":{"include":{"maxItems":32,"type":"array","items":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[^\"]*$"}},"exclude":{"maxItems":32,"type":"array","items":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[^\"]*$"}}}}},"required":["description"]}}},"required":["company","conditions"]},"QualificationRunCreateDto":{"type":"object","properties":{"icpId":{"type":"string","minLength":1},"subjectIds":{"minItems":1,"type":"array","items":{"type":"string","minLength":1}},"ignoreIcpMismatch":{"default":false,"type":"boolean"}},"required":["icpId","subjectIds"]},"QualificationRunRerunDto":{"type":"object","properties":{"ignoreIcpMismatch":{"default":false,"type":"boolean"}}},"AudiencePreviewDto":{"type":"object","properties":{"audience":{"type":"object","properties":{"include":{"type":"object","properties":{"match":{"type":"string","enum":["all","any"],"description":"How this group's conditions join. `all` means a lead must satisfy EVERY condition; `any` means one is enough. Inside a single condition the fields always AND and the values in a field always OR, whatever `match` says — so `{ crmStage: ['on_hold','lost'], tagId: ['t1'] }` reads as (on_hold OR lost) AND t1."},"conditions":{"minItems":1,"maxItems":10,"type":"array","items":{"type":"object","properties":{"crmStage":{"description":"Keep leads standing at ANY of these Pipeline columns. `on_hold` is the parked pile — people a campaign ran out of things to say to, or whose conversation went quiet for two weeks. `new` is NOT 'people arriving': it is every lead nobody has worked yet, including every CSV row ever imported, so a rule over it can select tens of thousands.","minItems":1,"type":"array","items":{"type":"string","enum":["new","invite_sent","connected","contacted","replied","interested","meeting_booked","won","on_hold","lost","discarded"]}},"tagId":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"ownerId":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"qualificationStatus":{"description":"Keep leads whose ICP verdict is ANY of these. A lead the audience adds can still be qualified afterwards like any other member — `list_qualify` works on an audience list exactly as it does on a hand-made one.","anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"lastContacted":{"description":"Keep leads last contacted inside this window — `7d`, `30d`, `90d`, `never`, or `YYYY-MM-DD..YYYY-MM-DD`. Counts BOTH a campaign send and a message in the chat. This is the field that makes an `exclude` group safe: `exclude` + `lastContacted: '30d'` is how you say 'nobody who heard from me this month'. Resolved against the clock at every evaluation, so a stored `30d` always means the 30 days before tonight's run, never the 30 days before the day you saved it.","type":"string"},"companyId":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"createdAfter":{"description":"Keep only leads that ARRIVED in the org after this instant (ISO-8601, e.g. `2026-09-21T00:00:00.000Z`). This is what 'the people coming in' means: `crmStage: ['new']` on its own is the whole untouched backlog — every CSV row ever imported — which in the largest orgs is tens of thousands of people who have been sitting there for a year. Pair the two: `{ crmStage: ['new'], createdAfter: '<now>' }` is a flow for people who arrive from here on. An ABSOLUTE instant, not a rolling window, so the audience does not quietly forget the people it admitted last month.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"additionalProperties":false},"description":"The conditions this group joins, 1 to 10. Each must name at least one field; an empty condition is refused rather than read as 'everyone'."}},"required":["match","conditions"],"description":"Who the rule selects. Required — a rule with only an exclude would select everyone and then take some away, which is never what an operator means."},"exclude":{"description":"Who to take back OUT of that selection. Optional, and evaluated as `include AND NOT exclude`, so both apply at once. A lead the exclude cannot decide about — no owner on file when you exclude by owner, no employer when you exclude by company — is KEPT, not dropped.","type":"object","properties":{"match":{"type":"string","enum":["all","any"],"description":"How this group's conditions join. `all` means a lead must satisfy EVERY condition; `any` means one is enough. Inside a single condition the fields always AND and the values in a field always OR, whatever `match` says — so `{ crmStage: ['on_hold','lost'], tagId: ['t1'] }` reads as (on_hold OR lost) AND t1."},"conditions":{"minItems":1,"maxItems":10,"type":"array","items":{"type":"object","properties":{"crmStage":{"description":"Keep leads standing at ANY of these Pipeline columns. `on_hold` is the parked pile — people a campaign ran out of things to say to, or whose conversation went quiet for two weeks. `new` is NOT 'people arriving': it is every lead nobody has worked yet, including every CSV row ever imported, so a rule over it can select tens of thousands.","minItems":1,"type":"array","items":{"type":"string","enum":["new","invite_sent","connected","contacted","replied","interested","meeting_booked","won","on_hold","lost","discarded"]}},"tagId":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"ownerId":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"qualificationStatus":{"description":"Keep leads whose ICP verdict is ANY of these. A lead the audience adds can still be qualified afterwards like any other member — `list_qualify` works on an audience list exactly as it does on a hand-made one.","anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"lastContacted":{"description":"Keep leads last contacted inside this window — `7d`, `30d`, `90d`, `never`, or `YYYY-MM-DD..YYYY-MM-DD`. Counts BOTH a campaign send and a message in the chat. This is the field that makes an `exclude` group safe: `exclude` + `lastContacted: '30d'` is how you say 'nobody who heard from me this month'. Resolved against the clock at every evaluation, so a stored `30d` always means the 30 days before tonight's run, never the 30 days before the day you saved it.","type":"string"},"companyId":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"createdAfter":{"description":"Keep only leads that ARRIVED in the org after this instant (ISO-8601, e.g. `2026-09-21T00:00:00.000Z`). This is what 'the people coming in' means: `crmStage: ['new']` on its own is the whole untouched backlog — every CSV row ever imported — which in the largest orgs is tens of thousands of people who have been sitting there for a year. Pair the two: `{ crmStage: ['new'], createdAfter: '<now>' }` is a flow for people who arrive from here on. An ABSOLUTE instant, not a rolling window, so the audience does not quietly forget the people it admitted last month.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"additionalProperties":false},"description":"The conditions this group joins, 1 to 10. Each must name at least one field; an empty condition is refused rather than read as 'everyone'."}},"required":["match","conditions"]}},"required":["include"],"x-nestjs_zod-self-required":true}},"required":["audience"]},"LeadListCreateDto":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"audience":{"type":"object","properties":{"include":{"type":"object","properties":{"match":{"type":"string","enum":["all","any"],"description":"How this group's conditions join. `all` means a lead must satisfy EVERY condition; `any` means one is enough. Inside a single condition the fields always AND and the values in a field always OR, whatever `match` says — so `{ crmStage: ['on_hold','lost'], tagId: ['t1'] }` reads as (on_hold OR lost) AND t1."},"conditions":{"minItems":1,"maxItems":10,"type":"array","items":{"type":"object","properties":{"crmStage":{"description":"Keep leads standing at ANY of these Pipeline columns. `on_hold` is the parked pile — people a campaign ran out of things to say to, or whose conversation went quiet for two weeks. `new` is NOT 'people arriving': it is every lead nobody has worked yet, including every CSV row ever imported, so a rule over it can select tens of thousands.","minItems":1,"type":"array","items":{"type":"string","enum":["new","invite_sent","connected","contacted","replied","interested","meeting_booked","won","on_hold","lost","discarded"]}},"tagId":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"ownerId":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"qualificationStatus":{"description":"Keep leads whose ICP verdict is ANY of these. A lead the audience adds can still be qualified afterwards like any other member — `list_qualify` works on an audience list exactly as it does on a hand-made one.","anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"lastContacted":{"description":"Keep leads last contacted inside this window — `7d`, `30d`, `90d`, `never`, or `YYYY-MM-DD..YYYY-MM-DD`. Counts BOTH a campaign send and a message in the chat. This is the field that makes an `exclude` group safe: `exclude` + `lastContacted: '30d'` is how you say 'nobody who heard from me this month'. Resolved against the clock at every evaluation, so a stored `30d` always means the 30 days before tonight's run, never the 30 days before the day you saved it.","type":"string"},"companyId":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"createdAfter":{"description":"Keep only leads that ARRIVED in the org after this instant (ISO-8601, e.g. `2026-09-21T00:00:00.000Z`). This is what 'the people coming in' means: `crmStage: ['new']` on its own is the whole untouched backlog — every CSV row ever imported — which in the largest orgs is tens of thousands of people who have been sitting there for a year. Pair the two: `{ crmStage: ['new'], createdAfter: '<now>' }` is a flow for people who arrive from here on. An ABSOLUTE instant, not a rolling window, so the audience does not quietly forget the people it admitted last month.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"additionalProperties":false},"description":"The conditions this group joins, 1 to 10. Each must name at least one field; an empty condition is refused rather than read as 'everyone'."}},"required":["match","conditions"],"description":"Who the rule selects. Required — a rule with only an exclude would select everyone and then take some away, which is never what an operator means."},"exclude":{"description":"Who to take back OUT of that selection. Optional, and evaluated as `include AND NOT exclude`, so both apply at once. A lead the exclude cannot decide about — no owner on file when you exclude by owner, no employer when you exclude by company — is KEPT, not dropped.","type":"object","properties":{"match":{"type":"string","enum":["all","any"],"description":"How this group's conditions join. `all` means a lead must satisfy EVERY condition; `any` means one is enough. Inside a single condition the fields always AND and the values in a field always OR, whatever `match` says — so `{ crmStage: ['on_hold','lost'], tagId: ['t1'] }` reads as (on_hold OR lost) AND t1."},"conditions":{"minItems":1,"maxItems":10,"type":"array","items":{"type":"object","properties":{"crmStage":{"description":"Keep leads standing at ANY of these Pipeline columns. `on_hold` is the parked pile — people a campaign ran out of things to say to, or whose conversation went quiet for two weeks. `new` is NOT 'people arriving': it is every lead nobody has worked yet, including every CSV row ever imported, so a rule over it can select tens of thousands.","minItems":1,"type":"array","items":{"type":"string","enum":["new","invite_sent","connected","contacted","replied","interested","meeting_booked","won","on_hold","lost","discarded"]}},"tagId":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"ownerId":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"qualificationStatus":{"description":"Keep leads whose ICP verdict is ANY of these. A lead the audience adds can still be qualified afterwards like any other member — `list_qualify` works on an audience list exactly as it does on a hand-made one.","anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"lastContacted":{"description":"Keep leads last contacted inside this window — `7d`, `30d`, `90d`, `never`, or `YYYY-MM-DD..YYYY-MM-DD`. Counts BOTH a campaign send and a message in the chat. This is the field that makes an `exclude` group safe: `exclude` + `lastContacted: '30d'` is how you say 'nobody who heard from me this month'. Resolved against the clock at every evaluation, so a stored `30d` always means the 30 days before tonight's run, never the 30 days before the day you saved it.","type":"string"},"companyId":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"createdAfter":{"description":"Keep only leads that ARRIVED in the org after this instant (ISO-8601, e.g. `2026-09-21T00:00:00.000Z`). This is what 'the people coming in' means: `crmStage: ['new']` on its own is the whole untouched backlog — every CSV row ever imported — which in the largest orgs is tens of thousands of people who have been sitting there for a year. Pair the two: `{ crmStage: ['new'], createdAfter: '<now>' }` is a flow for people who arrive from here on. An ABSOLUTE instant, not a rolling window, so the audience does not quietly forget the people it admitted last month.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"additionalProperties":false},"description":"The conditions this group joins, 1 to 10. Each must name at least one field; an empty condition is refused rather than read as 'everyone'."}},"required":["match","conditions"]}},"required":["include"],"x-nestjs_zod-self-required":false}},"required":["name"]},"LeadListUpdateDto":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200,"x-nestjs_zod-uses-3-point-1-syntax":true},"audience":{"anyOf":[{"type":"object","properties":{"include":{"type":"object","properties":{"match":{"type":"string","enum":["all","any"],"description":"How this group's conditions join. `all` means a lead must satisfy EVERY condition; `any` means one is enough. Inside a single condition the fields always AND and the values in a field always OR, whatever `match` says — so `{ crmStage: ['on_hold','lost'], tagId: ['t1'] }` reads as (on_hold OR lost) AND t1."},"conditions":{"minItems":1,"maxItems":10,"type":"array","items":{"type":"object","properties":{"crmStage":{"description":"Keep leads standing at ANY of these Pipeline columns. `on_hold` is the parked pile — people a campaign ran out of things to say to, or whose conversation went quiet for two weeks. `new` is NOT 'people arriving': it is every lead nobody has worked yet, including every CSV row ever imported, so a rule over it can select tens of thousands.","minItems":1,"type":"array","items":{"type":"string","enum":["new","invite_sent","connected","contacted","replied","interested","meeting_booked","won","on_hold","lost","discarded"]}},"tagId":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"ownerId":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"qualificationStatus":{"description":"Keep leads whose ICP verdict is ANY of these. A lead the audience adds can still be qualified afterwards like any other member — `list_qualify` works on an audience list exactly as it does on a hand-made one.","anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"lastContacted":{"description":"Keep leads last contacted inside this window — `7d`, `30d`, `90d`, `never`, or `YYYY-MM-DD..YYYY-MM-DD`. Counts BOTH a campaign send and a message in the chat. This is the field that makes an `exclude` group safe: `exclude` + `lastContacted: '30d'` is how you say 'nobody who heard from me this month'. Resolved against the clock at every evaluation, so a stored `30d` always means the 30 days before tonight's run, never the 30 days before the day you saved it.","type":"string"},"companyId":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"createdAfter":{"description":"Keep only leads that ARRIVED in the org after this instant (ISO-8601, e.g. `2026-09-21T00:00:00.000Z`). This is what 'the people coming in' means: `crmStage: ['new']` on its own is the whole untouched backlog — every CSV row ever imported — which in the largest orgs is tens of thousands of people who have been sitting there for a year. Pair the two: `{ crmStage: ['new'], createdAfter: '<now>' }` is a flow for people who arrive from here on. An ABSOLUTE instant, not a rolling window, so the audience does not quietly forget the people it admitted last month.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"additionalProperties":false},"description":"The conditions this group joins, 1 to 10. Each must name at least one field; an empty condition is refused rather than read as 'everyone'."}},"required":["match","conditions"],"description":"Who the rule selects. Required — a rule with only an exclude would select everyone and then take some away, which is never what an operator means."},"exclude":{"description":"Who to take back OUT of that selection. Optional, and evaluated as `include AND NOT exclude`, so both apply at once. A lead the exclude cannot decide about — no owner on file when you exclude by owner, no employer when you exclude by company — is KEPT, not dropped.","type":"object","properties":{"match":{"type":"string","enum":["all","any"],"description":"How this group's conditions join. `all` means a lead must satisfy EVERY condition; `any` means one is enough. Inside a single condition the fields always AND and the values in a field always OR, whatever `match` says — so `{ crmStage: ['on_hold','lost'], tagId: ['t1'] }` reads as (on_hold OR lost) AND t1."},"conditions":{"minItems":1,"maxItems":10,"type":"array","items":{"type":"object","properties":{"crmStage":{"description":"Keep leads standing at ANY of these Pipeline columns. `on_hold` is the parked pile — people a campaign ran out of things to say to, or whose conversation went quiet for two weeks. `new` is NOT 'people arriving': it is every lead nobody has worked yet, including every CSV row ever imported, so a rule over it can select tens of thousands.","minItems":1,"type":"array","items":{"type":"string","enum":["new","invite_sent","connected","contacted","replied","interested","meeting_booked","won","on_hold","lost","discarded"]}},"tagId":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"ownerId":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"qualificationStatus":{"description":"Keep leads whose ICP verdict is ANY of these. A lead the audience adds can still be qualified afterwards like any other member — `list_qualify` works on an audience list exactly as it does on a hand-made one.","anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"lastContacted":{"description":"Keep leads last contacted inside this window — `7d`, `30d`, `90d`, `never`, or `YYYY-MM-DD..YYYY-MM-DD`. Counts BOTH a campaign send and a message in the chat. This is the field that makes an `exclude` group safe: `exclude` + `lastContacted: '30d'` is how you say 'nobody who heard from me this month'. Resolved against the clock at every evaluation, so a stored `30d` always means the 30 days before tonight's run, never the 30 days before the day you saved it.","type":"string"},"companyId":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"createdAfter":{"description":"Keep only leads that ARRIVED in the org after this instant (ISO-8601, e.g. `2026-09-21T00:00:00.000Z`). This is what 'the people coming in' means: `crmStage: ['new']` on its own is the whole untouched backlog — every CSV row ever imported — which in the largest orgs is tens of thousands of people who have been sitting there for a year. Pair the two: `{ crmStage: ['new'], createdAfter: '<now>' }` is a flow for people who arrive from here on. An ABSOLUTE instant, not a rolling window, so the audience does not quietly forget the people it admitted last month.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"additionalProperties":false},"description":"The conditions this group joins, 1 to 10. Each must name at least one field; an empty condition is refused rather than read as 'everyone'."}},"required":["match","conditions"]}},"required":["include"]},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true}},"required":["name"]},"ListArchiveDto":{"type":"object","properties":{"archived":{"type":"boolean","description":"true archives the list; false restores it."}},"required":["archived"]},"ListColumnsDto":{"type":"object","properties":{"columns":{"maxItems":100,"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":40,"description":"The column's name, as it appears on the list."},"renameFrom":{"description":"The column this entry RENAMES. Carry it and every member's values travel to the new name; omit it and you have deleted one column and added an empty one.","type":"string","minLength":1,"maxLength":40}},"required":["name"]}}},"required":["columns"]},"ListColumnValuesDto":{"type":"object","properties":{"values":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","maxLength":20000},"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-self-required":true}},"required":["values"]},"LeadListMemberKeysActionDto":{"type":"object","properties":{"keys":{"minItems":1,"maxItems":10000,"type":"array","items":{"type":"string","minLength":1,"maxLength":2048}}},"required":["keys"]},"LeadListAddMembersDto":{"type":"object","properties":{"items":{"minItems":1,"maxItems":500,"type":"array","items":{"anyOf":[{"type":"object","properties":{"leadId":{"type":"string","minLength":1}},"required":["leadId"]},{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":2048}},"required":["url"]},{"type":"object","properties":{"snapshot":{"type":"object","properties":{"providerId":{"type":"string","minLength":1},"publicIdentifier":{"type":"string"},"profileUrl":{"type":"string"},"name":{"type":"string"},"headline":{"type":"string"},"company":{"type":"string"},"companyId":{"type":"string"},"title":{"type":"string"},"industry":{"type":"string"},"location":{"type":"string"},"avatarUrl":{"type":"string"}},"required":["providerId"]}},"required":["snapshot"]}]}}},"required":["items"]},"LeadListLoadProfilesDto":{"type":"object","properties":{"leadIds":{"minItems":1,"maxItems":5000,"type":"array","items":{"type":"string","minLength":1},"x-nestjs_zod-parent-metadata":{"default":{}}}}},"LeadListReconcileDto":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"addKeys":{"maxItems":2500,"type":"array","items":{"type":"string","minLength":1,"maxLength":2048}},"removeKeys":{"maxItems":2500,"type":"array","items":{"type":"string","minLength":1}}},"required":["name","addKeys","removeKeys"]},"CompanyListCreateDto":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200}},"required":["name"]},"CompanyListColumnsDto":{"type":"object","properties":{"columns":{"maxItems":100,"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":40,"description":"The column's name, as it appears on the list."},"renameFrom":{"description":"The column this entry RENAMES. Carry it and every member's values travel to the new name; omit it and you have deleted one column and added an empty one.","type":"string","minLength":1,"maxLength":40}},"required":["name"]}}},"required":["columns"]},"CompanyListColumnValuesDto":{"type":"object","properties":{"values":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string","maxLength":20000},"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-self-required":true}},"required":["values"]},"CompanyListUpdateDto":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200}},"required":["name"]},"CompanyListArchiveDto":{"type":"object","properties":{"archived":{"type":"boolean","description":"true archives the list; false restores it."}},"required":["archived"]},"CompanyListMemberKeysActionDto":{"type":"object","properties":{"keys":{"minItems":1,"maxItems":10000,"type":"array","items":{"type":"string","minLength":1,"maxLength":2048}}},"required":["keys"]},"CompanyListAddMembersDto":{"type":"object","properties":{"items":{"minItems":1,"maxItems":500,"type":"array","items":{"anyOf":[{"type":"object","properties":{"companyId":{"type":"string","minLength":1}},"required":["companyId"]},{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":2048}},"required":["url"]},{"type":"object","properties":{"snapshot":{"type":"object","properties":{"providerId":{"type":"string","minLength":1},"name":{"type":"string"},"publicIdentifier":{"type":"string"},"description":{"type":"string"},"profileUrl":{"type":"string"},"website":{"type":"string"},"industries":{"type":"array","items":{"type":"string"}},"employeeCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"followerCount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"hqCity":{"type":"string"},"hqCountry":{"type":"string"},"logoUrl":{"type":"string"}},"required":["providerId"]}},"required":["snapshot"]}]}}},"required":["items"]},"CompanyListReconcileDto":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"addKeys":{"maxItems":2500,"type":"array","items":{"type":"string","minLength":1,"maxLength":2048}},"removeKeys":{"maxItems":2500,"type":"array","items":{"type":"string","minLength":1}}},"required":["name","addKeys","removeKeys"]},"CompanyListRemoveMembersDto":{"type":"object","properties":{"companyIds":{"minItems":1,"maxItems":500,"type":"array","items":{"type":"string","minLength":1}}},"required":["companyIds"]},"ActAsStartDto":{"type":"object","properties":{"userId":{"type":"string","minLength":1},"organizationId":{"type":"string","minLength":1}},"required":["userId"]},"SignupDto":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"email":{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"password":{"type":"string","minLength":8,"maxLength":256},"companyName":{"type":"string","minLength":1,"maxLength":120},"icp":{"type":"string","maxLength":2000},"attribution":{"type":"object","properties":{"gclid":{"type":"string","maxLength":255},"utmSource":{"type":"string","maxLength":255},"utmMedium":{"type":"string","maxLength":255},"utmCampaign":{"type":"string","maxLength":255},"utmTerm":{"type":"string","maxLength":255},"firstTouchPath":{"type":"string","maxLength":2048},"firstTouchReferrer":{"type":"string","maxLength":255},"firstTouchAt":{"type":"string","maxLength":10}},"x-nestjs_zod-self-required":false}},"required":["name","email","password","companyName"]},"FreeToolSubscribeDto":{"type":"object","properties":{"email":{"type":"string","maxLength":320,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"source":{"type":"string","enum":["funding_radar_latam","funding_radar_us"]},"marketingConsent":{"type":"boolean"},"attribution":{"type":"object","properties":{"gclid":{"type":"string","maxLength":255},"utmSource":{"type":"string","maxLength":255},"utmMedium":{"type":"string","maxLength":255},"utmCampaign":{"type":"string","maxLength":255},"utmTerm":{"type":"string","maxLength":255},"firstTouchPath":{"type":"string","maxLength":2048},"firstTouchReferrer":{"type":"string","maxLength":255},"firstTouchAt":{"type":"string","maxLength":10}},"x-nestjs_zod-self-required":false},"website":{"type":"string","maxLength":500}},"required":["email","source"]},"InviteMemberDto":{"type":"object","properties":{"email":{"type":"string","format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"role":{"type":"string","enum":["member","admin"]}},"required":["email","role"]},"ChangeMemberRoleDto":{"type":"object","properties":{"role":{"type":"string","enum":["member","admin"]}},"required":["role"]},"RenameOrganizationDto":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120,"description":"The workspace's new display name."}},"required":["name"]},"AgentChatDto":{"type":"object","properties":{"messages":{"minItems":1,"maxItems":200,"type":"array","items":{},"x-nestjs_zod-uses-3-point-1-syntax":true},"model":{"type":"string","minLength":3,"maxLength":120,"pattern":"^[a-z0-9][a-z0-9._-]*\\/[a-z0-9][a-z0-9._:-]*$","x-nestjs_zod-uses-3-point-1-syntax":true},"effort":{"type":"string","enum":["minimal","low","medium","high"],"x-nestjs_zod-uses-3-point-1-syntax":true},"searchMode":{"type":"string","enum":["advanced","my_network"],"x-nestjs_zod-uses-3-point-1-syntax":true},"listContext":{"type":"object","properties":{"asset":{"type":"string","enum":["leads","companies"]},"listId":{"type":"string"},"diff":{"type":"object","properties":{"added":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"id":{"type":"string"},"hit":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"qualification":{}},"required":["key","hit"]}},"removedKeys":{"type":"array","items":{"type":"string"}}},"required":["added","removedKeys"]}},"required":["asset","listId","diff"],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-self-required":false},"companyListMentions":{"maxItems":20,"type":"array","items":{"type":"object","properties":{"companyListId":{"type":"string"},"mode":{"type":"string","enum":["include","exclude"]}},"required":["companyListId","mode"]},"x-nestjs_zod-uses-3-point-1-syntax":true}},"required":["messages"]},"SearchMoreDto":{"type":"object","properties":{"input":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-self-required":true},"cursor":{"type":"string","x-nestjs_zod-uses-3-point-1-syntax":true},"mode":{"type":"string","enum":["page","all"],"x-nestjs_zod-uses-3-point-1-syntax":true},"limit":{"type":"integer","exclusiveMinimum":0,"maximum":100,"x-nestjs_zod-uses-3-point-1-syntax":true},"source":{"type":"string","enum":["classic","post_reactions","event_attendees"],"x-nestjs_zod-uses-3-point-1-syntax":true},"companyListMentions":{"maxItems":20,"type":"array","items":{"type":"object","properties":{"companyListId":{"type":"string"},"mode":{"type":"string","enum":["include","exclude"]}},"required":["companyListId","mode"]},"x-nestjs_zod-uses-3-point-1-syntax":true},"poolGrant":{"type":"string","maxLength":2048,"x-nestjs_zod-uses-3-point-1-syntax":true}},"required":["input","mode"]},"PublishIcpDto":{"type":"object","properties":{"ifDraftUpdatedAt":{"description":"The `draft.updatedAt` you showed the operator. Publish then refuses (ICP_DRAFT_CHANGED) if the draft changed after, instead of publishing edits they did not see.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}}},"CreateIcpDto":{"type":"object","properties":{"description":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"companySalesNavCriteria":{"anyOf":[{"type":"object","properties":{"category":{"default":"companies","type":"string","enum":["people","companies"]},"keywords":{"description":"LAST resort — matches noisily across all text. Prefer a structured filter for any title/industry/geography/size intent; use keywords only for a concept no filter captures. This is a BOOLEAN query, not a phrase: bare space-separated words are AND-ed (ALL must appear), so \"fintech payments neobank\" requires all three together and usually returns ZERO. For ALTERNATIVES, OR them, quote each, and ALWAYS wrap the OR group in parentheses: `(\"fintech\" OR \"payments\" OR \"neobank\")`. The parentheses are MANDATORY — LinkedIn silently mis-parses an unparenthesized OR of 4+ terms and returns ~0. Quote multi-word phrases; combine groups with AND/NOT (e.g. `(\"fintech\" OR \"neobank\") AND \"payments\"`). Operators must be UPPERCASE.","type":"string","minLength":1,"maxLength":2000},"filters":{"description":"Id-resolved dimensions (location, industry, company, …). Same dimension repeated = OR; different dimensions = AND (each narrows the results).","maxItems":40,"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["location","industry","function","current_company","past_company","company_location","school","past_role","groups","persona","technologies","account_lists","lead_lists","postal_code"],"description":"Which id-resolved dimension. People: location, industry, function, current_company, past_company, company_location, school, past_role, groups, persona, account_lists, lead_lists, postal_code. Companies: location, industry, technologies, account_lists, postal_code — the rest are people-only and are REFUSED here rather than quietly ignored. On a companies search the company IS the subject, so its location is plain `location` (`company_location` is accepted as a synonym for it, and means the EMPLOYER’s location only on a people search). `groups` is measured from YOU, like the saved lists: LinkedIn only knows the groups your own account has JOINED, so it works only on your OWN Sales Navigator seat and is otherwise refused, rather than answered about a different audience. To reach the people in a group, use `group_members` instead — it reads the group’s own member list on your own seat: any public group, or a members-only one your seat has joined."},"query":{"type":"string","minLength":1,"maxLength":256,"description":"The value as a human-readable NAME (never an id). Phrase it the way LinkedIn names things — canonical industry names (\"Financial Services\", not \"fintech\"), real place names (\"Greater Madrid Metropolitan Area\" or the country). Resolution takes the best single typeahead match and echoes the resolved label back."},"mode":{"description":"\"include\" (default) requires the value; \"exclude\" filters it out.","type":"string","enum":["include","exclude"]}},"required":["type","query"]}},"cursor":{"description":"Pass the cursor from a prior result to page. It continues only the exact search that made it: send it with the SAME category and filters as the first page, or it is refused.","type":"string","maxLength":65536},"limit":{"description":"Page size (max 100 for Sales Nav; default 10). One page costs one metered action WHATEVER its size, so raise it when you are filling a list rather than sampling.","type":"integer","minimum":1,"maximum":100},"firstName":{"type":"string","minLength":1,"maxLength":128},"lastName":{"type":"string","minLength":1,"maxLength":128},"role":{"description":"Current job-TITLE keywords (include/exclude) — the primary people filter. Use it for ALL title intent, NOT `keywords` and NOT `seniority`. Each include entry is a separate Boolean title clause LinkedIn ORs. Two kinds: (1) single-title pills — exact exec titles + founder, one entry per variant (e.g. \"CEO\",\"Chief Executive Officer\",\"Founder\",\"Fundador\"); (2) ONE seniority-block pill for broad leadership roles: a marker AND a parenthesized OR-list of role synonyms, e.g. `<<SENIORITY_BLOCK_EN>> AND (\"growth\" OR \"demand generation\")`. The marker (one of <<SENIORITY_BLOCK_EN>> / <<SENIORITY_BLOCK_ES_EN>> / <<SENIORITY_BLOCK_PT_EN>>, by language) expands server-side to a broad leadership OR-block so you recall heads/VPs/directors/managers without enumerating titles. See the playbook for the full recipe. MATCHING: a pill matches a SET OF WORDS, not a phrase, and it matches a person across ALL of their CURRENT jobs. When you also scope by company, only their position AT THAT COMPANY is returned — so a hit whose shown title does not match your pills is usually a CORRECT match through a side venture, not a broken filter. `Founder`/`Co-Founder`/`Owner`/`CEO` anchored to a company list therefore mean \"anyone there who founded or owns anything, anywhere\"; to find who RUNS a company use `Gerente General`/`Director General`/`Managing Director`/`Country Manager`, and `linkedin_fetch` to check one odd hit.","type":"object","properties":{"include":{"type":"array","items":{"type":"string","minLength":1}},"exclude":{"type":"array","items":{"type":"string","minLength":1}}}},"seniority":{"description":"LinkedIn's coarse seniority ladder (cxo, vice_president, director, senior, …) — NOT job titles. Use only when you mean a seniority level; pair with `role` for \"VP-level whose title contains X\".","type":"object","properties":{"include":{"type":"array","items":{"type":"string","enum":["owner/partner","cxo","vice_president","director","experienced_manager","entry_level_manager","strategic","senior","entry_level","in_training"]}},"exclude":{"type":"array","items":{"type":"string","enum":["owner/partner","cxo","vice_president","director","experienced_manager","entry_level_manager","strategic","senior","entry_level","in_training"]}}}},"tenure":{"description":"Years at the current company in their current role, as {min,max} ranges. Years MUST be LinkedIn bucket breakpoints — valid min: 0, 1, 3, 6, 10; valid max: 1, 2, 5, 10 (buckets <1, 1-2, 3-5, 6-10, 10+). Any other value (e.g. min:5 or min:2) is rejected. So \"5+ years\" → {min:6}; \"3+ years\" → {min:3}; \"3 to 5 years\" → {min:3,max:5}.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"tenureAtCompany":{"description":"Total years at the current company, as {min,max} ranges. Years MUST be LinkedIn bucket breakpoints — valid min: 0, 1, 3, 6, 10; valid max: 1, 2, 5, 10 (buckets <1, 1-2, 3-5, 6-10, 10+). Any other value (e.g. min:5 or min:2) is rejected. So \"5+ years\" → {min:6}; \"3+ years\" → {min:3}; \"3 to 5 years\" → {min:3,max:5}.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"tenureAtRole":{"description":"Years in the current role, as {min,max} ranges. Years MUST be LinkedIn bucket breakpoints — valid min: 0, 1, 3, 6, 10; valid max: 1, 2, 5, 10 (buckets <1, 1-2, 3-5, 6-10, 10+). Any other value (e.g. min:5 or min:2) is rejected. So \"5+ years\" → {min:6}; \"3+ years\" → {min:3}; \"3 to 5 years\" → {min:3,max:5}.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"companyHeadcount":{"description":"Size band of the person's current employer (people search). For a company's OWN size use `headcount`. Approximate \"startup\" with small buckets ([\"1-10\",\"11-50\",\"51-200\"]).","type":"array","items":{"type":"string","enum":["1-10","11-50","51-200","201-500","501-1000","1001-5000","5001-10000","10001+"]}},"companyType":{"description":"Ownership type of the person's current employer (people search; e.g. privately_held, public_company). A companies search has no company-type facet.","type":"array","items":{"type":"string","enum":["public_company","privately_held","non_profit","educational_institution","partnership","self_employed","self_owned","government_agency"]}},"availableForWork":{"description":"Signals availability for a new role (#OpenToWork, or no current position). true requires it, false excludes it. Screened after the search, on loaded profiles only; unknown never counts as available.","anyOf":[{"type":"boolean"},{"type":"null"}]},"minFollowerCount":{"description":"Minimum LinkedIn follower count for a person. Screened after the search, on loaded profiles only; a profile whose follower count we could not read never passes.","anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"postedWithinDays":{"description":"Require an own post within this many days (1-365). Screened last, on loaded profiles only, and it costs one extra LinkedIn read; a person with no readable recent post never passes.","anyOf":[{"type":"integer","minimum":1,"maximum":365},{"type":"null"}]},"profileLanguage":{"description":"Profile languages as 2-letter ISO codes (e.g. [\"en\",\"es\"]).","type":"array","items":{"type":"string","minLength":2,"maxLength":2}},"networkDistance":{"description":"Connection degree from the operator: 1 / 2 / 3 — valid for BOTH people and companies. The \"GROUP\" value (shared group) is PEOPLE only; do not use it on a companies search. Answered only on the operator's OWN Sales Navigator seat. A degree IS a structured filter, so with the org's OWN Sales Navigator seat this is the right place to ask for \"my 1st-degree X\" — you keep the `role` / `seniority` precision classic search cannot express. Do NOT downgrade to `search_people` for it. `identity_get` says whether it can be answered here (`capabilities.viewerRelativeFilters`) — but do not gate the SEARCH on it: every other filter runs either way, so drop this one and keep the rest rather than leaving. When it cannot be answered the search says so and refuses THIS filter only; classic `search_people` with `networkDistance` is then the route, because it always runs on the operator's own seat. Never treat a Sales-Nav hit as connected: confirm before building a campaign that sends a direct message.","type":"array","items":{"anyOf":[{"type":"number","const":1},{"type":"number","const":2},{"type":"number","const":3},{"type":"string","const":"GROUP"}]}},"connectionsOf":{"description":"LinkedIn provider ids (`ACoAA…`, from people.suggest — NOT numeric member ids) whose connections to search within. Aimed at someone you are NOT connected to, this returns your MUTUAL connections with them — the people who could introduce you — matching the `shared_connections_count` on their profile. `networkDistance` defaults to [1] and must STAY [1] for such a target: at any other degree Sales Navigator silently discards this filter and answers with your entire 2nd-degree network, which looks like a real result. The one exception is a target you ARE connected to, where [2] validly returns everyone they know that you do not. Looking for an introduction to someone? Read the `warm-intro` skill first — this filter is one step of it, and the rest decides which of the people it returns can actually help. Like `networkDistance` this is relative to the SEAT, and works here whenever `identity_get`'s `capabilities.viewerRelativeFilters` is true. When it is not, the search refuses THIS filter and nothing else — classic `search_people` is the route for the introduction hunt, while every other Sales Navigator filter still runs here.","type":"array","items":{"type":"string"}},"changedJobs":{"description":"Spotlight: only people who recently changed jobs.","type":"boolean"},"postedOnLinkedin":{"type":"boolean"},"mentionedInNews":{"type":"boolean"},"followingYourCompany":{"type":"boolean"},"pastColleague":{"description":"Spotlight, relative to YOU: only people you actually worked with. Combined with `connectionsOf` it answers \"which of this person's connections are my own former colleagues\" — the shortest warm path there is. Expect a very small result; that is the point, not a misfire.","type":"boolean"},"sharedExperiences":{"description":"Spotlight, relative to YOU: only people who share a school, employer or group with you. The wider net beneath `pastColleague`, and the same combination with `connectionsOf` applies. The response never says WHICH experience is shared — membership in the result is the signal; load a profile to name the overlap.","type":"boolean"},"viewedYourProfileRecently":{"type":"boolean"},"viewedProfileRecently":{"type":"boolean"},"messagedRecently":{"type":"boolean"},"includeSavedLeads":{"type":"boolean"},"includeSavedAccounts":{"type":"boolean"},"hasJobOffers":{"description":"Company search: only companies currently hiring.","type":"boolean"},"headcount":{"description":"The company's OWN size band (companies search; the analog of people-search `companyHeadcount`). Approximate \"startup\" with small buckets ([\"1-10\",\"11-50\",\"51-200\"]).","type":"array","items":{"type":"string","enum":["1-10","11-50","51-200","201-500","501-1000","1001-5000","5001-10000","10001+"]}},"headcountGrowth":{"description":"Company headcount growth rate as a {min,max} percentage range.","type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}},"annualRevenue":{"description":"Company annual revenue {currency (ISO 4217), min, max} in millions. Both min AND max are required and MUST be breakpoints: 0, 0.2, 1, 2.5, 5, 10, 20, 50, 100, 500, 1000, 1001.","type":"object","properties":{"currency":{"type":"string","minLength":3,"maxLength":3},"min":{"type":"number"},"max":{"type":"number"}},"required":["currency","min","max"]},"followersCount":{"description":"COMPANY followers only — a companies search. Search has no filter for a PERSON's followers; check that with the ICP. {min,max} ranges. Breakpoints — min: 1, 51, 101, 1001, 5001; max: 50, 100, 1000, 5000.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"fortune":{"description":"Fortune ranking {min,max} ranges (e.g. Fortune 500). Breakpoints — min: 0, 51, 101, 251; max: 50, 100, 250, 500.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"recentActivities":{"description":"Company signals: senior_leadership_changes and/or funding_events.","type":"array","items":{"type":"string","enum":["senior_leadership_changes","funding_events"]}},"departmentHeadcount":{"type":"object","properties":{"department":{"type":"array","items":{"type":"string"}},"min":{"type":"number"},"max":{"type":"number"}},"required":["department"]},"departmentHeadcountGrowth":{"type":"object","properties":{"department":{"type":"array","items":{"type":"string"}},"min":{"type":"number"},"max":{"type":"number"}},"required":["department"]},"savedAccounts":{"type":"array","items":{"type":"string"}},"savedSearchId":{"type":"string","pattern":"^\\d+$"},"recentSearchId":{"type":"string","pattern":"^\\d+$"},"lastViewedAt":{"type":"number"},"withinArea":{"type":"number"}}},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"peopleSalesNavCriteria":{"anyOf":[{"type":"object","properties":{"category":{"default":"people","type":"string","enum":["people","companies"]},"keywords":{"description":"LAST resort — matches noisily across all text. Prefer a structured filter for any title/industry/geography/size intent; use keywords only for a concept no filter captures. This is a BOOLEAN query, not a phrase: bare space-separated words are AND-ed (ALL must appear), so \"fintech payments neobank\" requires all three together and usually returns ZERO. For ALTERNATIVES, OR them, quote each, and ALWAYS wrap the OR group in parentheses: `(\"fintech\" OR \"payments\" OR \"neobank\")`. The parentheses are MANDATORY — LinkedIn silently mis-parses an unparenthesized OR of 4+ terms and returns ~0. Quote multi-word phrases; combine groups with AND/NOT (e.g. `(\"fintech\" OR \"neobank\") AND \"payments\"`). Operators must be UPPERCASE.","type":"string","minLength":1,"maxLength":2000},"filters":{"description":"Id-resolved dimensions (location, industry, company, …). Same dimension repeated = OR; different dimensions = AND (each narrows the results).","maxItems":40,"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["location","industry","function","current_company","past_company","company_location","school","past_role","groups","persona","technologies","account_lists","lead_lists","postal_code"],"description":"Which id-resolved dimension. People: location, industry, function, current_company, past_company, company_location, school, past_role, groups, persona, account_lists, lead_lists, postal_code. Companies: location, industry, technologies, account_lists, postal_code — the rest are people-only and are REFUSED here rather than quietly ignored. On a companies search the company IS the subject, so its location is plain `location` (`company_location` is accepted as a synonym for it, and means the EMPLOYER’s location only on a people search). `groups` is measured from YOU, like the saved lists: LinkedIn only knows the groups your own account has JOINED, so it works only on your OWN Sales Navigator seat and is otherwise refused, rather than answered about a different audience. To reach the people in a group, use `group_members` instead — it reads the group’s own member list on your own seat: any public group, or a members-only one your seat has joined."},"query":{"type":"string","minLength":1,"maxLength":256,"description":"The value as a human-readable NAME (never an id). Phrase it the way LinkedIn names things — canonical industry names (\"Financial Services\", not \"fintech\"), real place names (\"Greater Madrid Metropolitan Area\" or the country). Resolution takes the best single typeahead match and echoes the resolved label back."},"mode":{"description":"\"include\" (default) requires the value; \"exclude\" filters it out.","type":"string","enum":["include","exclude"]}},"required":["type","query"]}},"cursor":{"description":"Pass the cursor from a prior result to page. It continues only the exact search that made it: send it with the SAME category and filters as the first page, or it is refused.","type":"string","maxLength":65536},"limit":{"description":"Page size (max 100 for Sales Nav; default 10). One page costs one metered action WHATEVER its size, so raise it when you are filling a list rather than sampling.","type":"integer","minimum":1,"maximum":100},"firstName":{"type":"string","minLength":1,"maxLength":128},"lastName":{"type":"string","minLength":1,"maxLength":128},"role":{"description":"Current job-TITLE keywords (include/exclude) — the primary people filter. Use it for ALL title intent, NOT `keywords` and NOT `seniority`. Each include entry is a separate Boolean title clause LinkedIn ORs. Two kinds: (1) single-title pills — exact exec titles + founder, one entry per variant (e.g. \"CEO\",\"Chief Executive Officer\",\"Founder\",\"Fundador\"); (2) ONE seniority-block pill for broad leadership roles: a marker AND a parenthesized OR-list of role synonyms, e.g. `<<SENIORITY_BLOCK_EN>> AND (\"growth\" OR \"demand generation\")`. The marker (one of <<SENIORITY_BLOCK_EN>> / <<SENIORITY_BLOCK_ES_EN>> / <<SENIORITY_BLOCK_PT_EN>>, by language) expands server-side to a broad leadership OR-block so you recall heads/VPs/directors/managers without enumerating titles. See the playbook for the full recipe. MATCHING: a pill matches a SET OF WORDS, not a phrase, and it matches a person across ALL of their CURRENT jobs. When you also scope by company, only their position AT THAT COMPANY is returned — so a hit whose shown title does not match your pills is usually a CORRECT match through a side venture, not a broken filter. `Founder`/`Co-Founder`/`Owner`/`CEO` anchored to a company list therefore mean \"anyone there who founded or owns anything, anywhere\"; to find who RUNS a company use `Gerente General`/`Director General`/`Managing Director`/`Country Manager`, and `linkedin_fetch` to check one odd hit.","type":"object","properties":{"include":{"type":"array","items":{"type":"string","minLength":1}},"exclude":{"type":"array","items":{"type":"string","minLength":1}}}},"seniority":{"description":"LinkedIn's coarse seniority ladder (cxo, vice_president, director, senior, …) — NOT job titles. Use only when you mean a seniority level; pair with `role` for \"VP-level whose title contains X\".","type":"object","properties":{"include":{"type":"array","items":{"type":"string","enum":["owner/partner","cxo","vice_president","director","experienced_manager","entry_level_manager","strategic","senior","entry_level","in_training"]}},"exclude":{"type":"array","items":{"type":"string","enum":["owner/partner","cxo","vice_president","director","experienced_manager","entry_level_manager","strategic","senior","entry_level","in_training"]}}}},"tenure":{"description":"Years at the current company in their current role, as {min,max} ranges. Years MUST be LinkedIn bucket breakpoints — valid min: 0, 1, 3, 6, 10; valid max: 1, 2, 5, 10 (buckets <1, 1-2, 3-5, 6-10, 10+). Any other value (e.g. min:5 or min:2) is rejected. So \"5+ years\" → {min:6}; \"3+ years\" → {min:3}; \"3 to 5 years\" → {min:3,max:5}.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"tenureAtCompany":{"description":"Total years at the current company, as {min,max} ranges. Years MUST be LinkedIn bucket breakpoints — valid min: 0, 1, 3, 6, 10; valid max: 1, 2, 5, 10 (buckets <1, 1-2, 3-5, 6-10, 10+). Any other value (e.g. min:5 or min:2) is rejected. So \"5+ years\" → {min:6}; \"3+ years\" → {min:3}; \"3 to 5 years\" → {min:3,max:5}.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"tenureAtRole":{"description":"Years in the current role, as {min,max} ranges. Years MUST be LinkedIn bucket breakpoints — valid min: 0, 1, 3, 6, 10; valid max: 1, 2, 5, 10 (buckets <1, 1-2, 3-5, 6-10, 10+). Any other value (e.g. min:5 or min:2) is rejected. So \"5+ years\" → {min:6}; \"3+ years\" → {min:3}; \"3 to 5 years\" → {min:3,max:5}.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"companyHeadcount":{"description":"Size band of the person's current employer (people search). For a company's OWN size use `headcount`. Approximate \"startup\" with small buckets ([\"1-10\",\"11-50\",\"51-200\"]).","type":"array","items":{"type":"string","enum":["1-10","11-50","51-200","201-500","501-1000","1001-5000","5001-10000","10001+"]}},"companyType":{"description":"Ownership type of the person's current employer (people search; e.g. privately_held, public_company). A companies search has no company-type facet.","type":"array","items":{"type":"string","enum":["public_company","privately_held","non_profit","educational_institution","partnership","self_employed","self_owned","government_agency"]}},"availableForWork":{"description":"Signals availability for a new role (#OpenToWork, or no current position). true requires it, false excludes it. Screened after the search, on loaded profiles only; unknown never counts as available.","anyOf":[{"type":"boolean"},{"type":"null"}]},"minFollowerCount":{"description":"Minimum LinkedIn follower count for a person. Screened after the search, on loaded profiles only; a profile whose follower count we could not read never passes.","anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"postedWithinDays":{"description":"Require an own post within this many days (1-365). Screened last, on loaded profiles only, and it costs one extra LinkedIn read; a person with no readable recent post never passes.","anyOf":[{"type":"integer","minimum":1,"maximum":365},{"type":"null"}]},"profileLanguage":{"description":"Profile languages as 2-letter ISO codes (e.g. [\"en\",\"es\"]).","type":"array","items":{"type":"string","minLength":2,"maxLength":2}},"networkDistance":{"description":"Connection degree from the operator: 1 / 2 / 3 — valid for BOTH people and companies. The \"GROUP\" value (shared group) is PEOPLE only; do not use it on a companies search. Answered only on the operator's OWN Sales Navigator seat. A degree IS a structured filter, so with the org's OWN Sales Navigator seat this is the right place to ask for \"my 1st-degree X\" — you keep the `role` / `seniority` precision classic search cannot express. Do NOT downgrade to `search_people` for it. `identity_get` says whether it can be answered here (`capabilities.viewerRelativeFilters`) — but do not gate the SEARCH on it: every other filter runs either way, so drop this one and keep the rest rather than leaving. When it cannot be answered the search says so and refuses THIS filter only; classic `search_people` with `networkDistance` is then the route, because it always runs on the operator's own seat. Never treat a Sales-Nav hit as connected: confirm before building a campaign that sends a direct message.","type":"array","items":{"anyOf":[{"type":"number","const":1},{"type":"number","const":2},{"type":"number","const":3},{"type":"string","const":"GROUP"}]}},"connectionsOf":{"description":"LinkedIn provider ids (`ACoAA…`, from people.suggest — NOT numeric member ids) whose connections to search within. Aimed at someone you are NOT connected to, this returns your MUTUAL connections with them — the people who could introduce you — matching the `shared_connections_count` on their profile. `networkDistance` defaults to [1] and must STAY [1] for such a target: at any other degree Sales Navigator silently discards this filter and answers with your entire 2nd-degree network, which looks like a real result. The one exception is a target you ARE connected to, where [2] validly returns everyone they know that you do not. Looking for an introduction to someone? Read the `warm-intro` skill first — this filter is one step of it, and the rest decides which of the people it returns can actually help. Like `networkDistance` this is relative to the SEAT, and works here whenever `identity_get`'s `capabilities.viewerRelativeFilters` is true. When it is not, the search refuses THIS filter and nothing else — classic `search_people` is the route for the introduction hunt, while every other Sales Navigator filter still runs here.","type":"array","items":{"type":"string"}},"changedJobs":{"description":"Spotlight: only people who recently changed jobs.","type":"boolean"},"postedOnLinkedin":{"type":"boolean"},"mentionedInNews":{"type":"boolean"},"followingYourCompany":{"type":"boolean"},"pastColleague":{"description":"Spotlight, relative to YOU: only people you actually worked with. Combined with `connectionsOf` it answers \"which of this person's connections are my own former colleagues\" — the shortest warm path there is. Expect a very small result; that is the point, not a misfire.","type":"boolean"},"sharedExperiences":{"description":"Spotlight, relative to YOU: only people who share a school, employer or group with you. The wider net beneath `pastColleague`, and the same combination with `connectionsOf` applies. The response never says WHICH experience is shared — membership in the result is the signal; load a profile to name the overlap.","type":"boolean"},"viewedYourProfileRecently":{"type":"boolean"},"viewedProfileRecently":{"type":"boolean"},"messagedRecently":{"type":"boolean"},"includeSavedLeads":{"type":"boolean"},"includeSavedAccounts":{"type":"boolean"},"hasJobOffers":{"description":"Company search: only companies currently hiring.","type":"boolean"},"headcount":{"description":"The company's OWN size band (companies search; the analog of people-search `companyHeadcount`). Approximate \"startup\" with small buckets ([\"1-10\",\"11-50\",\"51-200\"]).","type":"array","items":{"type":"string","enum":["1-10","11-50","51-200","201-500","501-1000","1001-5000","5001-10000","10001+"]}},"headcountGrowth":{"description":"Company headcount growth rate as a {min,max} percentage range.","type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}},"annualRevenue":{"description":"Company annual revenue {currency (ISO 4217), min, max} in millions. Both min AND max are required and MUST be breakpoints: 0, 0.2, 1, 2.5, 5, 10, 20, 50, 100, 500, 1000, 1001.","type":"object","properties":{"currency":{"type":"string","minLength":3,"maxLength":3},"min":{"type":"number"},"max":{"type":"number"}},"required":["currency","min","max"]},"followersCount":{"description":"COMPANY followers only — a companies search. Search has no filter for a PERSON's followers; check that with the ICP. {min,max} ranges. Breakpoints — min: 1, 51, 101, 1001, 5001; max: 50, 100, 1000, 5000.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"fortune":{"description":"Fortune ranking {min,max} ranges (e.g. Fortune 500). Breakpoints — min: 0, 51, 101, 251; max: 50, 100, 250, 500.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"recentActivities":{"description":"Company signals: senior_leadership_changes and/or funding_events.","type":"array","items":{"type":"string","enum":["senior_leadership_changes","funding_events"]}},"departmentHeadcount":{"type":"object","properties":{"department":{"type":"array","items":{"type":"string"}},"min":{"type":"number"},"max":{"type":"number"}},"required":["department"]},"departmentHeadcountGrowth":{"type":"object","properties":{"department":{"type":"array","items":{"type":"string"}},"min":{"type":"number"},"max":{"type":"number"}},"required":["department"]},"savedAccounts":{"type":"array","items":{"type":"string"}},"savedSearchId":{"type":"string","pattern":"^\\d+$"},"recentSearchId":{"type":"string","pattern":"^\\d+$"},"lastViewedAt":{"type":"number"},"withinArea":{"type":"number"}}},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"companyQualificationConditions":{"maxItems":200,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"description":{"type":"string","minLength":1,"maxLength":2000},"webSearch":{"type":"boolean"},"siteKeywords":{"type":"object","properties":{"include":{"maxItems":32,"type":"array","items":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[^\"]*$"}},"exclude":{"maxItems":32,"type":"array","items":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[^\"]*$"}}}}},"required":["description"]},"x-nestjs_zod-uses-3-point-1-syntax":true},"peopleQualificationConditions":{"maxItems":200,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"description":{"type":"string","minLength":1,"maxLength":2000},"webSearch":{"type":"boolean"},"siteKeywords":{"type":"object","properties":{"include":{"maxItems":32,"type":"array","items":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[^\"]*$"}},"exclude":{"maxItems":32,"type":"array","items":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[^\"]*$"}}}}},"required":["description"]},"x-nestjs_zod-uses-3-point-1-syntax":true},"strictFilters":{"type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true},"waiveMissingCompany":{"type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true},"name":{"type":"string","minLength":1,"maxLength":200,"x-nestjs_zod-uses-3-point-1-syntax":true}},"required":["name"]},"UpdateIcpDto":{"type":"object","properties":{"description":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"companySalesNavCriteria":{"anyOf":[{"type":"object","properties":{"category":{"default":"companies","type":"string","enum":["people","companies"]},"keywords":{"description":"LAST resort — matches noisily across all text. Prefer a structured filter for any title/industry/geography/size intent; use keywords only for a concept no filter captures. This is a BOOLEAN query, not a phrase: bare space-separated words are AND-ed (ALL must appear), so \"fintech payments neobank\" requires all three together and usually returns ZERO. For ALTERNATIVES, OR them, quote each, and ALWAYS wrap the OR group in parentheses: `(\"fintech\" OR \"payments\" OR \"neobank\")`. The parentheses are MANDATORY — LinkedIn silently mis-parses an unparenthesized OR of 4+ terms and returns ~0. Quote multi-word phrases; combine groups with AND/NOT (e.g. `(\"fintech\" OR \"neobank\") AND \"payments\"`). Operators must be UPPERCASE.","type":"string","minLength":1,"maxLength":2000},"filters":{"description":"Id-resolved dimensions (location, industry, company, …). Same dimension repeated = OR; different dimensions = AND (each narrows the results).","maxItems":40,"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["location","industry","function","current_company","past_company","company_location","school","past_role","groups","persona","technologies","account_lists","lead_lists","postal_code"],"description":"Which id-resolved dimension. People: location, industry, function, current_company, past_company, company_location, school, past_role, groups, persona, account_lists, lead_lists, postal_code. Companies: location, industry, technologies, account_lists, postal_code — the rest are people-only and are REFUSED here rather than quietly ignored. On a companies search the company IS the subject, so its location is plain `location` (`company_location` is accepted as a synonym for it, and means the EMPLOYER’s location only on a people search). `groups` is measured from YOU, like the saved lists: LinkedIn only knows the groups your own account has JOINED, so it works only on your OWN Sales Navigator seat and is otherwise refused, rather than answered about a different audience. To reach the people in a group, use `group_members` instead — it reads the group’s own member list on your own seat: any public group, or a members-only one your seat has joined."},"query":{"type":"string","minLength":1,"maxLength":256,"description":"The value as a human-readable NAME (never an id). Phrase it the way LinkedIn names things — canonical industry names (\"Financial Services\", not \"fintech\"), real place names (\"Greater Madrid Metropolitan Area\" or the country). Resolution takes the best single typeahead match and echoes the resolved label back."},"mode":{"description":"\"include\" (default) requires the value; \"exclude\" filters it out.","type":"string","enum":["include","exclude"]}},"required":["type","query"]}},"cursor":{"description":"Pass the cursor from a prior result to page. It continues only the exact search that made it: send it with the SAME category and filters as the first page, or it is refused.","type":"string","maxLength":65536},"limit":{"description":"Page size (max 100 for Sales Nav; default 10). One page costs one metered action WHATEVER its size, so raise it when you are filling a list rather than sampling.","type":"integer","minimum":1,"maximum":100},"firstName":{"type":"string","minLength":1,"maxLength":128},"lastName":{"type":"string","minLength":1,"maxLength":128},"role":{"description":"Current job-TITLE keywords (include/exclude) — the primary people filter. Use it for ALL title intent, NOT `keywords` and NOT `seniority`. Each include entry is a separate Boolean title clause LinkedIn ORs. Two kinds: (1) single-title pills — exact exec titles + founder, one entry per variant (e.g. \"CEO\",\"Chief Executive Officer\",\"Founder\",\"Fundador\"); (2) ONE seniority-block pill for broad leadership roles: a marker AND a parenthesized OR-list of role synonyms, e.g. `<<SENIORITY_BLOCK_EN>> AND (\"growth\" OR \"demand generation\")`. The marker (one of <<SENIORITY_BLOCK_EN>> / <<SENIORITY_BLOCK_ES_EN>> / <<SENIORITY_BLOCK_PT_EN>>, by language) expands server-side to a broad leadership OR-block so you recall heads/VPs/directors/managers without enumerating titles. See the playbook for the full recipe. MATCHING: a pill matches a SET OF WORDS, not a phrase, and it matches a person across ALL of their CURRENT jobs. When you also scope by company, only their position AT THAT COMPANY is returned — so a hit whose shown title does not match your pills is usually a CORRECT match through a side venture, not a broken filter. `Founder`/`Co-Founder`/`Owner`/`CEO` anchored to a company list therefore mean \"anyone there who founded or owns anything, anywhere\"; to find who RUNS a company use `Gerente General`/`Director General`/`Managing Director`/`Country Manager`, and `linkedin_fetch` to check one odd hit.","type":"object","properties":{"include":{"type":"array","items":{"type":"string","minLength":1}},"exclude":{"type":"array","items":{"type":"string","minLength":1}}}},"seniority":{"description":"LinkedIn's coarse seniority ladder (cxo, vice_president, director, senior, …) — NOT job titles. Use only when you mean a seniority level; pair with `role` for \"VP-level whose title contains X\".","type":"object","properties":{"include":{"type":"array","items":{"type":"string","enum":["owner/partner","cxo","vice_president","director","experienced_manager","entry_level_manager","strategic","senior","entry_level","in_training"]}},"exclude":{"type":"array","items":{"type":"string","enum":["owner/partner","cxo","vice_president","director","experienced_manager","entry_level_manager","strategic","senior","entry_level","in_training"]}}}},"tenure":{"description":"Years at the current company in their current role, as {min,max} ranges. Years MUST be LinkedIn bucket breakpoints — valid min: 0, 1, 3, 6, 10; valid max: 1, 2, 5, 10 (buckets <1, 1-2, 3-5, 6-10, 10+). Any other value (e.g. min:5 or min:2) is rejected. So \"5+ years\" → {min:6}; \"3+ years\" → {min:3}; \"3 to 5 years\" → {min:3,max:5}.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"tenureAtCompany":{"description":"Total years at the current company, as {min,max} ranges. Years MUST be LinkedIn bucket breakpoints — valid min: 0, 1, 3, 6, 10; valid max: 1, 2, 5, 10 (buckets <1, 1-2, 3-5, 6-10, 10+). Any other value (e.g. min:5 or min:2) is rejected. So \"5+ years\" → {min:6}; \"3+ years\" → {min:3}; \"3 to 5 years\" → {min:3,max:5}.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"tenureAtRole":{"description":"Years in the current role, as {min,max} ranges. Years MUST be LinkedIn bucket breakpoints — valid min: 0, 1, 3, 6, 10; valid max: 1, 2, 5, 10 (buckets <1, 1-2, 3-5, 6-10, 10+). Any other value (e.g. min:5 or min:2) is rejected. So \"5+ years\" → {min:6}; \"3+ years\" → {min:3}; \"3 to 5 years\" → {min:3,max:5}.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"companyHeadcount":{"description":"Size band of the person's current employer (people search). For a company's OWN size use `headcount`. Approximate \"startup\" with small buckets ([\"1-10\",\"11-50\",\"51-200\"]).","type":"array","items":{"type":"string","enum":["1-10","11-50","51-200","201-500","501-1000","1001-5000","5001-10000","10001+"]}},"companyType":{"description":"Ownership type of the person's current employer (people search; e.g. privately_held, public_company). A companies search has no company-type facet.","type":"array","items":{"type":"string","enum":["public_company","privately_held","non_profit","educational_institution","partnership","self_employed","self_owned","government_agency"]}},"availableForWork":{"description":"Signals availability for a new role (#OpenToWork, or no current position). true requires it, false excludes it. Screened after the search, on loaded profiles only; unknown never counts as available.","anyOf":[{"type":"boolean"},{"type":"null"}]},"minFollowerCount":{"description":"Minimum LinkedIn follower count for a person. Screened after the search, on loaded profiles only; a profile whose follower count we could not read never passes.","anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"postedWithinDays":{"description":"Require an own post within this many days (1-365). Screened last, on loaded profiles only, and it costs one extra LinkedIn read; a person with no readable recent post never passes.","anyOf":[{"type":"integer","minimum":1,"maximum":365},{"type":"null"}]},"profileLanguage":{"description":"Profile languages as 2-letter ISO codes (e.g. [\"en\",\"es\"]).","type":"array","items":{"type":"string","minLength":2,"maxLength":2}},"networkDistance":{"description":"Connection degree from the operator: 1 / 2 / 3 — valid for BOTH people and companies. The \"GROUP\" value (shared group) is PEOPLE only; do not use it on a companies search. Answered only on the operator's OWN Sales Navigator seat. A degree IS a structured filter, so with the org's OWN Sales Navigator seat this is the right place to ask for \"my 1st-degree X\" — you keep the `role` / `seniority` precision classic search cannot express. Do NOT downgrade to `search_people` for it. `identity_get` says whether it can be answered here (`capabilities.viewerRelativeFilters`) — but do not gate the SEARCH on it: every other filter runs either way, so drop this one and keep the rest rather than leaving. When it cannot be answered the search says so and refuses THIS filter only; classic `search_people` with `networkDistance` is then the route, because it always runs on the operator's own seat. Never treat a Sales-Nav hit as connected: confirm before building a campaign that sends a direct message.","type":"array","items":{"anyOf":[{"type":"number","const":1},{"type":"number","const":2},{"type":"number","const":3},{"type":"string","const":"GROUP"}]}},"connectionsOf":{"description":"LinkedIn provider ids (`ACoAA…`, from people.suggest — NOT numeric member ids) whose connections to search within. Aimed at someone you are NOT connected to, this returns your MUTUAL connections with them — the people who could introduce you — matching the `shared_connections_count` on their profile. `networkDistance` defaults to [1] and must STAY [1] for such a target: at any other degree Sales Navigator silently discards this filter and answers with your entire 2nd-degree network, which looks like a real result. The one exception is a target you ARE connected to, where [2] validly returns everyone they know that you do not. Looking for an introduction to someone? Read the `warm-intro` skill first — this filter is one step of it, and the rest decides which of the people it returns can actually help. Like `networkDistance` this is relative to the SEAT, and works here whenever `identity_get`'s `capabilities.viewerRelativeFilters` is true. When it is not, the search refuses THIS filter and nothing else — classic `search_people` is the route for the introduction hunt, while every other Sales Navigator filter still runs here.","type":"array","items":{"type":"string"}},"changedJobs":{"description":"Spotlight: only people who recently changed jobs.","type":"boolean"},"postedOnLinkedin":{"type":"boolean"},"mentionedInNews":{"type":"boolean"},"followingYourCompany":{"type":"boolean"},"pastColleague":{"description":"Spotlight, relative to YOU: only people you actually worked with. Combined with `connectionsOf` it answers \"which of this person's connections are my own former colleagues\" — the shortest warm path there is. Expect a very small result; that is the point, not a misfire.","type":"boolean"},"sharedExperiences":{"description":"Spotlight, relative to YOU: only people who share a school, employer or group with you. The wider net beneath `pastColleague`, and the same combination with `connectionsOf` applies. The response never says WHICH experience is shared — membership in the result is the signal; load a profile to name the overlap.","type":"boolean"},"viewedYourProfileRecently":{"type":"boolean"},"viewedProfileRecently":{"type":"boolean"},"messagedRecently":{"type":"boolean"},"includeSavedLeads":{"type":"boolean"},"includeSavedAccounts":{"type":"boolean"},"hasJobOffers":{"description":"Company search: only companies currently hiring.","type":"boolean"},"headcount":{"description":"The company's OWN size band (companies search; the analog of people-search `companyHeadcount`). Approximate \"startup\" with small buckets ([\"1-10\",\"11-50\",\"51-200\"]).","type":"array","items":{"type":"string","enum":["1-10","11-50","51-200","201-500","501-1000","1001-5000","5001-10000","10001+"]}},"headcountGrowth":{"description":"Company headcount growth rate as a {min,max} percentage range.","type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}},"annualRevenue":{"description":"Company annual revenue {currency (ISO 4217), min, max} in millions. Both min AND max are required and MUST be breakpoints: 0, 0.2, 1, 2.5, 5, 10, 20, 50, 100, 500, 1000, 1001.","type":"object","properties":{"currency":{"type":"string","minLength":3,"maxLength":3},"min":{"type":"number"},"max":{"type":"number"}},"required":["currency","min","max"]},"followersCount":{"description":"COMPANY followers only — a companies search. Search has no filter for a PERSON's followers; check that with the ICP. {min,max} ranges. Breakpoints — min: 1, 51, 101, 1001, 5001; max: 50, 100, 1000, 5000.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"fortune":{"description":"Fortune ranking {min,max} ranges (e.g. Fortune 500). Breakpoints — min: 0, 51, 101, 251; max: 50, 100, 250, 500.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"recentActivities":{"description":"Company signals: senior_leadership_changes and/or funding_events.","type":"array","items":{"type":"string","enum":["senior_leadership_changes","funding_events"]}},"departmentHeadcount":{"type":"object","properties":{"department":{"type":"array","items":{"type":"string"}},"min":{"type":"number"},"max":{"type":"number"}},"required":["department"]},"departmentHeadcountGrowth":{"type":"object","properties":{"department":{"type":"array","items":{"type":"string"}},"min":{"type":"number"},"max":{"type":"number"}},"required":["department"]},"savedAccounts":{"type":"array","items":{"type":"string"}},"savedSearchId":{"type":"string","pattern":"^\\d+$"},"recentSearchId":{"type":"string","pattern":"^\\d+$"},"lastViewedAt":{"type":"number"},"withinArea":{"type":"number"}}},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"peopleSalesNavCriteria":{"anyOf":[{"type":"object","properties":{"category":{"default":"people","type":"string","enum":["people","companies"]},"keywords":{"description":"LAST resort — matches noisily across all text. Prefer a structured filter for any title/industry/geography/size intent; use keywords only for a concept no filter captures. This is a BOOLEAN query, not a phrase: bare space-separated words are AND-ed (ALL must appear), so \"fintech payments neobank\" requires all three together and usually returns ZERO. For ALTERNATIVES, OR them, quote each, and ALWAYS wrap the OR group in parentheses: `(\"fintech\" OR \"payments\" OR \"neobank\")`. The parentheses are MANDATORY — LinkedIn silently mis-parses an unparenthesized OR of 4+ terms and returns ~0. Quote multi-word phrases; combine groups with AND/NOT (e.g. `(\"fintech\" OR \"neobank\") AND \"payments\"`). Operators must be UPPERCASE.","type":"string","minLength":1,"maxLength":2000},"filters":{"description":"Id-resolved dimensions (location, industry, company, …). Same dimension repeated = OR; different dimensions = AND (each narrows the results).","maxItems":40,"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["location","industry","function","current_company","past_company","company_location","school","past_role","groups","persona","technologies","account_lists","lead_lists","postal_code"],"description":"Which id-resolved dimension. People: location, industry, function, current_company, past_company, company_location, school, past_role, groups, persona, account_lists, lead_lists, postal_code. Companies: location, industry, technologies, account_lists, postal_code — the rest are people-only and are REFUSED here rather than quietly ignored. On a companies search the company IS the subject, so its location is plain `location` (`company_location` is accepted as a synonym for it, and means the EMPLOYER’s location only on a people search). `groups` is measured from YOU, like the saved lists: LinkedIn only knows the groups your own account has JOINED, so it works only on your OWN Sales Navigator seat and is otherwise refused, rather than answered about a different audience. To reach the people in a group, use `group_members` instead — it reads the group’s own member list on your own seat: any public group, or a members-only one your seat has joined."},"query":{"type":"string","minLength":1,"maxLength":256,"description":"The value as a human-readable NAME (never an id). Phrase it the way LinkedIn names things — canonical industry names (\"Financial Services\", not \"fintech\"), real place names (\"Greater Madrid Metropolitan Area\" or the country). Resolution takes the best single typeahead match and echoes the resolved label back."},"mode":{"description":"\"include\" (default) requires the value; \"exclude\" filters it out.","type":"string","enum":["include","exclude"]}},"required":["type","query"]}},"cursor":{"description":"Pass the cursor from a prior result to page. It continues only the exact search that made it: send it with the SAME category and filters as the first page, or it is refused.","type":"string","maxLength":65536},"limit":{"description":"Page size (max 100 for Sales Nav; default 10). One page costs one metered action WHATEVER its size, so raise it when you are filling a list rather than sampling.","type":"integer","minimum":1,"maximum":100},"firstName":{"type":"string","minLength":1,"maxLength":128},"lastName":{"type":"string","minLength":1,"maxLength":128},"role":{"description":"Current job-TITLE keywords (include/exclude) — the primary people filter. Use it for ALL title intent, NOT `keywords` and NOT `seniority`. Each include entry is a separate Boolean title clause LinkedIn ORs. Two kinds: (1) single-title pills — exact exec titles + founder, one entry per variant (e.g. \"CEO\",\"Chief Executive Officer\",\"Founder\",\"Fundador\"); (2) ONE seniority-block pill for broad leadership roles: a marker AND a parenthesized OR-list of role synonyms, e.g. `<<SENIORITY_BLOCK_EN>> AND (\"growth\" OR \"demand generation\")`. The marker (one of <<SENIORITY_BLOCK_EN>> / <<SENIORITY_BLOCK_ES_EN>> / <<SENIORITY_BLOCK_PT_EN>>, by language) expands server-side to a broad leadership OR-block so you recall heads/VPs/directors/managers without enumerating titles. See the playbook for the full recipe. MATCHING: a pill matches a SET OF WORDS, not a phrase, and it matches a person across ALL of their CURRENT jobs. When you also scope by company, only their position AT THAT COMPANY is returned — so a hit whose shown title does not match your pills is usually a CORRECT match through a side venture, not a broken filter. `Founder`/`Co-Founder`/`Owner`/`CEO` anchored to a company list therefore mean \"anyone there who founded or owns anything, anywhere\"; to find who RUNS a company use `Gerente General`/`Director General`/`Managing Director`/`Country Manager`, and `linkedin_fetch` to check one odd hit.","type":"object","properties":{"include":{"type":"array","items":{"type":"string","minLength":1}},"exclude":{"type":"array","items":{"type":"string","minLength":1}}}},"seniority":{"description":"LinkedIn's coarse seniority ladder (cxo, vice_president, director, senior, …) — NOT job titles. Use only when you mean a seniority level; pair with `role` for \"VP-level whose title contains X\".","type":"object","properties":{"include":{"type":"array","items":{"type":"string","enum":["owner/partner","cxo","vice_president","director","experienced_manager","entry_level_manager","strategic","senior","entry_level","in_training"]}},"exclude":{"type":"array","items":{"type":"string","enum":["owner/partner","cxo","vice_president","director","experienced_manager","entry_level_manager","strategic","senior","entry_level","in_training"]}}}},"tenure":{"description":"Years at the current company in their current role, as {min,max} ranges. Years MUST be LinkedIn bucket breakpoints — valid min: 0, 1, 3, 6, 10; valid max: 1, 2, 5, 10 (buckets <1, 1-2, 3-5, 6-10, 10+). Any other value (e.g. min:5 or min:2) is rejected. So \"5+ years\" → {min:6}; \"3+ years\" → {min:3}; \"3 to 5 years\" → {min:3,max:5}.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"tenureAtCompany":{"description":"Total years at the current company, as {min,max} ranges. Years MUST be LinkedIn bucket breakpoints — valid min: 0, 1, 3, 6, 10; valid max: 1, 2, 5, 10 (buckets <1, 1-2, 3-5, 6-10, 10+). Any other value (e.g. min:5 or min:2) is rejected. So \"5+ years\" → {min:6}; \"3+ years\" → {min:3}; \"3 to 5 years\" → {min:3,max:5}.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"tenureAtRole":{"description":"Years in the current role, as {min,max} ranges. Years MUST be LinkedIn bucket breakpoints — valid min: 0, 1, 3, 6, 10; valid max: 1, 2, 5, 10 (buckets <1, 1-2, 3-5, 6-10, 10+). Any other value (e.g. min:5 or min:2) is rejected. So \"5+ years\" → {min:6}; \"3+ years\" → {min:3}; \"3 to 5 years\" → {min:3,max:5}.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"companyHeadcount":{"description":"Size band of the person's current employer (people search). For a company's OWN size use `headcount`. Approximate \"startup\" with small buckets ([\"1-10\",\"11-50\",\"51-200\"]).","type":"array","items":{"type":"string","enum":["1-10","11-50","51-200","201-500","501-1000","1001-5000","5001-10000","10001+"]}},"companyType":{"description":"Ownership type of the person's current employer (people search; e.g. privately_held, public_company). A companies search has no company-type facet.","type":"array","items":{"type":"string","enum":["public_company","privately_held","non_profit","educational_institution","partnership","self_employed","self_owned","government_agency"]}},"availableForWork":{"description":"Signals availability for a new role (#OpenToWork, or no current position). true requires it, false excludes it. Screened after the search, on loaded profiles only; unknown never counts as available.","anyOf":[{"type":"boolean"},{"type":"null"}]},"minFollowerCount":{"description":"Minimum LinkedIn follower count for a person. Screened after the search, on loaded profiles only; a profile whose follower count we could not read never passes.","anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"postedWithinDays":{"description":"Require an own post within this many days (1-365). Screened last, on loaded profiles only, and it costs one extra LinkedIn read; a person with no readable recent post never passes.","anyOf":[{"type":"integer","minimum":1,"maximum":365},{"type":"null"}]},"profileLanguage":{"description":"Profile languages as 2-letter ISO codes (e.g. [\"en\",\"es\"]).","type":"array","items":{"type":"string","minLength":2,"maxLength":2}},"networkDistance":{"description":"Connection degree from the operator: 1 / 2 / 3 — valid for BOTH people and companies. The \"GROUP\" value (shared group) is PEOPLE only; do not use it on a companies search. Answered only on the operator's OWN Sales Navigator seat. A degree IS a structured filter, so with the org's OWN Sales Navigator seat this is the right place to ask for \"my 1st-degree X\" — you keep the `role` / `seniority` precision classic search cannot express. Do NOT downgrade to `search_people` for it. `identity_get` says whether it can be answered here (`capabilities.viewerRelativeFilters`) — but do not gate the SEARCH on it: every other filter runs either way, so drop this one and keep the rest rather than leaving. When it cannot be answered the search says so and refuses THIS filter only; classic `search_people` with `networkDistance` is then the route, because it always runs on the operator's own seat. Never treat a Sales-Nav hit as connected: confirm before building a campaign that sends a direct message.","type":"array","items":{"anyOf":[{"type":"number","const":1},{"type":"number","const":2},{"type":"number","const":3},{"type":"string","const":"GROUP"}]}},"connectionsOf":{"description":"LinkedIn provider ids (`ACoAA…`, from people.suggest — NOT numeric member ids) whose connections to search within. Aimed at someone you are NOT connected to, this returns your MUTUAL connections with them — the people who could introduce you — matching the `shared_connections_count` on their profile. `networkDistance` defaults to [1] and must STAY [1] for such a target: at any other degree Sales Navigator silently discards this filter and answers with your entire 2nd-degree network, which looks like a real result. The one exception is a target you ARE connected to, where [2] validly returns everyone they know that you do not. Looking for an introduction to someone? Read the `warm-intro` skill first — this filter is one step of it, and the rest decides which of the people it returns can actually help. Like `networkDistance` this is relative to the SEAT, and works here whenever `identity_get`'s `capabilities.viewerRelativeFilters` is true. When it is not, the search refuses THIS filter and nothing else — classic `search_people` is the route for the introduction hunt, while every other Sales Navigator filter still runs here.","type":"array","items":{"type":"string"}},"changedJobs":{"description":"Spotlight: only people who recently changed jobs.","type":"boolean"},"postedOnLinkedin":{"type":"boolean"},"mentionedInNews":{"type":"boolean"},"followingYourCompany":{"type":"boolean"},"pastColleague":{"description":"Spotlight, relative to YOU: only people you actually worked with. Combined with `connectionsOf` it answers \"which of this person's connections are my own former colleagues\" — the shortest warm path there is. Expect a very small result; that is the point, not a misfire.","type":"boolean"},"sharedExperiences":{"description":"Spotlight, relative to YOU: only people who share a school, employer or group with you. The wider net beneath `pastColleague`, and the same combination with `connectionsOf` applies. The response never says WHICH experience is shared — membership in the result is the signal; load a profile to name the overlap.","type":"boolean"},"viewedYourProfileRecently":{"type":"boolean"},"viewedProfileRecently":{"type":"boolean"},"messagedRecently":{"type":"boolean"},"includeSavedLeads":{"type":"boolean"},"includeSavedAccounts":{"type":"boolean"},"hasJobOffers":{"description":"Company search: only companies currently hiring.","type":"boolean"},"headcount":{"description":"The company's OWN size band (companies search; the analog of people-search `companyHeadcount`). Approximate \"startup\" with small buckets ([\"1-10\",\"11-50\",\"51-200\"]).","type":"array","items":{"type":"string","enum":["1-10","11-50","51-200","201-500","501-1000","1001-5000","5001-10000","10001+"]}},"headcountGrowth":{"description":"Company headcount growth rate as a {min,max} percentage range.","type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}},"annualRevenue":{"description":"Company annual revenue {currency (ISO 4217), min, max} in millions. Both min AND max are required and MUST be breakpoints: 0, 0.2, 1, 2.5, 5, 10, 20, 50, 100, 500, 1000, 1001.","type":"object","properties":{"currency":{"type":"string","minLength":3,"maxLength":3},"min":{"type":"number"},"max":{"type":"number"}},"required":["currency","min","max"]},"followersCount":{"description":"COMPANY followers only — a companies search. Search has no filter for a PERSON's followers; check that with the ICP. {min,max} ranges. Breakpoints — min: 1, 51, 101, 1001, 5001; max: 50, 100, 1000, 5000.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"fortune":{"description":"Fortune ranking {min,max} ranges (e.g. Fortune 500). Breakpoints — min: 0, 51, 101, 251; max: 50, 100, 250, 500.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"recentActivities":{"description":"Company signals: senior_leadership_changes and/or funding_events.","type":"array","items":{"type":"string","enum":["senior_leadership_changes","funding_events"]}},"departmentHeadcount":{"type":"object","properties":{"department":{"type":"array","items":{"type":"string"}},"min":{"type":"number"},"max":{"type":"number"}},"required":["department"]},"departmentHeadcountGrowth":{"type":"object","properties":{"department":{"type":"array","items":{"type":"string"}},"min":{"type":"number"},"max":{"type":"number"}},"required":["department"]},"savedAccounts":{"type":"array","items":{"type":"string"}},"savedSearchId":{"type":"string","pattern":"^\\d+$"},"recentSearchId":{"type":"string","pattern":"^\\d+$"},"lastViewedAt":{"type":"number"},"withinArea":{"type":"number"}}},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"companyQualificationConditions":{"maxItems":200,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"description":{"type":"string","minLength":1,"maxLength":2000},"webSearch":{"type":"boolean"},"siteKeywords":{"type":"object","properties":{"include":{"maxItems":32,"type":"array","items":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[^\"]*$"}},"exclude":{"maxItems":32,"type":"array","items":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[^\"]*$"}}}}},"required":["description"]},"x-nestjs_zod-uses-3-point-1-syntax":true},"peopleQualificationConditions":{"maxItems":200,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"description":{"type":"string","minLength":1,"maxLength":2000},"webSearch":{"type":"boolean"},"siteKeywords":{"type":"object","properties":{"include":{"maxItems":32,"type":"array","items":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[^\"]*$"}},"exclude":{"maxItems":32,"type":"array","items":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[^\"]*$"}}}}},"required":["description"]},"x-nestjs_zod-uses-3-point-1-syntax":true},"strictFilters":{"type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true},"waiveMissingCompany":{"type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true},"name":{"type":"string","minLength":1,"maxLength":200,"x-nestjs_zod-uses-3-point-1-syntax":true}}},"AgentIcpChatDto":{"type":"object","properties":{"messages":{"minItems":1,"maxItems":200,"type":"array","items":{},"x-nestjs_zod-uses-3-point-1-syntax":true},"model":{"type":"string","minLength":3,"maxLength":120,"pattern":"^[a-z0-9][a-z0-9._-]*\\/[a-z0-9][a-z0-9._:-]*$","x-nestjs_zod-uses-3-point-1-syntax":true},"effort":{"type":"string","enum":["minimal","low","medium","high"],"x-nestjs_zod-uses-3-point-1-syntax":true},"icpId":{"type":"string","minLength":1,"x-nestjs_zod-uses-3-point-1-syntax":true},"draftSnapshot":{"type":"object","properties":{"description":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}]},"companySalesNavCriteria":{"anyOf":[{"anyOf":[{"type":"object","properties":{"category":{"default":"companies","type":"string","enum":["people","companies"]},"keywords":{"description":"LAST resort — matches noisily across all text. Prefer a structured filter for any title/industry/geography/size intent; use keywords only for a concept no filter captures. This is a BOOLEAN query, not a phrase: bare space-separated words are AND-ed (ALL must appear), so \"fintech payments neobank\" requires all three together and usually returns ZERO. For ALTERNATIVES, OR them, quote each, and ALWAYS wrap the OR group in parentheses: `(\"fintech\" OR \"payments\" OR \"neobank\")`. The parentheses are MANDATORY — LinkedIn silently mis-parses an unparenthesized OR of 4+ terms and returns ~0. Quote multi-word phrases; combine groups with AND/NOT (e.g. `(\"fintech\" OR \"neobank\") AND \"payments\"`). Operators must be UPPERCASE.","type":"string","minLength":1,"maxLength":2000},"filters":{"description":"Id-resolved dimensions (location, industry, company, …). Same dimension repeated = OR; different dimensions = AND (each narrows the results).","maxItems":40,"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["location","industry","function","current_company","past_company","company_location","school","past_role","groups","persona","technologies","account_lists","lead_lists","postal_code"],"description":"Which id-resolved dimension. People: location, industry, function, current_company, past_company, company_location, school, past_role, groups, persona, account_lists, lead_lists, postal_code. Companies: location, industry, technologies, account_lists, postal_code — the rest are people-only and are REFUSED here rather than quietly ignored. On a companies search the company IS the subject, so its location is plain `location` (`company_location` is accepted as a synonym for it, and means the EMPLOYER’s location only on a people search). `groups` is measured from YOU, like the saved lists: LinkedIn only knows the groups your own account has JOINED, so it works only on your OWN Sales Navigator seat and is otherwise refused, rather than answered about a different audience. To reach the people in a group, use `group_members` instead — it reads the group’s own member list on your own seat: any public group, or a members-only one your seat has joined."},"query":{"type":"string","minLength":1,"maxLength":256,"description":"The value as a human-readable NAME (never an id). Phrase it the way LinkedIn names things — canonical industry names (\"Financial Services\", not \"fintech\"), real place names (\"Greater Madrid Metropolitan Area\" or the country). Resolution takes the best single typeahead match and echoes the resolved label back."},"mode":{"description":"\"include\" (default) requires the value; \"exclude\" filters it out.","type":"string","enum":["include","exclude"]}},"required":["type","query"]}},"cursor":{"description":"Pass the cursor from a prior result to page. It continues only the exact search that made it: send it with the SAME category and filters as the first page, or it is refused.","type":"string","maxLength":65536},"limit":{"description":"Page size (max 100 for Sales Nav; default 10). One page costs one metered action WHATEVER its size, so raise it when you are filling a list rather than sampling.","type":"integer","minimum":1,"maximum":100},"firstName":{"type":"string","minLength":1,"maxLength":128},"lastName":{"type":"string","minLength":1,"maxLength":128},"role":{"description":"Current job-TITLE keywords (include/exclude) — the primary people filter. Use it for ALL title intent, NOT `keywords` and NOT `seniority`. Each include entry is a separate Boolean title clause LinkedIn ORs. Two kinds: (1) single-title pills — exact exec titles + founder, one entry per variant (e.g. \"CEO\",\"Chief Executive Officer\",\"Founder\",\"Fundador\"); (2) ONE seniority-block pill for broad leadership roles: a marker AND a parenthesized OR-list of role synonyms, e.g. `<<SENIORITY_BLOCK_EN>> AND (\"growth\" OR \"demand generation\")`. The marker (one of <<SENIORITY_BLOCK_EN>> / <<SENIORITY_BLOCK_ES_EN>> / <<SENIORITY_BLOCK_PT_EN>>, by language) expands server-side to a broad leadership OR-block so you recall heads/VPs/directors/managers without enumerating titles. See the playbook for the full recipe. MATCHING: a pill matches a SET OF WORDS, not a phrase, and it matches a person across ALL of their CURRENT jobs. When you also scope by company, only their position AT THAT COMPANY is returned — so a hit whose shown title does not match your pills is usually a CORRECT match through a side venture, not a broken filter. `Founder`/`Co-Founder`/`Owner`/`CEO` anchored to a company list therefore mean \"anyone there who founded or owns anything, anywhere\"; to find who RUNS a company use `Gerente General`/`Director General`/`Managing Director`/`Country Manager`, and `linkedin_fetch` to check one odd hit.","type":"object","properties":{"include":{"type":"array","items":{"type":"string","minLength":1}},"exclude":{"type":"array","items":{"type":"string","minLength":1}}}},"seniority":{"description":"LinkedIn's coarse seniority ladder (cxo, vice_president, director, senior, …) — NOT job titles. Use only when you mean a seniority level; pair with `role` for \"VP-level whose title contains X\".","type":"object","properties":{"include":{"type":"array","items":{"type":"string","enum":["owner/partner","cxo","vice_president","director","experienced_manager","entry_level_manager","strategic","senior","entry_level","in_training"]}},"exclude":{"type":"array","items":{"type":"string","enum":["owner/partner","cxo","vice_president","director","experienced_manager","entry_level_manager","strategic","senior","entry_level","in_training"]}}}},"tenure":{"description":"Years at the current company in their current role, as {min,max} ranges. Years MUST be LinkedIn bucket breakpoints — valid min: 0, 1, 3, 6, 10; valid max: 1, 2, 5, 10 (buckets <1, 1-2, 3-5, 6-10, 10+). Any other value (e.g. min:5 or min:2) is rejected. So \"5+ years\" → {min:6}; \"3+ years\" → {min:3}; \"3 to 5 years\" → {min:3,max:5}.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"tenureAtCompany":{"description":"Total years at the current company, as {min,max} ranges. Years MUST be LinkedIn bucket breakpoints — valid min: 0, 1, 3, 6, 10; valid max: 1, 2, 5, 10 (buckets <1, 1-2, 3-5, 6-10, 10+). Any other value (e.g. min:5 or min:2) is rejected. So \"5+ years\" → {min:6}; \"3+ years\" → {min:3}; \"3 to 5 years\" → {min:3,max:5}.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"tenureAtRole":{"description":"Years in the current role, as {min,max} ranges. Years MUST be LinkedIn bucket breakpoints — valid min: 0, 1, 3, 6, 10; valid max: 1, 2, 5, 10 (buckets <1, 1-2, 3-5, 6-10, 10+). Any other value (e.g. min:5 or min:2) is rejected. So \"5+ years\" → {min:6}; \"3+ years\" → {min:3}; \"3 to 5 years\" → {min:3,max:5}.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"companyHeadcount":{"description":"Size band of the person's current employer (people search). For a company's OWN size use `headcount`. Approximate \"startup\" with small buckets ([\"1-10\",\"11-50\",\"51-200\"]).","type":"array","items":{"type":"string","enum":["1-10","11-50","51-200","201-500","501-1000","1001-5000","5001-10000","10001+"]}},"companyType":{"description":"Ownership type of the person's current employer (people search; e.g. privately_held, public_company). A companies search has no company-type facet.","type":"array","items":{"type":"string","enum":["public_company","privately_held","non_profit","educational_institution","partnership","self_employed","self_owned","government_agency"]}},"availableForWork":{"description":"Signals availability for a new role (#OpenToWork, or no current position). true requires it, false excludes it. Screened after the search, on loaded profiles only; unknown never counts as available.","anyOf":[{"type":"boolean"},{"type":"null"}]},"minFollowerCount":{"description":"Minimum LinkedIn follower count for a person. Screened after the search, on loaded profiles only; a profile whose follower count we could not read never passes.","anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"postedWithinDays":{"description":"Require an own post within this many days (1-365). Screened last, on loaded profiles only, and it costs one extra LinkedIn read; a person with no readable recent post never passes.","anyOf":[{"type":"integer","minimum":1,"maximum":365},{"type":"null"}]},"profileLanguage":{"description":"Profile languages as 2-letter ISO codes (e.g. [\"en\",\"es\"]).","type":"array","items":{"type":"string","minLength":2,"maxLength":2}},"networkDistance":{"description":"Connection degree from the operator: 1 / 2 / 3 — valid for BOTH people and companies. The \"GROUP\" value (shared group) is PEOPLE only; do not use it on a companies search. Answered only on the operator's OWN Sales Navigator seat. A degree IS a structured filter, so with the org's OWN Sales Navigator seat this is the right place to ask for \"my 1st-degree X\" — you keep the `role` / `seniority` precision classic search cannot express. Do NOT downgrade to `search_people` for it. `identity_get` says whether it can be answered here (`capabilities.viewerRelativeFilters`) — but do not gate the SEARCH on it: every other filter runs either way, so drop this one and keep the rest rather than leaving. When it cannot be answered the search says so and refuses THIS filter only; classic `search_people` with `networkDistance` is then the route, because it always runs on the operator's own seat. Never treat a Sales-Nav hit as connected: confirm before building a campaign that sends a direct message.","type":"array","items":{"anyOf":[{"type":"number","const":1},{"type":"number","const":2},{"type":"number","const":3},{"type":"string","const":"GROUP"}]}},"connectionsOf":{"description":"LinkedIn provider ids (`ACoAA…`, from people.suggest — NOT numeric member ids) whose connections to search within. Aimed at someone you are NOT connected to, this returns your MUTUAL connections with them — the people who could introduce you — matching the `shared_connections_count` on their profile. `networkDistance` defaults to [1] and must STAY [1] for such a target: at any other degree Sales Navigator silently discards this filter and answers with your entire 2nd-degree network, which looks like a real result. The one exception is a target you ARE connected to, where [2] validly returns everyone they know that you do not. Looking for an introduction to someone? Read the `warm-intro` skill first — this filter is one step of it, and the rest decides which of the people it returns can actually help. Like `networkDistance` this is relative to the SEAT, and works here whenever `identity_get`'s `capabilities.viewerRelativeFilters` is true. When it is not, the search refuses THIS filter and nothing else — classic `search_people` is the route for the introduction hunt, while every other Sales Navigator filter still runs here.","type":"array","items":{"type":"string"}},"changedJobs":{"description":"Spotlight: only people who recently changed jobs.","type":"boolean"},"postedOnLinkedin":{"type":"boolean"},"mentionedInNews":{"type":"boolean"},"followingYourCompany":{"type":"boolean"},"pastColleague":{"description":"Spotlight, relative to YOU: only people you actually worked with. Combined with `connectionsOf` it answers \"which of this person's connections are my own former colleagues\" — the shortest warm path there is. Expect a very small result; that is the point, not a misfire.","type":"boolean"},"sharedExperiences":{"description":"Spotlight, relative to YOU: only people who share a school, employer or group with you. The wider net beneath `pastColleague`, and the same combination with `connectionsOf` applies. The response never says WHICH experience is shared — membership in the result is the signal; load a profile to name the overlap.","type":"boolean"},"viewedYourProfileRecently":{"type":"boolean"},"viewedProfileRecently":{"type":"boolean"},"messagedRecently":{"type":"boolean"},"includeSavedLeads":{"type":"boolean"},"includeSavedAccounts":{"type":"boolean"},"hasJobOffers":{"description":"Company search: only companies currently hiring.","type":"boolean"},"headcount":{"description":"The company's OWN size band (companies search; the analog of people-search `companyHeadcount`). Approximate \"startup\" with small buckets ([\"1-10\",\"11-50\",\"51-200\"]).","type":"array","items":{"type":"string","enum":["1-10","11-50","51-200","201-500","501-1000","1001-5000","5001-10000","10001+"]}},"headcountGrowth":{"description":"Company headcount growth rate as a {min,max} percentage range.","type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}},"annualRevenue":{"description":"Company annual revenue {currency (ISO 4217), min, max} in millions. Both min AND max are required and MUST be breakpoints: 0, 0.2, 1, 2.5, 5, 10, 20, 50, 100, 500, 1000, 1001.","type":"object","properties":{"currency":{"type":"string","minLength":3,"maxLength":3},"min":{"type":"number"},"max":{"type":"number"}},"required":["currency","min","max"]},"followersCount":{"description":"COMPANY followers only — a companies search. Search has no filter for a PERSON's followers; check that with the ICP. {min,max} ranges. Breakpoints — min: 1, 51, 101, 1001, 5001; max: 50, 100, 1000, 5000.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"fortune":{"description":"Fortune ranking {min,max} ranges (e.g. Fortune 500). Breakpoints — min: 0, 51, 101, 251; max: 50, 100, 250, 500.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"recentActivities":{"description":"Company signals: senior_leadership_changes and/or funding_events.","type":"array","items":{"type":"string","enum":["senior_leadership_changes","funding_events"]}},"departmentHeadcount":{"type":"object","properties":{"department":{"type":"array","items":{"type":"string"}},"min":{"type":"number"},"max":{"type":"number"}},"required":["department"]},"departmentHeadcountGrowth":{"type":"object","properties":{"department":{"type":"array","items":{"type":"string"}},"min":{"type":"number"},"max":{"type":"number"}},"required":["department"]},"savedAccounts":{"type":"array","items":{"type":"string"}},"savedSearchId":{"type":"string","pattern":"^\\d+$"},"recentSearchId":{"type":"string","pattern":"^\\d+$"},"lastViewedAt":{"type":"number"},"withinArea":{"type":"number"}}},{"type":"null"}]},{"type":"null"}]},"peopleSalesNavCriteria":{"anyOf":[{"anyOf":[{"type":"object","properties":{"category":{"default":"people","type":"string","enum":["people","companies"]},"keywords":{"description":"LAST resort — matches noisily across all text. Prefer a structured filter for any title/industry/geography/size intent; use keywords only for a concept no filter captures. This is a BOOLEAN query, not a phrase: bare space-separated words are AND-ed (ALL must appear), so \"fintech payments neobank\" requires all three together and usually returns ZERO. For ALTERNATIVES, OR them, quote each, and ALWAYS wrap the OR group in parentheses: `(\"fintech\" OR \"payments\" OR \"neobank\")`. The parentheses are MANDATORY — LinkedIn silently mis-parses an unparenthesized OR of 4+ terms and returns ~0. Quote multi-word phrases; combine groups with AND/NOT (e.g. `(\"fintech\" OR \"neobank\") AND \"payments\"`). Operators must be UPPERCASE.","type":"string","minLength":1,"maxLength":2000},"filters":{"description":"Id-resolved dimensions (location, industry, company, …). Same dimension repeated = OR; different dimensions = AND (each narrows the results).","maxItems":40,"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["location","industry","function","current_company","past_company","company_location","school","past_role","groups","persona","technologies","account_lists","lead_lists","postal_code"],"description":"Which id-resolved dimension. People: location, industry, function, current_company, past_company, company_location, school, past_role, groups, persona, account_lists, lead_lists, postal_code. Companies: location, industry, technologies, account_lists, postal_code — the rest are people-only and are REFUSED here rather than quietly ignored. On a companies search the company IS the subject, so its location is plain `location` (`company_location` is accepted as a synonym for it, and means the EMPLOYER’s location only on a people search). `groups` is measured from YOU, like the saved lists: LinkedIn only knows the groups your own account has JOINED, so it works only on your OWN Sales Navigator seat and is otherwise refused, rather than answered about a different audience. To reach the people in a group, use `group_members` instead — it reads the group’s own member list on your own seat: any public group, or a members-only one your seat has joined."},"query":{"type":"string","minLength":1,"maxLength":256,"description":"The value as a human-readable NAME (never an id). Phrase it the way LinkedIn names things — canonical industry names (\"Financial Services\", not \"fintech\"), real place names (\"Greater Madrid Metropolitan Area\" or the country). Resolution takes the best single typeahead match and echoes the resolved label back."},"mode":{"description":"\"include\" (default) requires the value; \"exclude\" filters it out.","type":"string","enum":["include","exclude"]}},"required":["type","query"]}},"cursor":{"description":"Pass the cursor from a prior result to page. It continues only the exact search that made it: send it with the SAME category and filters as the first page, or it is refused.","type":"string","maxLength":65536},"limit":{"description":"Page size (max 100 for Sales Nav; default 10). One page costs one metered action WHATEVER its size, so raise it when you are filling a list rather than sampling.","type":"integer","minimum":1,"maximum":100},"firstName":{"type":"string","minLength":1,"maxLength":128},"lastName":{"type":"string","minLength":1,"maxLength":128},"role":{"description":"Current job-TITLE keywords (include/exclude) — the primary people filter. Use it for ALL title intent, NOT `keywords` and NOT `seniority`. Each include entry is a separate Boolean title clause LinkedIn ORs. Two kinds: (1) single-title pills — exact exec titles + founder, one entry per variant (e.g. \"CEO\",\"Chief Executive Officer\",\"Founder\",\"Fundador\"); (2) ONE seniority-block pill for broad leadership roles: a marker AND a parenthesized OR-list of role synonyms, e.g. `<<SENIORITY_BLOCK_EN>> AND (\"growth\" OR \"demand generation\")`. The marker (one of <<SENIORITY_BLOCK_EN>> / <<SENIORITY_BLOCK_ES_EN>> / <<SENIORITY_BLOCK_PT_EN>>, by language) expands server-side to a broad leadership OR-block so you recall heads/VPs/directors/managers without enumerating titles. See the playbook for the full recipe. MATCHING: a pill matches a SET OF WORDS, not a phrase, and it matches a person across ALL of their CURRENT jobs. When you also scope by company, only their position AT THAT COMPANY is returned — so a hit whose shown title does not match your pills is usually a CORRECT match through a side venture, not a broken filter. `Founder`/`Co-Founder`/`Owner`/`CEO` anchored to a company list therefore mean \"anyone there who founded or owns anything, anywhere\"; to find who RUNS a company use `Gerente General`/`Director General`/`Managing Director`/`Country Manager`, and `linkedin_fetch` to check one odd hit.","type":"object","properties":{"include":{"type":"array","items":{"type":"string","minLength":1}},"exclude":{"type":"array","items":{"type":"string","minLength":1}}}},"seniority":{"description":"LinkedIn's coarse seniority ladder (cxo, vice_president, director, senior, …) — NOT job titles. Use only when you mean a seniority level; pair with `role` for \"VP-level whose title contains X\".","type":"object","properties":{"include":{"type":"array","items":{"type":"string","enum":["owner/partner","cxo","vice_president","director","experienced_manager","entry_level_manager","strategic","senior","entry_level","in_training"]}},"exclude":{"type":"array","items":{"type":"string","enum":["owner/partner","cxo","vice_president","director","experienced_manager","entry_level_manager","strategic","senior","entry_level","in_training"]}}}},"tenure":{"description":"Years at the current company in their current role, as {min,max} ranges. Years MUST be LinkedIn bucket breakpoints — valid min: 0, 1, 3, 6, 10; valid max: 1, 2, 5, 10 (buckets <1, 1-2, 3-5, 6-10, 10+). Any other value (e.g. min:5 or min:2) is rejected. So \"5+ years\" → {min:6}; \"3+ years\" → {min:3}; \"3 to 5 years\" → {min:3,max:5}.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"tenureAtCompany":{"description":"Total years at the current company, as {min,max} ranges. Years MUST be LinkedIn bucket breakpoints — valid min: 0, 1, 3, 6, 10; valid max: 1, 2, 5, 10 (buckets <1, 1-2, 3-5, 6-10, 10+). Any other value (e.g. min:5 or min:2) is rejected. So \"5+ years\" → {min:6}; \"3+ years\" → {min:3}; \"3 to 5 years\" → {min:3,max:5}.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"tenureAtRole":{"description":"Years in the current role, as {min,max} ranges. Years MUST be LinkedIn bucket breakpoints — valid min: 0, 1, 3, 6, 10; valid max: 1, 2, 5, 10 (buckets <1, 1-2, 3-5, 6-10, 10+). Any other value (e.g. min:5 or min:2) is rejected. So \"5+ years\" → {min:6}; \"3+ years\" → {min:3}; \"3 to 5 years\" → {min:3,max:5}.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"companyHeadcount":{"description":"Size band of the person's current employer (people search). For a company's OWN size use `headcount`. Approximate \"startup\" with small buckets ([\"1-10\",\"11-50\",\"51-200\"]).","type":"array","items":{"type":"string","enum":["1-10","11-50","51-200","201-500","501-1000","1001-5000","5001-10000","10001+"]}},"companyType":{"description":"Ownership type of the person's current employer (people search; e.g. privately_held, public_company). A companies search has no company-type facet.","type":"array","items":{"type":"string","enum":["public_company","privately_held","non_profit","educational_institution","partnership","self_employed","self_owned","government_agency"]}},"availableForWork":{"description":"Signals availability for a new role (#OpenToWork, or no current position). true requires it, false excludes it. Screened after the search, on loaded profiles only; unknown never counts as available.","anyOf":[{"type":"boolean"},{"type":"null"}]},"minFollowerCount":{"description":"Minimum LinkedIn follower count for a person. Screened after the search, on loaded profiles only; a profile whose follower count we could not read never passes.","anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"postedWithinDays":{"description":"Require an own post within this many days (1-365). Screened last, on loaded profiles only, and it costs one extra LinkedIn read; a person with no readable recent post never passes.","anyOf":[{"type":"integer","minimum":1,"maximum":365},{"type":"null"}]},"profileLanguage":{"description":"Profile languages as 2-letter ISO codes (e.g. [\"en\",\"es\"]).","type":"array","items":{"type":"string","minLength":2,"maxLength":2}},"networkDistance":{"description":"Connection degree from the operator: 1 / 2 / 3 — valid for BOTH people and companies. The \"GROUP\" value (shared group) is PEOPLE only; do not use it on a companies search. Answered only on the operator's OWN Sales Navigator seat. A degree IS a structured filter, so with the org's OWN Sales Navigator seat this is the right place to ask for \"my 1st-degree X\" — you keep the `role` / `seniority` precision classic search cannot express. Do NOT downgrade to `search_people` for it. `identity_get` says whether it can be answered here (`capabilities.viewerRelativeFilters`) — but do not gate the SEARCH on it: every other filter runs either way, so drop this one and keep the rest rather than leaving. When it cannot be answered the search says so and refuses THIS filter only; classic `search_people` with `networkDistance` is then the route, because it always runs on the operator's own seat. Never treat a Sales-Nav hit as connected: confirm before building a campaign that sends a direct message.","type":"array","items":{"anyOf":[{"type":"number","const":1},{"type":"number","const":2},{"type":"number","const":3},{"type":"string","const":"GROUP"}]}},"connectionsOf":{"description":"LinkedIn provider ids (`ACoAA…`, from people.suggest — NOT numeric member ids) whose connections to search within. Aimed at someone you are NOT connected to, this returns your MUTUAL connections with them — the people who could introduce you — matching the `shared_connections_count` on their profile. `networkDistance` defaults to [1] and must STAY [1] for such a target: at any other degree Sales Navigator silently discards this filter and answers with your entire 2nd-degree network, which looks like a real result. The one exception is a target you ARE connected to, where [2] validly returns everyone they know that you do not. Looking for an introduction to someone? Read the `warm-intro` skill first — this filter is one step of it, and the rest decides which of the people it returns can actually help. Like `networkDistance` this is relative to the SEAT, and works here whenever `identity_get`'s `capabilities.viewerRelativeFilters` is true. When it is not, the search refuses THIS filter and nothing else — classic `search_people` is the route for the introduction hunt, while every other Sales Navigator filter still runs here.","type":"array","items":{"type":"string"}},"changedJobs":{"description":"Spotlight: only people who recently changed jobs.","type":"boolean"},"postedOnLinkedin":{"type":"boolean"},"mentionedInNews":{"type":"boolean"},"followingYourCompany":{"type":"boolean"},"pastColleague":{"description":"Spotlight, relative to YOU: only people you actually worked with. Combined with `connectionsOf` it answers \"which of this person's connections are my own former colleagues\" — the shortest warm path there is. Expect a very small result; that is the point, not a misfire.","type":"boolean"},"sharedExperiences":{"description":"Spotlight, relative to YOU: only people who share a school, employer or group with you. The wider net beneath `pastColleague`, and the same combination with `connectionsOf` applies. The response never says WHICH experience is shared — membership in the result is the signal; load a profile to name the overlap.","type":"boolean"},"viewedYourProfileRecently":{"type":"boolean"},"viewedProfileRecently":{"type":"boolean"},"messagedRecently":{"type":"boolean"},"includeSavedLeads":{"type":"boolean"},"includeSavedAccounts":{"type":"boolean"},"hasJobOffers":{"description":"Company search: only companies currently hiring.","type":"boolean"},"headcount":{"description":"The company's OWN size band (companies search; the analog of people-search `companyHeadcount`). Approximate \"startup\" with small buckets ([\"1-10\",\"11-50\",\"51-200\"]).","type":"array","items":{"type":"string","enum":["1-10","11-50","51-200","201-500","501-1000","1001-5000","5001-10000","10001+"]}},"headcountGrowth":{"description":"Company headcount growth rate as a {min,max} percentage range.","type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}},"annualRevenue":{"description":"Company annual revenue {currency (ISO 4217), min, max} in millions. Both min AND max are required and MUST be breakpoints: 0, 0.2, 1, 2.5, 5, 10, 20, 50, 100, 500, 1000, 1001.","type":"object","properties":{"currency":{"type":"string","minLength":3,"maxLength":3},"min":{"type":"number"},"max":{"type":"number"}},"required":["currency","min","max"]},"followersCount":{"description":"COMPANY followers only — a companies search. Search has no filter for a PERSON's followers; check that with the ICP. {min,max} ranges. Breakpoints — min: 1, 51, 101, 1001, 5001; max: 50, 100, 1000, 5000.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"fortune":{"description":"Fortune ranking {min,max} ranges (e.g. Fortune 500). Breakpoints — min: 0, 51, 101, 251; max: 50, 100, 250, 500.","type":"array","items":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"}}}},"recentActivities":{"description":"Company signals: senior_leadership_changes and/or funding_events.","type":"array","items":{"type":"string","enum":["senior_leadership_changes","funding_events"]}},"departmentHeadcount":{"type":"object","properties":{"department":{"type":"array","items":{"type":"string"}},"min":{"type":"number"},"max":{"type":"number"}},"required":["department"]},"departmentHeadcountGrowth":{"type":"object","properties":{"department":{"type":"array","items":{"type":"string"}},"min":{"type":"number"},"max":{"type":"number"}},"required":["department"]},"savedAccounts":{"type":"array","items":{"type":"string"}},"savedSearchId":{"type":"string","pattern":"^\\d+$"},"recentSearchId":{"type":"string","pattern":"^\\d+$"},"lastViewedAt":{"type":"number"},"withinArea":{"type":"number"}}},{"type":"null"}]},{"type":"null"}]},"companyQualificationConditions":{"maxItems":200,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"description":{"type":"string","minLength":1,"maxLength":2000},"webSearch":{"type":"boolean"},"siteKeywords":{"type":"object","properties":{"include":{"maxItems":32,"type":"array","items":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[^\"]*$"}},"exclude":{"maxItems":32,"type":"array","items":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[^\"]*$"}}}}},"required":["description"]}},"peopleQualificationConditions":{"maxItems":200,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128},"description":{"type":"string","minLength":1,"maxLength":2000},"webSearch":{"type":"boolean"},"siteKeywords":{"type":"object","properties":{"include":{"maxItems":32,"type":"array","items":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[^\"]*$"}},"exclude":{"maxItems":32,"type":"array","items":{"type":"string","minLength":1,"maxLength":120,"pattern":"^[^\"]*$"}}}}},"required":["description"]}},"strictFilters":{"type":"boolean"},"waiveMissingCompany":{"type":"boolean"},"name":{"type":"string","maxLength":200}},"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-self-required":false}},"required":["messages"]},"AgentValuePropChatDto":{"type":"object","properties":{"messages":{"minItems":1,"maxItems":200,"type":"array","items":{}},"model":{"type":"string","minLength":3,"maxLength":120,"pattern":"^[a-z0-9][a-z0-9._-]*\\/[a-z0-9][a-z0-9._:-]*$"},"effort":{"type":"string","enum":["minimal","low","medium","high"]},"draftSnapshot":{"type":"string"}},"required":["messages"]},"AgentSignalsChatDto":{"type":"object","properties":{"messages":{"minItems":1,"maxItems":200,"type":"array","items":{},"x-nestjs_zod-uses-3-point-1-syntax":true},"model":{"type":"string","minLength":3,"maxLength":120,"pattern":"^[a-z0-9][a-z0-9._-]*\\/[a-z0-9][a-z0-9._:-]*$","x-nestjs_zod-uses-3-point-1-syntax":true},"effort":{"type":"string","enum":["minimal","low","medium","high"],"x-nestjs_zod-uses-3-point-1-syntax":true},"icpId":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"draftSnapshot":{"maxItems":20,"type":"array","items":{"type":"object","properties":{"signalId":{"type":"string","minLength":1},"signalKey":{"type":"string","enum":["changed_jobs","posted_recently","posted_with_keyword","viewed_my_profile","recently_connected","engaged_with_profile","engaged_with_keyword","engaged_with_post","company_raised_funds","company_leadership_change","parked_lead_news","lookalike","company_followers","company_hiring"]},"config":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["signalKey"]},"x-nestjs_zod-uses-3-point-1-syntax":true}},"required":["messages","icpId"]},"CreateSourceBodyDto":{"type":"object","properties":{"icpId":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"signals":{"minItems":1,"type":"array","items":{"type":"object","properties":{"signalKey":{"type":"string","enum":["changed_jobs","posted_recently","posted_with_keyword","viewed_my_profile","recently_connected","engaged_with_profile","engaged_with_keyword","engaged_with_post","company_raised_funds","company_leadership_change","parked_lead_news","lookalike","company_followers","company_hiring"]},"config":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["signalKey"]},"x-nestjs_zod-uses-3-point-1-syntax":true},"contactFilter":{"type":"object","properties":{"buckets":{"minItems":1,"type":"array","items":{"type":"string","enum":["new","unanswered","in_conversation"]},"description":"Which contact-history buckets may enroll: `new` (no conversation either way, and nothing a Kairon campaign sent), `unanswered` (we messaged, no reply), `in_conversation` (they wrote to us). Unique, at least one. All three means enroll everyone. Anyone outside the selected buckets is skipped, not queued, so a narrow set is why a large audience enrolls almost nobody."},"scope":{"type":"string","enum":["seat","org"],"description":"Whose prior-contact history is read: `seat` (this campaign's sending seat) or `org` (every LinkedIn seat). Copying a `seat` filter onto a DIFFERENT seat changes what it means — the new seat's history is empty, so people the original filter excluded now enroll."}},"required":["buckets","scope"],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-self-required":false},"acceptExtraListCharge":{"type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true},"seatId":{"type":"string","minLength":1,"x-nestjs_zod-uses-3-point-1-syntax":true}},"required":["icpId","signals"]},"SetSourceBodyDto":{"type":"object","properties":{"icpId":{"description":"The ICP every new person must pass before joining the list, from icp_list. Its ACTIVE version is the check, so revising the ICP changes future runs. Omit it or pass null for no ICP: then everyone the signals find is added. This is a full replacement, so on a list that HAS an ICP, omitting it removes the check — send back the `icp.id` source_get gave you to keep it. Six signals also SEARCH with the ICP and need one: lookalike, changed_jobs, posted_recently, company_raised_funds, company_leadership_change, company_hiring. Changing the ICP restarts those six from the top of their feed; the others keep their place.","anyOf":[{"type":"string","minLength":1},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"signals":{"minItems":1,"type":"array","items":{"oneOf":[{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"The id of an EXISTING signal, exactly as source_get returned it. Echo it to keep that signal and its place in the feed. Omit it to add a new signal. An id this source does not carry is refused, never treated as new."},"signalKey":{"type":"string","const":"changed_jobs","description":"People who recently changed jobs. Needs no Sales Navigator seat of your own: the search runs on Kairon’s Seat Pool. The exception is an ICP whose searched side has a viewer-relative filter (networkDistance, connectionsOf, pastColleague, sharedExperiences…, or a group, account-list or lead-list filter): this signal then reads on the list’s seat, which must have its own Sales Navigator (seatId)."},"config":{"description":"No configuration — this signal takes none.","type":"object","properties":{}}},"required":["signalKey"]},{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"The id of an EXISTING signal, exactly as source_get returned it. Echo it to keep that signal and its place in the feed. Omit it to add a new signal. An id this source does not carry is refused, never treated as new."},"signalKey":{"type":"string","const":"posted_recently","description":"People who posted recently. Needs no Sales Navigator seat of your own: the search runs on Kairon’s Seat Pool. The exception is an ICP whose searched side has a viewer-relative filter (networkDistance, connectionsOf, pastColleague, sharedExperiences…, or a group, account-list or lead-list filter): this signal then reads on the list’s seat, which must have its own Sales Navigator (seatId)."},"config":{"description":"No configuration — this signal takes none.","type":"object","properties":{}}},"required":["signalKey"]},{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"The id of an EXISTING signal, exactly as source_get returned it. Echo it to keep that signal and its place in the feed. Omit it to add a new signal. An id this source does not carry is refused, never treated as new."},"signalKey":{"type":"string","const":"viewed_my_profile","description":"People who viewed the seat’s profile. Needs a paid seat."},"config":{"description":"No configuration — this signal takes none.","type":"object","properties":{}}},"required":["signalKey"]},{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"The id of an EXISTING signal, exactly as source_get returned it. Echo it to keep that signal and its place in the feed. Omit it to add a new signal. An id this source does not carry is refused, never treated as new."},"signalKey":{"type":"string","const":"recently_connected","description":"People who recently accepted a connection. Any seat."},"config":{"description":"No configuration — this signal takes none.","type":"object","properties":{}}},"required":["signalKey"]},{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"The id of an EXISTING signal, exactly as source_get returned it. Echo it to keep that signal and its place in the feed. Omit it to add a new signal. An id this source does not carry is refused, never treated as new."},"signalKey":{"type":"string","const":"company_raised_funds","description":"Buyers at companies that recently raised funding. Needs no Sales Navigator seat of your own: the search runs on Kairon’s Seat Pool. The exception is an ICP whose searched side has a viewer-relative filter (networkDistance, connectionsOf, pastColleague, sharedExperiences…, or a group, account-list or lead-list filter): this signal then reads on the list’s seat, which must have its own Sales Navigator (seatId). Takes no config — both hops read the targeted ICP."},"config":{"description":"No configuration — this signal takes none.","type":"object","properties":{}}},"required":["signalKey"]},{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"The id of an EXISTING signal, exactly as source_get returned it. Echo it to keep that signal and its place in the feed. Omit it to add a new signal. An id this source does not carry is refused, never treated as new."},"signalKey":{"type":"string","const":"company_leadership_change","description":"Buyers at companies with a recent leadership change. Needs no Sales Navigator seat of your own: the search runs on Kairon’s Seat Pool. The exception is an ICP whose searched side has a viewer-relative filter (networkDistance, connectionsOf, pastColleague, sharedExperiences…, or a group, account-list or lead-list filter): this signal then reads on the list’s seat, which must have its own Sales Navigator (seatId). Takes no config — both hops read the targeted ICP."},"config":{"description":"No configuration — this signal takes none.","type":"object","properties":{}}},"required":["signalKey"]},{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"The id of an EXISTING signal, exactly as source_get returned it. Echo it to keep that signal and its place in the feed. Omit it to add a new signal. An id this source does not carry is refused, never treated as new."},"signalKey":{"type":"string","const":"lookalike","description":"People matching the targeted ICP, a few every day, with no event required — the signal to add when a list must keep growing while the event signals are quiet. Needs an ICP with Sales Navigator criteria on at least one side (an ICP with none is refused). Needs no Sales Navigator seat of your own: the search runs on Kairon’s Seat Pool. The exception is an ICP whose searched side has a viewer-relative filter (networkDistance, connectionsOf, pastColleague, sharedExperiences…, or a group, account-list or lead-list filter): this signal then reads on the list’s seat, which must have its own Sales Navigator (seatId). Takes no config — it walks the ICP’s own search. Unlike the event signals it carries no \"why now\", so a lead it appends gives the message writer less to open on."},"config":{"description":"No configuration — this signal takes none.","type":"object","properties":{}}},"required":["signalKey"]},{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"The id of an EXISTING signal, exactly as source_get returned it. Echo it to keep that signal and its place in the feed. Omit it to add a new signal. An id this source does not carry is refused, never treated as new."},"signalKey":{"type":"string","const":"posted_with_keyword","description":"People who published a post matching a query. Any seat. May appear MORE THAN ONCE on a source — one per query."},"config":{"type":"object","properties":{"keyword":{"type":"string","minLength":1,"description":"The boolean search query the posts search runs, e.g. \"hiring SDR\" OR \"sales lead\"."}},"required":["keyword"],"description":"The query this signal watches for."}},"required":["signalKey","config"]},{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"The id of an EXISTING signal, exactly as source_get returned it. Echo it to keep that signal and its place in the feed. Omit it to add a new signal. An id this source does not carry is refused, never treated as new."},"signalKey":{"type":"string","const":"engaged_with_keyword","description":"People who ENGAGED with posts matching a query — the engagers, not the authors. Any seat. May appear more than once."},"config":{"type":"object","properties":{"keyword":{"type":"string","minLength":1,"description":"The boolean search query the posts search runs, e.g. \"hiring SDR\" OR \"sales lead\"."}},"required":["keyword"],"description":"The query this signal watches for."}},"required":["signalKey","config"]},{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"The id of an EXISTING signal, exactly as source_get returned it. Echo it to keep that signal and its place in the feed. Omit it to add a new signal. An id this source does not carry is refused, never treated as new."},"signalKey":{"type":"string","const":"engaged_with_profile","description":"People who engaged with a chosen profile’s posts. Any seat. May appear more than once — one per watched profile."},"config":{"type":"object","properties":{"target":{"type":"object","properties":{"kind":{"type":"string","enum":["person","company"],"description":"Whether the watched profile is a person or a company."},"url":{"type":"string","minLength":1,"description":"The LinkedIn URL of the profile whose engagers this surfaces."}},"required":["kind","url"],"description":"The profile being watched."}},"required":["target"],"description":"Whose engagement this signal surfaces."}},"required":["signalKey","config"]},{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"The id of an EXISTING signal, exactly as source_get returned it. Echo it to keep that signal and its place in the feed. Omit it to add a new signal. An id this source does not carry is refused, never treated as new."},"signalKey":{"type":"string","const":"engaged_with_post","description":"People who commented on or reacted to ONE named post. Any seat. May appear more than once — one per watched post. Short-lived by nature: a post stops gathering engagement after a few days, and this signal then goes quiet on its own."},"config":{"type":"object","properties":{"url":{"type":"string","minLength":1,"description":"The LinkedIn permalink of the post whose engagers this surfaces."}},"required":["url"],"description":"The post this signal watches."}},"required":["signalKey","config"]},{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"The id of an EXISTING signal, exactly as source_get returned it. Echo it to keep that signal and its place in the feed. Omit it to add a new signal. An id this source does not carry is refused, never treated as new."},"signalKey":{"type":"string","const":"company_followers","description":"People who FOLLOW a company page the source’s seat administers — an opted-in audience. Walks the whole follower list once, a few pages a day, then keeps picking up new followers. Any seat, but only for a page that seat runs. May appear more than once — one per page."},"config":{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":512,"description":"The LinkedIn company page link (https://www.linkedin.com/company/<slug>). It must be a page the source’s seat ADMINISTERS — LinkedIn shows followers to admins only, and the save is refused otherwise."}},"required":["url"],"description":"The company page this signal walks."}},"required":["signalKey","config"]},{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"The id of an EXISTING signal, exactly as source_get returned it. Echo it to keep that signal and its place in the feed. Omit it to add a new signal. An id this source does not carry is refused, never treated as new."},"signalKey":{"type":"string","const":"company_hiring","description":"Buyers at companies that just published a job posting matching a search — the hiring signal. The people search at each company uses the ICP’s people criteria. Both searches run on Kairon’s Seat Pool, so no seat of your own is needed — unless the job search sets inYourNetwork, or the ICP’s people side has a viewer-relative filter (that one needs a seat with its own Sales Navigator). Either case reads on the list’s seat (seatId). May appear more than once — one per search (e.g. one per country)."},"config":{"type":"object","properties":{"keywords":{"description":"What the company is hiring FOR — a product, stack or role (\"Oracle\", \"NetSuite\", \"SAP HCM\"). This is the market sweep: it returns every company hiring that profile, so it DISCOVERS companies rather than filtering ones you already hold. Requires `region` unless `company` is also set. A product name usually needs no translation — \"Oracle\" catches Portuguese and Spanish postings alike.","type":"string","minLength":1,"maxLength":512},"region":{"type":"string","minLength":1,"maxLength":200,"description":"The ONE country to watch, in plain language (\"Brazil\") or as a LinkedIn geo id. Required: without it LinkedIn silently searches only the seat's own country. Watch another country with another hiring signal."},"datePosted":{"description":"How many days back to look. A sweep defaults to 30 days, which is almost always right: LinkedIn removes a posting when the role closes, so 90 days measured 170 postings against 151 at 30 — to find MORE companies repeat the sweep in a few weeks rather than widening it. A COMPANY CHECK has no default window: \"is this company hiring\" is asked of everything still open, so an empty answer means \"not hiring\" rather than \"nothing lately\".","type":"integer","minimum":1,"maximum":365},"roles":{"description":"Job TITLES from LinkedIn's own taxonomy, in plain language (\"Product Analyst\", \"Head of Growth\") — resolved to title ids for you and echoed back. This is the sharpest filter this tool has and usually beats `keywords`: measured on the same Argentina sweep, `keywords: \"Product Analyst\"` returned 1241 postings while `roles: [\"Product Analyst\"]` returned 17, because keywords match anywhere in a posting while a title id matches the ROLE. LinkedIn treats several titles as OR — pass the variants you mean (\"Product Analyst\", \"Senior Product Analyst\").","minItems":1,"maxItems":10,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}},"functions":{"description":"Job FUNCTIONS — the department a role belongs to (\"Product Management\", \"Engineering\", \"Marketing\"), resolved to LinkedIn ids and echoed back. Much wider than `roles`: Product Management alone returned 207 postings where the \"Product Analyst\" title returned 17. Reach for it to size a department across a market; reach for `roles` to find one job.","minItems":1,"maxItems":10,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}},"industries":{"description":"The HIRING COMPANY's industry, in plain language (\"Financial Services\", \"Software Development\") — resolved to LinkedIn ids and echoed back. This filters by the employer, not by the role, so it is how a sweep is aimed at the market you actually sell to.","minItems":1,"maxItems":10,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}},"seniority":{"description":"LinkedIn's EXPERIENCE LEVEL on the posting. This is the ONLY way to ask for seniority — putting \"Senior\" in `keywords` does the opposite of what it looks like, because LinkedIn ORs the words: the same sweep went from 1241 hits to 2480, wider, not narrower. Several levels are OR (\"senior and above\" is `[\"mid_senior\",\"director\",\"executive\"]`, measured 675 against a 1241 baseline).","minItems":1,"type":"array","items":{"type":"string","enum":["executive","director","mid_senior","associate","entry","intern"]}},"jobType":{"description":"LinkedIn's JOB TYPE — the employment arrangement. Several are OR.","minItems":1,"type":"array","items":{"type":"string","enum":["full_time","part_time","contract","temporary","volunteer","internship","other"]}},"presence":{"description":"On-site / hybrid / remote, as the posting declares it. Several are OR.","minItems":1,"type":"array","items":{"type":"string","enum":["on_site","hybrid","remote"]}},"underTenApplicants":{"description":"LinkedIn's UNDER 10 APPLICANTS. The sharpest recency filter there is — it says the posting is not just recent but still UNWORKED, and it cut the same 1241-hit sweep to 127. Use it when the value of the signal is getting there first.","type":"boolean"},"inYourNetwork":{"description":"LinkedIn's IN YOUR NETWORK — only companies where the seat already has a connection. Warm ground: it cut the same sweep from 1241 to 265, and every hit comes with a path in.","type":"boolean"},"easyApply":{"description":"LinkedIn's EASY APPLY.","type":"boolean"},"hasVerifications":{"description":"LinkedIn's HAS VERIFICATIONS — the poster verified their identity.","type":"boolean"},"fairChanceEmployer":{"description":"LinkedIn's FAIR CHANCE EMPLOYER.","type":"boolean"},"benefits":{"description":"LinkedIn's BENEFITS, as the posting declares them. Several are OR.","minItems":1,"type":"array","items":{"type":"string","enum":["medical_insurance","vision_insurance","dental_insurance","disability_insurance","401(k)","pension_plan","paid_maternity_leave","paid_paternity_leave","commuter_benefits","student_loan_assistance","tuition_assistance"]}},"commitments":{"description":"LinkedIn's COMMITMENTS, as the company declares them. Several are OR.","minItems":1,"type":"array","items":{"type":"string","enum":["career_growth_and_learning","diversity_equity_and_inclusion","environmental_sustainability","social_impact","work_life_balance"]}},"minimumSalary":{"description":"LinkedIn's SALARY floor. Both fields are required together, and `value` is in THOUSANDS from a fixed ladder LinkedIn will not interpolate — dollars (USD/AUD/CAD) step 40…200, pounds (GBP) step 20…100. Off-ladder numbers are refused rather than rounded.","oneOf":[{"type":"object","properties":{"currency":{"type":"string","enum":["USD","AUD","CAD"],"description":"A dollar currency — these three share one ladder (40…200, in 20s)."},"value":{"anyOf":[{"type":"number","const":40},{"type":"number","const":60},{"type":"number","const":80},{"type":"number","const":100},{"type":"number","const":120},{"type":"number","const":140},{"type":"number","const":160},{"type":"number","const":180},{"type":"number","const":200}],"description":"In THOUSANDS of dollars, from LinkedIn's fixed ladder (40 = \"$40,000+\")."}},"required":["currency","value"]},{"type":"object","properties":{"currency":{"type":"string","const":"GBP","description":"Pounds — a different ladder (20…100, in 10s)."},"value":{"anyOf":[{"type":"number","const":20},{"type":"number","const":30},{"type":"number","const":40},{"type":"number","const":50},{"type":"number","const":60},{"type":"number","const":70},{"type":"number","const":80},{"type":"number","const":90},{"type":"number","const":100}],"description":"In THOUSANDS of pounds, from LinkedIn's fixed ladder (20 = \"£20,000+\")."}},"required":["currency","value"]}]}},"required":["region"],"additionalProperties":false,"description":"The job search to watch: every job_search market-sweep filter. `region` (one country, plain language) is REQUIRED, and so is at least one of `roles`, `keywords`, `functions`, `industries` — `roles` (job titles) is the sharpest. LinkedIn has no language filter: ask for Spanish-speaking roles with `keywords` such as \"español\". Checked with one job search when saved: a region or term that matches nothing on LinkedIn is refused."}},"required":["signalKey","config"]},{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"The id of an EXISTING signal, exactly as source_get returned it. Echo it to keep that signal and its place in the feed. Omit it to add a new signal. An id this source does not carry is refused, never treated as new."},"signalKey":{"type":"string","const":"parked_lead_news","description":"The people already on this org’s Pipeline in Nurture, brought back when something happens to them. The ONLY signal that reads your own data instead of searching LinkedIn — so it grows a list with people you already gave up on, not strangers. It must be the ONLY signal on its source, and it never appears twice."},"config":{"type":"object","properties":{"triggers":{"minItems":1,"type":"array","items":{"type":"string","enum":["changed_jobs","company_news","posted"]},"description":"Which news wakes a parked lead. At least one. `changed_jobs` — they moved to a new company, the strongest trigger there is; when the list has an ICP, the wake re-checks them against it at the new place. `company_news` — the company they work at published a new post. `posted` — they published something you can reply to."},"cooldownDays":{"default":90,"description":"How many days a lead is left alone after being woken. Defaults to 90, never below 7. It is what stops someone who posts every week being written to every week — the answer to \"how often may we come back\", which nothing else in the system decides.","type":"integer","minimum":7,"maximum":9007199254740991}},"required":["triggers"],"description":"Which news wakes a parked lead, and how long they are left alone afterwards. `triggers`: `changed_jobs` (they moved company — the strongest one, and it re-checks them against the ICP at the new company), `company_news` (the company they work at published a new post), `posted` (they published something you can reply to). At least one. `cooldownDays` defaults to 90 and is never below 7: it is what stops someone who posts every week being written to every week."}},"required":["signalKey","config"]}]},"description":"The COMPLETE set of signals this source should carry — at least one. Any signal not listed here is removed. Echo each kept signal with the `id` source_get gave it, or it is treated as new and restarts from the top of its feed.","x-nestjs_zod-uses-3-point-1-syntax":true},"status":{"description":"Whether the source keeps feeding the list. `paused` stops it without losing anything — the signals, their places in their feeds, and every member already found all survive, and resuming carries on where it left off. Use this rather than source_delete to stop a list growing for a while. Omitted leaves the current setting; a new source starts `active`.","type":"string","enum":["active","paused"],"x-nestjs_zod-uses-3-point-1-syntax":true},"contactFilter":{"description":"Who this list may add, by how much you have already talked to them — the same rule a campaign enrolls by. Omitted leaves the current setting; a new source adds everyone. Narrow it to stop a list filling up with people already in a conversation.","type":"object","properties":{"buckets":{"minItems":1,"type":"array","items":{"type":"string","enum":["new","unanswered","in_conversation"]},"description":"Which contact-history buckets may enroll: `new` (no conversation either way, and nothing a Kairon campaign sent), `unanswered` (we messaged, no reply), `in_conversation` (they wrote to us). Unique, at least one. All three means enroll everyone. Anyone outside the selected buckets is skipped, not queued, so a narrow set is why a large audience enrolls almost nobody."},"scope":{"type":"string","enum":["seat","org"],"description":"Whose prior-contact history is read: `seat` (this campaign's sending seat) or `org` (every LinkedIn seat). Copying a `seat` filter onto a DIFFERENT seat changes what it means — the new seat's history is empty, so people the original filter excluded now enroll."}},"required":["buckets","scope"],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-self-required":false},"dailyTarget":{"description":"How many qualified people this list should gain per day (UTC), 1-1000. A floor, not a cap: every event signal still runs in full first, and the lookalike signal then keeps searching until the day's total reaches this number, the search runs out, 30 people in a row fail the ICP, or 20 companies (or result pages) in a row add nobody (it picks up from there the next day). Only the lookalike fills the gap, so on a source without one this only reports progress. Omitted leaves the current setting; a new source starts at 30.","type":"integer","minimum":1,"maximum":1000,"x-nestjs_zod-uses-3-point-1-syntax":true},"peoplePerCompany":{"description":"How many people a walk that goes company by company takes at each company, 1-100. Applies to the lookalike (when the ICP describes companies) and to the recently-raised-funds and new-senior-leadership signals. Higher means fewer companies and less variety, but more of a big employer. Omitted leaves the current setting; a new source starts at 3.","type":"integer","minimum":1,"maximum":100,"x-nestjs_zod-uses-3-point-1-syntax":true},"seatId":{"description":"Which workspace seat (a channel account id from seat_list) reads this list's SEAT signals: viewed_my_profile, recently_connected and company_followers, and any signal whose own search is measured from a seat (firstDegreeOnly, postedByMe, postedByFollowed or inYourNetwork in its config, or a networkDistance-style filter in the ICP). Every other signal reads on Kairon's own accounts and needs no seat. Any member may pick any connected seat. Omitted: the list keeps its seat, else takes yours if it can run them; if neither works the call is refused with SOURCE_SEAT_REQUIRED, which lists the seats that can. Refused with SOURCE_SEAT_CANNOT_RUN when the seat lacks what a signal needs (a paid licence for viewed_my_profile, page admin for company_followers, Sales Navigator for a viewer-relative ICP). Ignored when no signal needs a seat.","type":"string","minLength":1,"x-nestjs_zod-uses-3-point-1-syntax":true},"acceptExtraListCharge":{"description":"The workspace's plan includes a number of growing lists (lists whose source is active). Turning a list on past that number costs the plan's price for an extra list, every month, billed to the organization; on a plan that sells none it is refused. A call that turns a list on past the included number is REFUSED unless this is true, and the refusal carries the price: ask the user first, then retry with it. Ignored when the call turns no list on, or the list fits. A list carries at most 3 signals.","type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true}},"required":["signals"]},"UpdateSourceBodyDto":{"type":"object","properties":{"icpId":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"status":{"type":"string","enum":["active","paused"],"x-nestjs_zod-uses-3-point-1-syntax":true},"contactFilter":{"type":"object","properties":{"buckets":{"minItems":1,"type":"array","items":{"type":"string","enum":["new","unanswered","in_conversation"]},"description":"Which contact-history buckets may enroll: `new` (no conversation either way, and nothing a Kairon campaign sent), `unanswered` (we messaged, no reply), `in_conversation` (they wrote to us). Unique, at least one. All three means enroll everyone. Anyone outside the selected buckets is skipped, not queued, so a narrow set is why a large audience enrolls almost nobody."},"scope":{"type":"string","enum":["seat","org"],"description":"Whose prior-contact history is read: `seat` (this campaign's sending seat) or `org` (every LinkedIn seat). Copying a `seat` filter onto a DIFFERENT seat changes what it means — the new seat's history is empty, so people the original filter excluded now enroll."}},"required":["buckets","scope"],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-self-required":false},"dailyTarget":{"type":"integer","minimum":1,"maximum":1000,"x-nestjs_zod-uses-3-point-1-syntax":true},"peoplePerCompany":{"type":"integer","minimum":1,"maximum":100,"x-nestjs_zod-uses-3-point-1-syntax":true},"acceptExtraListCharge":{"type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true},"seatId":{"type":"string","minLength":1,"x-nestjs_zod-uses-3-point-1-syntax":true}}},"AddSignalBodyDto":{"type":"object","properties":{"signalKey":{"type":"string","enum":["changed_jobs","posted_recently","posted_with_keyword","viewed_my_profile","recently_connected","engaged_with_profile","engaged_with_keyword","engaged_with_post","company_raised_funds","company_leadership_change","parked_lead_news","lookalike","company_followers","company_hiring"],"x-nestjs_zod-uses-3-point-1-syntax":true},"config":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-self-required":false}},"required":["signalKey"]},"EditSignalConfigBodyDto":{"type":"object","properties":{"root":{"type":"object","properties":{},"additionalProperties":{},"x-nestjs_zod-unwrap-root":true,"x-nestjs_zod-self-required":false}}},"RequalifyRunBodyDto":{"type":"object","properties":{"leadIds":{"minItems":1,"maxItems":200,"type":"array","items":{"type":"string","minLength":1}}},"required":["leadIds"]},"SourcePreviewBodyDto":{"type":"object","properties":{"icpId":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"signals":{"minItems":1,"type":"array","items":{"type":"object","properties":{"signalKey":{"type":"string","enum":["changed_jobs","posted_recently","posted_with_keyword","viewed_my_profile","recently_connected","engaged_with_profile","engaged_with_keyword","engaged_with_post","company_raised_funds","company_leadership_change","parked_lead_news","lookalike","company_followers","company_hiring"]},"config":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["signalKey"]},"x-nestjs_zod-uses-3-point-1-syntax":true},"seatId":{"type":"string","minLength":1,"x-nestjs_zod-uses-3-point-1-syntax":true}},"required":["icpId","signals"]},"AgentCampaignChatDto":{"type":"object","properties":{"messages":{"minItems":1,"maxItems":200,"type":"array","items":{},"x-nestjs_zod-uses-3-point-1-syntax":true},"model":{"type":"string","minLength":3,"maxLength":120,"pattern":"^[a-z0-9][a-z0-9._-]*\\/[a-z0-9][a-z0-9._:-]*$","x-nestjs_zod-uses-3-point-1-syntax":true},"effort":{"type":"string","enum":["minimal","low","medium","high"],"x-nestjs_zod-uses-3-point-1-syntax":true},"graph":{"type":"object","properties":{"nodes":{"maxItems":100,"type":"array","items":{"oneOf":[{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80},"type":{"type":"string","const":"send_invite"},"config":{"type":"object","properties":{"note":{"default":"","description":"Invite note, and the seed when `draftMode` is `ai_template`. In `ai_template` this seed is authoritative: the writer reproduces it word for word and adds nothing, so EVERY per-lead detail must sit inside a `{{...}}` slot written here. A seed with no slots sends the identical message to every lead. A slot holds a description of the fact to write there, phrased as a clause — e.g. `{{one short clause, 8-14 words, on what their company does}}`. Custom list columns reach a message two ways: `{{@columnName}}` sends that column's value word for word, and a normal AI slot that mentions a column can use it as a fact, written in the writer's own words. At publish it must be ≤300 characters, or ≤250 once it contains any `{{token}}` (the braces count), leaving room for what the token expands to. Over that, publish fails with `invite_note_too_long`. A note needs a sender with LinkedIn Premium or Sales Navigator (`canSendInviteNote` on `seat_list`); on any other seat leave it empty — `campaign_set_graph` refuses a note there.","type":"string","maxLength":2000},"draftMode":{"description":"How the copy is produced. `template`: sent as written — only allowlisted `{{variables}}` and per-lead `{{@slots}}` are substituted, no AI. `ai_template`: the AI personalizes YOUR seed, filling its `{{described slots}}` and nothing else. Absent means `template`.","type":"string","enum":["template","ai_template"]},"instruction":{"description":"Optional note on tone and register, layered on the seed — NOT where the copy comes from. It reaches the writer AFTER the rule that says to keep the seed as written, so anything it asks for that the seed has no `{{slot}}` for is silently ignored: \"personalize the opening with their company\" does nothing unless a slot sits there. Write the copy in the seed.","type":"string","maxLength":4000},"language":{"description":"Force every message on this step into one language, or set 'auto' so each lead is written to in their OWN language, translating your seed faithfully. OMIT IT and the step uses the default language the sender chose in their settings, or 'auto' when they chose none — which is usually what you want. This rule outranks the seed's original language.","anyOf":[{"type":"string","const":"auto"},{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"]}]},"localization":{"description":"The seed translated into other languages, one per ISO 639-1 code, each keeping every `{{…}}` slot byte-exact and every `---` line. Kairon writes a language here the first time it drafts a lead in it; you may edit any entry and it is then used as written for every later lead in that language. Leave it out to let Kairon translate.","type":"object","properties":{"seedHash":{"type":"string","minLength":1,"description":"Hash of the seed text these translations were made for. Kairon sets it; when the seed changes, the whole object goes stale and is rebuilt. Copy it through unchanged."},"seedLanguage":{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"],"description":"The ISO 639-1 code of the language the seed itself is written in, detected once by Kairon."},"translations":{"type":"object","propertyNames":{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"]},"additionalProperties":{"type":"string","minLength":1},"description":"One translated seed per ISO 639-1 code. Each must keep every `{{…}}` slot byte-exact and in order, and the same number of `---` lines, or publish refuses it."}},"required":["seedHash","seedLanguage","translations"]},"reviewBeforeSend":{"description":"Default false. True holds every send this step drafts for the operator to approve, even when the campaign is on autopilot. Nothing is scheduled until they approve it.","type":"boolean"},"verifyBeforeSend":{"description":"DEPRECATED, and accepted only so campaigns published before the rename still parse. Set `reviewBeforeSend` instead; if both are present the new one wins.","type":"boolean"},"adaptToCulture":{"description":"Retired: accepted for old steps and ignored. Do not send it.","type":"boolean"}},"additionalProperties":false},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80},"type":{"type":"string","const":"wait_connection_accepted"},"config":{"type":"object","properties":{"timeoutDays":{"type":"integer","minimum":1,"maximum":7,"description":"How many whole days to wait for the invite to be accepted, 1-7. On expiry the run leaves by the `timeout` edge; wire one or those leads stop here."},"withdrawOnTimeout":{"description":"Withdraw the pending invite when the wait times out. Default true — it reclaims LinkedIn pending-invite quota, which is capped. Set false to leave the invite standing, so someone who accepts weeks later still lands on the `accepted` edge of a later wait.","type":"boolean"}},"required":["timeoutDays"],"additionalProperties":false},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80},"type":{"type":"string","const":"delay"},"config":{"type":"object","properties":{"value":{"type":"integer","minimum":1,"maximum":10080,"description":"How long to pause before the next step, counted in `unit`. The total may not exceed 7 days."},"unit":{"type":"string","enum":["minutes","hours","days"],"description":"The unit `value` is counted in. Use `minutes`/`hours` for the hot follow-up right after an invite is accepted, `days` for a nurture gap. Counted in real time, not send windows — the next step then waits for the window to open."}},"required":["value","unit"],"additionalProperties":false},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80},"type":{"type":"string","const":"wait_reply"},"config":{"type":"object","properties":{"value":{"type":"integer","minimum":1,"maximum":10080,"description":"How long to wait for the lead to reply, counted in `unit`. The total may not exceed 7 days."},"unit":{"type":"string","enum":["minutes","hours","days"],"description":"The unit `value` is counted in. `minutes`/`hours` for a same-day nudge, `days` for a normal follow-up gap."}},"required":["value","unit"],"additionalProperties":false},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80},"type":{"type":"string","const":"agentic_reply"},"config":{"type":"object","properties":{"instruction":{"default":"","description":"REQUIRED. The goal — what the operator wants out of this conversation, in one line. E.g. \"Get them to book a call with me.\" or \"Find out if they own hiring, or who does.\" This is the only field the step needs: the agent chooses its own wording and works out for itself when the conversation is finished. It does NOT invent substance — anything it cannot answer straight from this goal and `additionalInstructions` is handed to a human instead, so the more `additionalInstructions` says, the fewer turns come back to the operator.","type":"string","maxLength":8000},"additionalInstructions":{"default":"","description":"Optional, and it decides how much the agent can answer on its own: it hands a turn to a human whenever the answer is not straightforward from the goal plus this field. Put here the facts it may use (dates, prices, links — STATE EVERY ONE, it must never state a fact you did not give it), when to treat the conversation as finished, what to hand straight to a human whatever it knows, how to answer an objection you expect, and any other steering. E.g. \"The event is Tuesday 12 March, 6pm, at our office. If they ask who else is going, hand it to me. If they say it is too far, offer the recording.\"","type":"string","maxLength":8000},"silence":{"default":{"value":7,"unit":"days"},"description":"How long the agent keeps listening — for her FIRST reply, and after each of its own answers. She goes quiet past this and the step leaves by `no_reply`, so a follow-up can still chase her.","type":"object","properties":{"value":{"type":"integer","minimum":1,"maximum":10080,"description":"How long to keep listening for her next message, counted in `unit`. The total may not exceed 7 days."},"unit":{"type":"string","enum":["minutes","hours","days"],"description":"The unit `value` is counted in."}},"required":["value","unit"]},"maxTurns":{"description":"How many times the agent may answer before it hands off for good and the run ends. Defaults to 10.","type":"integer","minimum":1,"maximum":20},"attachments":{"description":"Files the agent may send with an answer when they fit the conversation — each at most once per conversation. Say in the instruction when to send which. Images and PDFs; on LinkedIn also one voice note and one video.","maxItems":5,"type":"array","items":{"type":"object","properties":{"storageKey":{"type":"string","maxLength":512,"pattern":"^step-attachments\\/.*"},"fileName":{"type":"string","minLength":1,"maxLength":255},"mimeType":{"type":"string","minLength":1,"maxLength":255},"byteSize":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["storageKey","fileName","mimeType","byteSize"],"additionalProperties":false}}},"additionalProperties":false},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80},"type":{"type":"string","const":"send_message"},"config":{"type":"object","properties":{"body":{"default":"","description":"The message. In `ai_template` this seed is authoritative: the writer reproduces it word for word and adds nothing, so EVERY per-lead detail must sit inside a `{{...}}` slot written here. A seed with no slots sends the identical message to every lead. A slot holds a description of the fact to write there, phrased as a clause — e.g. `{{one short clause, 8-14 words, on what their company does}}`. Custom list columns reach a message two ways: `{{@columnName}}` sends that column's value word for word, and a normal AI slot that mentions a column can use it as a fact, written in the writer's own words. To send this as SEVERAL messages rather than one, separate them with a line containing only `---`. Each part arrives as its own LinkedIn message a couple of seconds later, in the same conversation — what a person does when they type a short opener and then the reason they wrote. The whole thing still counts as ONE send against the daily limit. This is the same thing the \"Add bubble\" button does in the campaign editor.","type":"string","maxLength":8000},"draftMode":{"description":"How the copy is produced. `template`: sent as written — only allowlisted `{{variables}}` and per-lead `{{@slots}}` are substituted, no AI. `ai_template`: the AI personalizes YOUR seed, filling its `{{described slots}}` and nothing else. Absent means `template`.","type":"string","enum":["template","ai_template"]},"instruction":{"description":"Optional note on tone and register, layered on the seed — NOT where the copy comes from. It reaches the writer AFTER the rule that says to keep the seed as written, so anything it asks for that the seed has no `{{slot}}` for is silently ignored: \"personalize the opening with their company\" does nothing unless a slot sits there. Write the copy in the seed.","type":"string","maxLength":4000},"language":{"description":"Force every message on this step into one language, or set 'auto' so each lead is written to in their OWN language, translating your seed faithfully. OMIT IT and the step uses the default language the sender chose in their settings, or 'auto' when they chose none — which is usually what you want. This rule outranks the seed's original language.","anyOf":[{"type":"string","const":"auto"},{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"]}]},"localization":{"description":"The seed translated into other languages, one per ISO 639-1 code, each keeping every `{{…}}` slot byte-exact and every `---` line. Kairon writes a language here the first time it drafts a lead in it; you may edit any entry and it is then used as written for every later lead in that language. Leave it out to let Kairon translate.","type":"object","properties":{"seedHash":{"type":"string","minLength":1,"description":"Hash of the seed text these translations were made for. Kairon sets it; when the seed changes, the whole object goes stale and is rebuilt. Copy it through unchanged."},"seedLanguage":{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"],"description":"The ISO 639-1 code of the language the seed itself is written in, detected once by Kairon."},"translations":{"type":"object","propertyNames":{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"]},"additionalProperties":{"type":"string","minLength":1},"description":"One translated seed per ISO 639-1 code. Each must keep every `{{…}}` slot byte-exact and in order, and the same number of `---` lines, or publish refuses it."}},"required":["seedHash","seedLanguage","translations"]},"reviewBeforeSend":{"description":"Default false. True holds every send this step drafts for the operator to approve, even when the campaign is on autopilot. Nothing is scheduled until they approve it.","type":"boolean"},"verifyBeforeSend":{"description":"DEPRECATED, and accepted only so campaigns published before the rename still parse. Set `reviewBeforeSend` instead; if both are present the new one wins.","type":"boolean"},"adaptToCulture":{"description":"Retired: accepted for old steps and ignored. Do not send it.","type":"boolean"},"condition":{"description":"Only send when one of their own recent posts meets this test - e.g. \"a new job or a promotion\". The newest post that meets it becomes what the message refers to; a post that is bad news for its author never meets it. When none does, the step is SKIPPED and the lead moves on; nothing is sent. Omit it and the message sends as usual.","type":"string","maxLength":1000},"maxPostAgeDays":{"description":"With a condition: Only consider their own posts from the last this-many days, 1-90. Defaults to 90. In a loop, the step also only considers posts published after it last acted on a post, or last checked and found none that met its condition.","type":"integer","minimum":1,"maximum":90},"bySender":{"description":"Optional per-sender text, keyed by the sender's user id (`seat_list` → `ownerUserId`). A lead sent by that sender gets this version; every other sender gets the step's own `body`. Same draft mode and language as the step.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"object","properties":{"body":{"type":"string","maxLength":8000,"description":"This sender's message, in place of the step's `body`. In `ai_template` this seed is authoritative: the writer reproduces it word for word and adds nothing, so EVERY per-lead detail must sit inside a `{{...}}` slot written here. A seed with no slots sends the identical message to every lead. A slot holds a description of the fact to write there, phrased as a clause — e.g. `{{one short clause, 8-14 words, on what their company does}}`."},"instruction":{"description":"This sender's note, in place of the step's `instruction`. Optional note on tone and register, layered on the seed — NOT where the copy comes from. It reaches the writer AFTER the rule that says to keep the seed as written, so anything it asks for that the seed has no `{{slot}}` for is silently ignored: \"personalize the opening with their company\" does nothing unless a slot sits there. Write the copy in the seed.","type":"string","maxLength":4000},"localization":{"description":"The seed translated into other languages, one per ISO 639-1 code, each keeping every `{{…}}` slot byte-exact and every `---` line. Kairon writes a language here the first time it drafts a lead in it; you may edit any entry and it is then used as written for every later lead in that language. Leave it out to let Kairon translate.","type":"object","properties":{"seedHash":{"type":"string","minLength":1,"description":"Hash of the seed text these translations were made for. Kairon sets it; when the seed changes, the whole object goes stale and is rebuilt. Copy it through unchanged."},"seedLanguage":{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"],"description":"The ISO 639-1 code of the language the seed itself is written in, detected once by Kairon."},"translations":{"type":"object","propertyNames":{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"]},"additionalProperties":{"type":"string","minLength":1},"description":"One translated seed per ISO 639-1 code. Each must keep every `{{…}}` slot byte-exact and in order, and the same number of `---` lines, or publish refuses it."}},"required":["seedHash","seedLanguage","translations"]}},"required":["body"]}},"attachments":{"description":"Files sent with this step to every lead it reaches: images and PDFs, plus one voice note and one video on a LinkedIn message.","maxItems":5,"type":"array","items":{"type":"object","properties":{"storageKey":{"type":"string","maxLength":512,"pattern":"^step-attachments\\/.*"},"fileName":{"type":"string","minLength":1,"maxLength":255},"mimeType":{"type":"string","minLength":1,"maxLength":255},"byteSize":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["storageKey","fileName","mimeType","byteSize"],"additionalProperties":false}},"attachmentsBySender":{"description":"Optional per-sender files, keyed by the sender's user id (`seat_list` → `ownerUserId`): that sender's leads get these files instead of the step's `attachments` (an empty list sends none). Read-only notes — add files through `attachments` first.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"maxItems":5,"type":"array","items":{"type":"object","properties":{"storageKey":{"type":"string","maxLength":512,"pattern":"^step-attachments\\/.*"},"fileName":{"type":"string","minLength":1,"maxLength":255},"mimeType":{"type":"string","minLength":1,"maxLength":255},"byteSize":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["storageKey","fileName","mimeType","byteSize"],"additionalProperties":false}}}},"additionalProperties":false},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80},"type":{"type":"string","const":"send_inmail"},"config":{"type":"object","properties":{"subject":{"default":"","description":"Required. The InMail subject line — fixed text you write, never AI-written, in every draftMode. The only tokens allowed are template variables (firstName, lastName, companyName, jobTitle, location, headline, companyIndustry); a described slot or a per-lead {{@slot}} is refused. Empty is refused at save and at publish.","type":"string","maxLength":200},"body":{"default":"","description":"The InMail body. In `ai_template` this seed is authoritative: the writer reproduces it word for word and adds nothing, so EVERY per-lead detail must sit inside a `{{...}}` slot written here. A seed with no slots sends the identical message to every lead. A slot holds a description of the fact to write there, phrased as a clause — e.g. `{{one short clause, 8-14 words, on what their company does}}`. Custom list columns reach a message two ways: `{{@columnName}}` sends that column's value word for word, and a normal AI slot that mentions a column can use it as a fact, written in the writer's own words.","type":"string","maxLength":8000},"draftMode":{"description":"How the copy is produced. `template`: sent as written — only allowlisted `{{variables}}` and per-lead `{{@slots}}` are substituted, no AI. `ai_template`: the AI personalizes YOUR seed, filling its `{{described slots}}` and nothing else. Absent means `template`.","type":"string","enum":["template","ai_template"]},"instruction":{"description":"Optional note on tone and register, layered on the seed — NOT where the copy comes from. It reaches the writer AFTER the rule that says to keep the seed as written, so anything it asks for that the seed has no `{{slot}}` for is silently ignored: \"personalize the opening with their company\" does nothing unless a slot sits there. Write the copy in the seed.","type":"string","maxLength":4000},"language":{"description":"Force every message on this step into one language, or set 'auto' so each lead is written to in their OWN language, translating your seed faithfully. OMIT IT and the step uses the default language the sender chose in their settings, or 'auto' when they chose none — which is usually what you want. This rule outranks the seed's original language.","anyOf":[{"type":"string","const":"auto"},{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"]}]},"localization":{"description":"The seed translated into other languages, one per ISO 639-1 code, each keeping every `{{…}}` slot byte-exact and every `---` line. Kairon writes a language here the first time it drafts a lead in it; you may edit any entry and it is then used as written for every later lead in that language. Leave it out to let Kairon translate.","type":"object","properties":{"seedHash":{"type":"string","minLength":1,"description":"Hash of the seed text these translations were made for. Kairon sets it; when the seed changes, the whole object goes stale and is rebuilt. Copy it through unchanged."},"seedLanguage":{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"],"description":"The ISO 639-1 code of the language the seed itself is written in, detected once by Kairon."},"translations":{"type":"object","propertyNames":{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"]},"additionalProperties":{"type":"string","minLength":1},"description":"One translated seed per ISO 639-1 code. Each must keep every `{{…}}` slot byte-exact and in order, and the same number of `---` lines, or publish refuses it."}},"required":["seedHash","seedLanguage","translations"]},"reviewBeforeSend":{"description":"Default false. True holds every send this step drafts for the operator to approve, even when the campaign is on autopilot. Nothing is scheduled until they approve it.","type":"boolean"},"verifyBeforeSend":{"description":"DEPRECATED, and accepted only so campaigns published before the rename still parse. Set `reviewBeforeSend` instead; if both are present the new one wins.","type":"boolean"},"adaptToCulture":{"description":"Retired: accepted for old steps and ignored. Do not send it.","type":"boolean"},"attachments":{"description":"Files sent with this step to every lead it reaches: images and PDFs, plus one voice note and one video on a LinkedIn message.","maxItems":5,"type":"array","items":{"type":"object","properties":{"storageKey":{"type":"string","maxLength":512,"pattern":"^step-attachments\\/.*"},"fileName":{"type":"string","minLength":1,"maxLength":255},"mimeType":{"type":"string","minLength":1,"maxLength":255},"byteSize":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["storageKey","fileName","mimeType","byteSize"],"additionalProperties":false}}},"additionalProperties":false},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80},"type":{"type":"string","const":"like_last_post"},"config":{"type":"object","properties":{"reaction":{"default":"like","description":"Which reaction to leave on the lead's latest own post. 'auto' reads the post and picks the fitting one of the six; a named value always leaves that one. Defaults to 'like', which is what every campaign saved before this field existed does.","type":"string","enum":["like","celebrate","support","love","insightful","funny","auto"]},"maxPostAgeDays":{"description":"Only react when the lead's latest own post is at most this many days old, 1-3650. When it is older, the step is SKIPPED and the lead moves on; nothing is liked. Defaults to 90 — a like on a years-old post, right before an invite, reads as automation.","type":"integer","minimum":1,"maximum":3650}},"additionalProperties":false},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80},"type":{"type":"string","const":"visit_profile"},"config":{"type":"object","properties":{},"additionalProperties":false},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80},"type":{"type":"string","const":"follow_profile"},"config":{"type":"object","properties":{},"additionalProperties":false},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80},"type":{"type":"string","const":"remove_relation"},"config":{"type":"object","properties":{},"additionalProperties":false},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80},"type":{"type":"string","const":"comment_on_post"},"config":{"type":"object","properties":{"instruction":{"description":"What the comment should say. UNLIKE a send step, this IS the whole brief: a comment has no operator template to personalize, so the guidance carries the intent alone.","type":"string","maxLength":4000},"condition":{"description":"Only comment when one of their own recent posts meets this test — e.g. \"the post is about AI\". The newest post that meets it is the one commented on; a post that is bad news for its author never meets it. When none does, the step is SKIPPED and the lead moves on to the next step; nothing is posted. Omit it and every eligible post qualifies.","type":"string","maxLength":1000},"maxLength":{"description":"Character ceiling for the comment, up to 1250. Omit and the cap is used.","type":"integer","minimum":1,"maximum":1250},"maxPostAgeDays":{"description":"Only consider their own posts from the last this-many days, 1-90. Defaults to 90. In a loop, the step also only considers posts published after it last acted on a post, or last checked and found none that met its condition.","type":"integer","minimum":1,"maximum":90},"language":{"description":"Force every message on this step into one language, or set 'auto' so each lead is written to in their OWN language, translating your seed faithfully. OMIT IT and the step uses the default language the sender chose in their settings, or 'auto' when they chose none — which is usually what you want. This rule outranks the seed's original language.","anyOf":[{"type":"string","const":"auto"},{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"]}]},"reviewBeforeSend":{"description":"Default false. True holds every send this step drafts for the operator to approve, even when the campaign is on autopilot. Nothing is scheduled until they approve it.","type":"boolean"},"verifyBeforeSend":{"description":"DEPRECATED, and accepted only so campaigns published before the rename still parse. Set `reviewBeforeSend` instead; if both are present the new one wins.","type":"boolean"}},"additionalProperties":false},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80},"type":{"type":"string","const":"research"},"config":{"type":"object","properties":{"instructions":{"type":"string","maxLength":4000}},"required":["instructions"],"additionalProperties":false},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80},"type":{"type":"string","const":"send_email"},"config":{"type":"object","properties":{"subject":{"default":"","description":"Required in managed mode (instantlyCampaignId empty) — fixed text you write, never AI-written, in every draftMode. Empty is refused at save and at publish. Ignored in custom mode (instantlyCampaignId set), where the operator's own Instantly campaign carries its own subject.","type":"string","maxLength":200},"body":{"default":"","description":"The email body. Unlike a LinkedIn send, this always renders as exact fixed text with `{{variables}}` substituted — `ai_template` is not implemented for email yet, so there is no seed-and-slots writing here. Required in managed mode; ignored in custom mode.","type":"string","maxLength":8000},"draftMode":{"description":"Fixed at `template` — `ai_template` is not implemented for `send_email` yet. Omit it or send 'template'; anything else is refused.","type":"string","const":"template"},"instruction":{"description":"Has no effect today: it only applies to `ai_template`, which `send_email` does not implement yet. Write the copy in `body`.","type":"string","maxLength":4000},"language":{"description":"Force every message on this step into one language, or set 'auto' so each lead is written to in their OWN language, translating your seed faithfully. OMIT IT and the step uses the default language the sender chose in their settings, or 'auto' when they chose none — which is usually what you want. This rule outranks the seed's original language.","anyOf":[{"type":"string","const":"auto"},{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"]}]},"localization":{"description":"The seed translated into other languages, one per ISO 639-1 code, each keeping every `{{…}}` slot byte-exact and every `---` line. Kairon writes a language here the first time it drafts a lead in it; you may edit any entry and it is then used as written for every later lead in that language. Leave it out to let Kairon translate.","type":"object","properties":{"seedHash":{"type":"string","minLength":1,"description":"Hash of the seed text these translations were made for. Kairon sets it; when the seed changes, the whole object goes stale and is rebuilt. Copy it through unchanged."},"seedLanguage":{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"],"description":"The ISO 639-1 code of the language the seed itself is written in, detected once by Kairon."},"translations":{"type":"object","propertyNames":{"type":"string","enum":["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","io","is","it","iu","ja","jv","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu"]},"additionalProperties":{"type":"string","minLength":1},"description":"One translated seed per ISO 639-1 code. Each must keep every `{{…}}` slot byte-exact and in order, and the same number of `---` lines, or publish refuses it."}},"required":["seedHash","seedLanguage","translations"]},"reviewBeforeSend":{"description":"Default false. True holds every send this step drafts for the operator to approve, even when the campaign is on autopilot. Nothing is scheduled until they approve it.","type":"boolean"},"verifyBeforeSend":{"description":"DEPRECATED, and accepted only so campaigns published before the rename still parse. Set `reviewBeforeSend` instead; if both are present the new one wins.","type":"boolean"},"adaptToCulture":{"description":"Retired: accepted for old steps and ignored. Do not send it.","type":"boolean"},"instantlyCampaignId":{"default":"","type":"string"},"enrichmentBudgetHours":{"description":"Hours (1-72, default 6) to keep waiting for Instantly to find and verify this lead's work email before giving up — the lead then settles as skipped rather than waiting forever, since Instantly gives no signal that an address will never be found.","type":"integer","minimum":1,"maximum":72},"attachments":{"description":"Files sent with this step to every lead it reaches: images and PDFs, plus one voice note and one video on a LinkedIn message.","maxItems":5,"type":"array","items":{"type":"object","properties":{"storageKey":{"type":"string","maxLength":512,"pattern":"^step-attachments\\/.*"},"fileName":{"type":"string","minLength":1,"maxLength":255},"mimeType":{"type":"string","minLength":1,"maxLength":255},"byteSize":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["storageKey","fileName","mimeType","byteSize"],"additionalProperties":false}}},"additionalProperties":false},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]},{"type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":80},"type":{"type":"string","const":"audience_split"},"config":{"type":"object","properties":{"weightA":{"default":50,"description":"Percent of enrolling leads sent down branch A; the rest go down branch B. Use 50 for an even test — 0 or 100 turns the test off and is what applying a winner writes.","type":"integer","minimum":0,"maximum":100},"metric":{"type":"string","enum":["accept_rate","reply_rate"],"description":"What counts as a win when comparing the two branches. Read by Split Review only — it changes nothing about how the campaign runs."},"checkpoint":{"oneOf":[{"type":"object","properties":{"mode":{"type":"string","const":"calculated","description":"Work the sample size out from past results."},"minimumDetectableEffectPoints":{"type":"number","minimum":1,"maximum":50,"description":"The smallest gap worth spotting, in percentage points — 10 means \"tell me once one branch is 10 points ahead\". Smaller numbers need many more leads."}},"required":["mode","minimumDetectableEffectPoints"]},{"type":"object","properties":{"mode":{"type":"string","const":"manual","description":"State the finish line yourself."},"by":{"oneOf":[{"type":"object","properties":{"unit":{"type":"string","const":"date","description":"Finish on a calendar day."},"at":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"The day the test may be judged, `YYYY-MM-DD`, read in the campaign’s own timezone."}},"required":["unit","at"]},{"type":"object","properties":{"unit":{"type":"string","const":"count","description":"Finish on a lead count."},"leadsPerBranch":{"type":"integer","minimum":1,"maximum":9007199254740991,"description":"How many leads EACH branch must reach before a winner may be named."}},"required":["unit","leadsPerBranch"]}],"description":"Whether the finish line is a date or a per-branch lead count."}},"required":["mode","by"]}],"description":"When a winner may be declared. No winner is ever named before this point, however far ahead one branch already looks — an early peek is how an A/B test lies."}},"required":["metric","checkpoint"],"additionalProperties":false},"uiPosition":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"]}},"required":["key","type","config","uiPosition"]}]}},"edges":{"maxItems":300,"type":"array","items":{"type":"object","properties":{"fromKey":{"type":"string","minLength":1,"maxLength":80,"description":"The `key` of the step this edge leaves."},"toKey":{"type":"string","minLength":1,"maxLength":80,"description":"The `key` of the step it routes to."},"condition":{"type":"string","minLength":1,"maxLength":40,"description":"Which OUTCOME of `fromKey` takes this edge — e.g. `sent`, `accepted`, `timeout`, `done`, `default`. Each step type emits a fixed set, and a condition it does not emit is refused. Some are REQUIRED: leave `wait_connection_accepted`'s `accepted` or a `delay`'s `default` unwired and publish fails with `required_outcome_unwired`."}},"required":["fromKey","toKey","condition"]}},"startNodeKey":{"anyOf":[{"type":"string","minLength":1,"maxLength":80},{"type":"null"}]}},"required":["nodes","edges","startNodeKey"],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-self-required":false},"context":{"type":"object","properties":{"campaignId":{"type":"string"},"leadListIds":{"default":[],"type":"array","items":{"type":"string"}},"channelAccountId":{"type":"string"}},"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-self-required":false}},"required":["messages"]},"InboxReplyDto":{"type":"object","properties":{"text":{"type":"string","maxLength":8000},"clientToken":{"description":"Your own idempotency key. Send the SAME token when retrying after a lost response and the message is not sent twice.","type":"string","minLength":1,"maxLength":128},"isRetry":{"type":"boolean"},"cc":{"description":"EMAIL conversations only: up to 5 addresses to copy on the reply, e.g. your main address so the conversation continues there. Refused on a LinkedIn conversation.","maxItems":5,"type":"array","items":{"type":"string","maxLength":320,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}}},"required":["text"]},"InboxEditDto":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":8000}},"required":["text"]},"SnippetCreateDto":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":60},"body":{"type":"string","minLength":1,"maxLength":2000}},"required":["name","body"]},"SnippetUpdateDto":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":60},"body":{"type":"string","minLength":1,"maxLength":2000}}},"ProfileButtonsQualifyDto":{"type":"object","properties":{"icpVersionId":{"type":"string","minLength":1}},"required":["icpVersionId"]},"InitiativeCreateDto":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200,"description":"Short, scannable name for the initiative — \"Expansión Centroamérica\".","x-nestjs_zod-uses-3-point-1-syntax":true},"body":{"description":"The thinking, in markdown: what it tries, why, what would prove it worked, and what has been learned. Free-form on purpose — write what an operator would want to reread in three weeks. Put a teammate on a step by mentioning them: `[@Ana](#kairon-ana@co.com)`, a normal markdown link whose destination is `#kairon-` plus their user id, email, or name (spaces as `+`). It is stored as their id; a name nobody here matches, or one two teammates share, is refused. `seat_list` names them.","anyOf":[{"type":"string","maxLength":20000},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"status":{"description":"`draft` while it is being shaped, `active` once it is being worked.","type":"string","enum":["draft","active","completed","canceled"],"x-nestjs_zod-uses-3-point-1-syntax":true},"priority":{"description":"0 is highest. Lower sorts first, matching every other priority in Kairon.","anyOf":[{"type":"integer","minimum":0,"maximum":3},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"startDate":{"description":"`YYYY-MM-DD`, this century. An initiative starts on a date, not at a moment.","anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"endDate":{"description":"`YYYY-MM-DD`, this century. When the initiative should have paid off, or be called. Must not be before `startDate`.","anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true}},"required":["name"]},"InitiativeUpdateDto":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200,"description":"Short, scannable name for the initiative — \"Expansión Centroamérica\".","x-nestjs_zod-uses-3-point-1-syntax":true},"body":{"description":"The thinking, in markdown: what it tries, why, what would prove it worked, and what has been learned. Free-form on purpose — write what an operator would want to reread in three weeks. Put a teammate on a step by mentioning them: `[@Ana](#kairon-ana@co.com)`, a normal markdown link whose destination is `#kairon-` plus their user id, email, or name (spaces as `+`). It is stored as their id; a name nobody here matches, or one two teammates share, is refused. `seat_list` names them.","anyOf":[{"type":"string","maxLength":20000},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"status":{"description":"`draft` while it is being shaped, `active` once it is being worked.","type":"string","enum":["draft","active","completed","canceled"],"x-nestjs_zod-uses-3-point-1-syntax":true},"priority":{"description":"0 is highest. Lower sorts first, matching every other priority in Kairon.","anyOf":[{"type":"integer","minimum":0,"maximum":3},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"startDate":{"description":"`YYYY-MM-DD`, this century. An initiative starts on a date, not at a moment.","anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"endDate":{"description":"`YYYY-MM-DD`, this century. When the initiative should have paid off, or be called. Must not be before `startDate`.","anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true}}},"CheckpointPublishDto":{"type":"object","properties":{"body":{"type":"string","minLength":1,"maxLength":20000,"description":"What happened and the ONE thing to do next, in markdown. Say the numbers you read and how they compare to this org’s own baseline, and whether the last checkpoint’s recommendation was actually done. To put a teammate’s name on a next step, mention them: `[@Ana](#kairon-ana@co.com)` — a normal markdown link whose destination is `#kairon-` plus their user id, email, or name (spaces as `+`). Whichever you use is stored as their id, and a name nobody here matches, or one two teammates share, is refused rather than saved as prose. Read user ids and names off `seat_list`."},"health":{"type":"string","enum":["on_track","at_risk","off_track"],"description":"The verdict, frozen at publish: `on_track`, `at_risk` or `off_track`. Judge VOLUME before rates — a low number of sends is not a bad result, it is not a result yet."}},"required":["body","health"]},"CheckpointUpdateDto":{"type":"object","properties":{"body":{"type":"string","minLength":1,"maxLength":20000,"description":"What happened and the ONE thing to do next, in markdown. Say the numbers you read and how they compare to this org’s own baseline, and whether the last checkpoint’s recommendation was actually done. To put a teammate’s name on a next step, mention them: `[@Ana](#kairon-ana@co.com)` — a normal markdown link whose destination is `#kairon-` plus their user id, email, or name (spaces as `+`). Whichever you use is stored as their id, and a name nobody here matches, or one two teammates share, is refused rather than saved as prose. Read user ids and names off `seat_list`."},"health":{"type":"string","enum":["on_track","at_risk","off_track"],"description":"The verdict, frozen at publish: `on_track`, `at_risk` or `off_track`. Judge VOLUME before rates — a low number of sends is not a bad result, it is not a result yet."}}},"InitiativeOwnerSetDto":{"type":"object","properties":{"userId":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true}},"required":["userId"]},"PartnerWorkspaceCreateDto":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100}},"required":["name"]},"CreateCsvImportDto":{"type":"object","properties":{"mode":{"type":"string","enum":["people","companies"],"x-nestjs_zod-uses-3-point-1-syntax":true},"country":{"anyOf":[{"type":"string","minLength":2,"maxLength":2},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"fileName":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-empty-type":true},"mapping":{"type":"object","properties":{"firstName":{"type":"string"},"lastName":{"type":"string"},"fullName":{"type":"string"},"company":{"type":"string"},"domain":{"type":"string"},"url":{"type":"string"},"role":{"type":"string"}},"x-nestjs_zod-uses-3-point-1-syntax":true,"x-nestjs_zod-self-required":true},"headers":{"type":"array","items":{"type":"string"},"x-nestjs_zod-uses-3-point-1-syntax":true},"rows":{"minItems":1,"maxItems":6000,"type":"array","items":{"type":"object","properties":{"rowIndex":{"type":"integer","minimum":0,"maximum":9007199254740991},"raw":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["rowIndex","raw"]},"x-nestjs_zod-uses-3-point-1-syntax":true}},"required":["mode","mapping","headers","rows"]},"CsvImportCompleteDto":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200}},"required":["name"]},"StartEmailEnrichmentDto":{"type":"object","properties":{"sampleSize":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991,"x-nestjs_zod-uses-3-point-1-syntax":true},"onlyQualified":{"type":"boolean","x-nestjs_zod-uses-3-point-1-syntax":true}}},"CopilotEditSendDto":{"type":"object","properties":{"body":{"type":"string","maxLength":8000},"subject":{"type":"string","minLength":1,"maxLength":200}},"required":["body"]},"CopilotRegenerateDto":{"type":"object","properties":{"feedback":{"type":"string","maxLength":4000}}},"ContentSettingsInputDto":{"type":"object","properties":{"checks":{"maxItems":20,"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":128,"description":"Stable id of an EXISTING check, to revise it. Omit it and a new check is minted."},"description":{"type":"string","minLength":1,"maxLength":2000,"description":"The rule itself, phrased so a draft can be judged against it and either passes or does not — \"No em dashes anywhere in the post\" works. A note to yourself about how the writing should feel gives nothing to test, so it silently never fires."}},"required":["description"]}},"competitorUrls":{"default":[],"maxItems":50,"type":"array","items":{"type":"string","maxLength":2048,"format":"uri"}},"sourceUrls":{"default":[],"maxItems":50,"type":"array","items":{"type":"string","maxLength":2048,"format":"uri"}}}},"NotificationSettingsInputDto":{"type":"object","properties":{"dailyDigestEnabled":{"type":"boolean"},"weeklyCheckpointEnabled":{"type":"boolean"},"campaignAlertsEnabled":{"type":"boolean"},"qualificationReportsEnabled":{"type":"boolean"},"nextStepEmailsEnabled":{"type":"boolean"}}},"AgentContentChatDto":{"type":"object","properties":{"messages":{"minItems":1,"maxItems":200,"type":"array","items":{}},"model":{"type":"string","minLength":3,"maxLength":120,"pattern":"^[a-z0-9][a-z0-9._-]*\\/[a-z0-9][a-z0-9._:-]*$"},"effort":{"type":"string","enum":["minimal","low","medium","high"]},"draftSnapshot":{"type":"string"}},"required":["messages"]},"ConnectInstantlyDto":{"type":"object","properties":{"apiKey":{"type":"string","minLength":1,"maxLength":500},"timeZone":{"type":"string","maxLength":100}},"required":["apiKey"]},"AdoptKaironWorkspaceDto":{"type":"object","properties":{"kaironWorkspaceId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"timeZone":{"type":"string","maxLength":100}},"required":["kaironWorkspaceId"]},"SearchSendingDomainDto":{"type":"object","properties":{"domain":{"type":"string","minLength":4,"maxLength":253,"pattern":"^[a-z0-9][a-z0-9-]*(\\.[a-z0-9-]+)*\\.(com|org)$","description":"The domain name to buy and send from, like `acme-outreach.com`. Only `.com` and `.org` can be registered, and a name carrying a well-known trademark is refused. Not the customer's real website — a sending domain is a separate name, so a problem with it never touches their main domain's reputation."}},"required":["domain"]},"QuoteSendingDomainDto":{"type":"object","properties":{"domain":{"type":"string","minLength":4,"maxLength":253,"pattern":"^[a-z0-9][a-z0-9-]*(\\.[a-z0-9-]+)*\\.(com|org)$","description":"The domain name to buy and send from, like `acme-outreach.com`. Only `.com` and `.org` can be registered, and a name carrying a well-known trademark is refused. Not the customer's real website — a sending domain is a separate name, so a problem with it never touches their main domain's reputation."},"mailboxes":{"minItems":1,"maxItems":5,"type":"array","items":{"type":"object","properties":{"emailAddressPrefix":{"type":"string","minLength":1,"maxLength":64,"description":"The part before the `@` — `ada` becomes `ada@the-domain.com`."},"firstName":{"type":"string","minLength":1,"maxLength":100,"description":"The mailbox owner's first name, as it appears in the From line of every email sent from it."},"lastName":{"type":"string","minLength":1,"maxLength":100,"description":"The mailbox owner's last name."}},"required":["emailAddressPrefix","firstName","lastName"]},"description":"The mailboxes to create on the domain — one to five, each a real person on the team, since a recipient who replies is replying to that name. More mailboxes means more sending capacity and more monthly cost."},"forwardingDomain":{"description":"The customer's real website, where a visitor to the sending domain is sent — `acme.com`. Worth setting: a sending domain that resolves to nothing is exactly what a suspicious recipient checks. Any extension, not just .com/.org. Ask the operator; never guess it from their email address.","type":"string"}},"required":["domain","mailboxes"]},"BuySendingDomainDto":{"type":"object","properties":{"domain":{"type":"string","minLength":4,"maxLength":253,"pattern":"^[a-z0-9][a-z0-9-]*(\\.[a-z0-9-]+)*\\.(com|org)$","description":"The domain name to buy and send from, like `acme-outreach.com`. Only `.com` and `.org` can be registered, and a name carrying a well-known trademark is refused. Not the customer's real website — a sending domain is a separate name, so a problem with it never touches their main domain's reputation."},"mailboxes":{"minItems":1,"maxItems":5,"type":"array","items":{"type":"object","properties":{"emailAddressPrefix":{"type":"string","minLength":1,"maxLength":64,"description":"The part before the `@` — `ada` becomes `ada@the-domain.com`."},"firstName":{"type":"string","minLength":1,"maxLength":100,"description":"The mailbox owner's first name, as it appears in the From line of every email sent from it."},"lastName":{"type":"string","minLength":1,"maxLength":100,"description":"The mailbox owner's last name."}},"required":["emailAddressPrefix","firstName","lastName"]},"description":"The mailboxes to create on the domain — one to five, each a real person on the team, since a recipient who replies is replying to that name. More mailboxes means more sending capacity and more monthly cost."},"forwardingDomain":{"description":"The customer's real website, where a visitor to the sending domain is sent — `acme.com`. Worth setting: a sending domain that resolves to nothing is exactly what a suspicious recipient checks. Any extension, not just .com/.org. Ask the operator; never guess it from their email address.","type":"string"},"agreedTotal":{"type":"number","minimum":0,"maximum":10000,"description":"The `dueNow` from the quote the operator agreed to, in whole dollars. The order is re-priced against the vendor immediately before buying and refused if the number moved, so a stale quote can never charge a different amount than the one shown."}},"required":["domain","mailboxes","agreedTotal"]},"EmailPlanRequestDto":{"type":"object","properties":{"kind":{"type":"string","enum":["plan","credits"],"description":"`plan` to have Kairon set this workspace up for email sending at all; `credits` to add enrichment credits, which are what finds a prospect's email address. Ask for `plan` first — credits are useless without somewhere to send from."},"quantity":{"default":1,"description":"How many credit packs are wanted. Ignored for `plan` — there is one workspace.","type":"integer","minimum":1,"maximum":20}},"required":["kind"]},"AddOwnedMailboxDto":{"type":"object","properties":{"email":{"type":"string","maxLength":254,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$","description":"The full address of a mailbox the customer already owns, like `ada@acme.com`."},"firstName":{"type":"string","minLength":1,"maxLength":100,"description":"The mailbox owner's first name — it appears in the From line of every send."},"lastName":{"type":"string","minLength":1,"maxLength":100,"description":"The mailbox owner's last name."},"provider":{"type":"string","enum":["google","microsoft","custom"],"description":"Who hosts the mailbox. `google` for Google Workspace or Gmail, `microsoft` for Microsoft 365 or Outlook — both fill in their own server settings. `custom` for anything else, and then all four host and port fields are required."},"password":{"type":"string","minLength":1,"maxLength":500,"description":"An APP PASSWORD for the mailbox, not the account password. For Google the operator creates one in their Google account with 2-step verification on. Ask them for it directly and never invent one; it is passed straight to the sending provider and stored nowhere in Kairon."},"smtpHost":{"description":"Outgoing mail server, `custom` provider only (Google and Microsoft are known).","type":"string","maxLength":253},"smtpPort":{"description":"Outgoing mail port, `custom` provider only — usually 465 or 587.","type":"integer","minimum":1,"maximum":65535},"imapHost":{"description":"Incoming mail server, `custom` provider only.","type":"string","maxLength":253},"imapPort":{"description":"Incoming mail port, `custom` provider only — usually 993.","type":"integer","minimum":1,"maximum":65535}},"required":["email","firstName","lastName","provider","password"]},"StartMailboxOauthDto":{"type":"object","properties":{"provider":{"type":"string","enum":["google","microsoft"]}},"required":["provider"]},"MailboxOauthStatusDto":{"type":"object","properties":{"sessionId":{"type":"string","minLength":1}},"required":["sessionId"]},"LearnLessonProgressDto":{"type":"object","properties":{"completed":{"type":"boolean"}},"required":["completed"]}}},"security":[{"api-key":[]}]}