{"tools":[{"name":"needleGetMe","title":"Get the authenticated user","description":"Returns the user and the workspace (`organization`) this caller is bound to.","category":"Me","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{}}},{"name":"needleListLeads","title":"List leads","description":"List a page of leads in this workspace. Use nextCursor as cursor for the next page.","category":"Leads","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"cursor":{"type":"string","minLength":1},"limit":{"type":"integer","minimum":1,"maximum":100}}}},{"name":"needleListLeadProperties","title":"List lead properties","description":"List every custom property key leads in this workspace use, with its type, lead count and most common values. Use them as properties.<key> in needleSearchLeads filters.","category":"Leads","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{}}},{"name":"needleUpdateLeadProperty","title":"Update a lead property","description":"Change how a custom property is compared when filtering (type: string, number, boolean, date), or whether it shows as a column in the leads table. Stored values are not changed.","category":"Leads","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"key":{"type":"string","minLength":1,"maxLength":256,"description":"Property key"},"type":{"type":"string","enum":["string","number","boolean","date"],"description":"How values are compared when filtering. Values are always stored as text; the type is guessed from the first value seen and can be changed."},"showAsColumn":{"type":"boolean","description":"Show this property as a column in the leads table."}},"required":["key"]}},{"name":"needleSearchLeads","title":"Search leads","description":"Find leads already in this workspace. With a query, best matches come first (name, then email starting with it); without one, newest first. Every word in query must appear in the name, email, company, title, or a handle. Filter built-in fields (jobTitle, companyDomain, createdAt…) or custom properties as properties.<key>; call needleListLeadProperties first for the keys, types and common values. Pass nextCursor as cursor, with the same query and filters, for the next page.","category":"Leads","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"query":{"description":"Free text. Every word must appear in the name, email, company, company domain, job title, or a profile handle. Combined with filters.","type":"string","maxLength":200},"filters":{"default":[],"description":"Every filter must match.","maxItems":20,"type":"array","items":{"type":"object","properties":{"field":{"type":"string","minLength":1,"maxLength":300,"description":"A built-in field (firstName, lastName, jobTitle, companyName, companyDomain, email, createdAt, updatedAt, createdBy, updatedBy, enrollmentStatus) or a custom property as properties.<key>, e.g. properties.industry. List custom properties and their types with GET /api/v1/lead-properties."},"operator":{"type":"string","enum":["eq","neq","in","not_in","contains","not_contains","starts_with","gt","gte","lt","lte","before","after","on","between","is_set","is_not_set"],"description":"string: eq, neq, in, not_in, contains, not_contains, starts_with. number: eq, neq, gt, gte, lt, lte. date: before, after, on, between. boolean: eq. Every type: is_set, is_not_set. createdBy and updatedBy (a member id): eq, neq, in, not_in. enrollmentStatus (active, waiting, completed, stopped, failed): eq and in match leads with any enrollment in those statuses, neq and not_in leads with none; is_set means enrolled in any campaign, is_not_set never enrolled. String matching ignores case. neq, not_in and not_contains also match leads without a value."},"value":{"description":"Omit for is_set and is_not_set. A list for in and not_in. Dates as YYYY-MM-DD, in UTC; two dates [from, to] for between, both inclusive. createdAt and updatedAt also take ISO 8601 instants with an offset, e.g. 2026-10-22T22:00:00Z, to bound by time instead of whole UTC days: before matches earlier, after matches at or later, and between includes from and excludes to. on always takes a date.","anyOf":[{"anyOf":[{"type":"string","maxLength":1000},{"type":"number"},{"type":"boolean"}]},{"minItems":1,"maxItems":100,"type":"array","items":{"anyOf":[{"type":"string","maxLength":1000},{"type":"number"},{"type":"boolean"}]}}]}},"required":["field","operator"]}},"cursor":{"type":"string","minLength":1},"limit":{"type":"integer","minimum":1,"maximum":100}}}},{"name":"needleCreateLead","title":"Create a lead","description":"Create a lead. Fails when an identity already belongs to a lead (the error data has that leadId); use needleUpsertLead to create-or-update. LinkedIn identity accepts john-doe, /in/john-doe, https://www.linkedin.com/in/john-doe, or a user id (ACoAAA…). Instagram accepts john-doe, @john-doe, or https://www.instagram.com/john-doe.","category":"Leads","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"identities":{"type":"object","properties":{"linkedin":{"type":"string","minLength":1,"description":"Public identifier (john-doe), /in/ path (/in/john-doe or in/john-doe), profile URL (https://www.linkedin.com/in/john-doe), or user id (ACoAAA…). Stored as the identifier, not the URL."},"instagram":{"type":"string","minLength":1,"description":"Username (john-doe), handle (@john-doe), or profile URL (https://www.instagram.com/john-doe). Stored as the username without @."}}},"timezone":{"type":"string"},"firstName":{"type":"string","maxLength":256},"lastName":{"type":"string","maxLength":256},"companyName":{"type":"string","maxLength":256},"companyDomain":{"type":"string","maxLength":256},"jobTitle":{"type":"string","maxLength":256},"email":{"type":"string","maxLength":256},"imageUrl":{"type":"string","maxLength":2048},"properties":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["identities","timezone"]}},{"name":"needleUpsertLead","title":"Create or update a lead","description":"Create a lead, or when a LinkedIn or Instagram identity already belongs to one, patch the fields sent onto it. Returns created or matched with the lead. Same identity formats as needleCreateLead.","category":"Leads","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"identities":{"type":"object","properties":{"linkedin":{"type":"string","minLength":1,"description":"Public identifier (john-doe), /in/ path (/in/john-doe or in/john-doe), profile URL (https://www.linkedin.com/in/john-doe), or user id (ACoAAA…). Stored as the identifier, not the URL."},"instagram":{"type":"string","minLength":1,"description":"Username (john-doe), handle (@john-doe), or profile URL (https://www.instagram.com/john-doe). Stored as the username without @."}}},"timezone":{"type":"string"},"firstName":{"type":"string","maxLength":256},"lastName":{"type":"string","maxLength":256},"companyName":{"type":"string","maxLength":256},"companyDomain":{"type":"string","maxLength":256},"jobTitle":{"type":"string","maxLength":256},"email":{"type":"string","maxLength":256},"imageUrl":{"type":"string","maxLength":2048},"properties":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["identities","timezone"]}},{"name":"needleCreateLeads","title":"Create leads in bulk","description":"Create up to 500 leads at once, matching on identity so re-sending a list does not duplicate anyone. Returns created, matched, or skipped per row, in request order, with the lead id to enroll. Same identity formats as needleCreateLead.","category":"Leads","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"leads":{"minItems":1,"maxItems":500,"type":"array","items":{"type":"object","properties":{"identities":{"default":{},"type":"object","properties":{"linkedin":{"type":"string","minLength":1,"description":"Public identifier (john-doe), /in/ path (/in/john-doe or in/john-doe), profile URL (https://www.linkedin.com/in/john-doe), or user id (ACoAAA…). Stored as the identifier, not the URL."},"instagram":{"type":"string","minLength":1,"description":"Username (john-doe), handle (@john-doe), or profile URL (https://www.instagram.com/john-doe). Stored as the username without @."}}},"timezone":{"type":"string"},"firstName":{"type":"string","maxLength":256},"lastName":{"type":"string","maxLength":256},"companyName":{"type":"string","maxLength":256},"companyDomain":{"type":"string","maxLength":256},"jobTitle":{"type":"string","maxLength":256},"email":{"type":"string","maxLength":256},"imageUrl":{"type":"string","maxLength":2048},"properties":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["timezone"]}}},"required":["leads"]}},{"name":"needleGetLead","title":"Get a lead","description":"Get a lead, its identities, and enrollments.","category":"Leads","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"leadId":{"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)$","description":"Lead id"}},"required":["leadId"]}},{"name":"needleUpdateLead","title":"Update a lead","description":"Update a lead profile or identities.","category":"Leads","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"leadId":{"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)$","description":"Lead id"},"identities":{"type":"object","properties":{"linkedin":{"type":"string","minLength":1,"description":"Public identifier (john-doe), /in/ path (/in/john-doe or in/john-doe), profile URL (https://www.linkedin.com/in/john-doe), or user id (ACoAAA…). Stored as the identifier, not the URL."},"instagram":{"type":"string","minLength":1,"description":"Username (john-doe), handle (@john-doe), or profile URL (https://www.instagram.com/john-doe). Stored as the username without @."}}},"timezone":{"type":"string"},"firstName":{"type":"string","maxLength":256},"lastName":{"type":"string","maxLength":256},"companyName":{"type":"string","maxLength":256},"companyDomain":{"type":"string","maxLength":256},"jobTitle":{"type":"string","maxLength":256},"email":{"type":"string","maxLength":256},"imageUrl":{"type":"string","maxLength":2048},"properties":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["leadId"]}},{"name":"needleUpdateLeads","title":"Update leads in bulk","description":"Update up to 500 existing leads by id; never creates leads. Each row takes leadId plus the fields to change, same as needleUpdateLead. Returns updated or skipped per row in request order; skipped rows say why (lead_not_found, invalid_identity, or identity_taken with the conflictingLeadId).","category":"Leads","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"leads":{"minItems":1,"maxItems":500,"type":"array","items":{"type":"object","properties":{"identities":{"type":"object","properties":{"linkedin":{"type":"string","minLength":1,"description":"Public identifier (john-doe), /in/ path (/in/john-doe or in/john-doe), profile URL (https://www.linkedin.com/in/john-doe), or user id (ACoAAA…). Stored as the identifier, not the URL."},"instagram":{"type":"string","minLength":1,"description":"Username (john-doe), handle (@john-doe), or profile URL (https://www.instagram.com/john-doe). Stored as the username without @."}}},"timezone":{"type":"string"},"firstName":{"type":"string","maxLength":256},"lastName":{"type":"string","maxLength":256},"companyName":{"type":"string","maxLength":256},"companyDomain":{"type":"string","maxLength":256},"jobTitle":{"type":"string","maxLength":256},"email":{"type":"string","maxLength":256},"imageUrl":{"type":"string","maxLength":2048},"properties":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"leadId":{"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)$","description":"The lead to update."}},"required":["leadId"]}}},"required":["leads"]}},{"name":"needleDeleteLead","title":"Delete a lead","description":"Delete a lead.","category":"Leads","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"leadId":{"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)$","description":"Lead id"}},"required":["leadId"]}},{"name":"needleDeleteLeads","title":"Delete leads in bulk","description":"Delete up to 500 leads by id, stopping their live campaign enrollments. Returns deleted or skipped (lead_not_found) per id in request order; retrying is safe.","category":"Leads","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"leadIds":{"minItems":1,"maxItems":500,"type":"array","items":{"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)$"},"description":"The leads to delete."}},"required":["leadIds"]}},{"name":"needleListLeadEvents","title":"List lead events","description":"List a page of events for a lead. Use nextCursor as cursor for the next page.","category":"Leads","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"leadId":{"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)$","description":"Lead id"},"cursor":{"type":"string","minLength":1},"limit":{"type":"integer","minimum":1,"maximum":100}},"required":["leadId"]}},{"name":"needleListLeadTasks","title":"List lead tasks","description":"List a page of the actions campaigns owe a lead, earliest scheduled first. Use nextCursor as cursor for the next page.","category":"Leads","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"leadId":{"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)$","description":"Lead id"},"cursor":{"type":"string","minLength":1},"limit":{"type":"integer","minimum":1,"maximum":100},"status":{"type":"string","enum":["pending","pending_approval"]}},"required":["leadId"]}},{"name":"needleListCampaigns","title":"List campaigns","description":"List a page of campaigns. Filter by status. Use nextCursor as cursor for the next page. Results leave out the step graph; use needleGetCampaign for it.","category":"Campaigns","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"cursor":{"type":"string","minLength":1},"limit":{"type":"integer","minimum":1,"maximum":100},"status":{"type":"string","enum":["draft","active","paused","archived"]}}}},{"name":"needleSearchCampaigns","title":"Search campaigns","description":"Find campaigns in this workspace by name. Every word in query must match; names starting with it come first. Pass nextCursor as cursor, with the same query, for more. Results leave out the step graph; use the returned id with needleGetCampaign for it.","category":"Campaigns","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"query":{"type":"string","minLength":1,"maxLength":200,"description":"Text to match. Every word must appear in the record."},"cursor":{"type":"string","minLength":1},"limit":{"type":"integer","minimum":1,"maximum":100}},"required":["query"]}},{"name":"needleSearchEnrollments","title":"Search enrollments","description":"Find enrollments by the lead or the campaign name. Every word in query must match; lead names starting with it come first. Pass campaignId to search inside one campaign. Pass nextCursor as cursor, with the same query and campaignId, for more. Each enrollment includes campaignId and campaignName.","category":"Campaigns","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"query":{"type":"string","minLength":1,"maxLength":200,"description":"Text to match. Every word must appear in the record."},"cursor":{"type":"string","minLength":1},"limit":{"type":"integer","minimum":1,"maximum":100},"campaignId":{"description":"Only enrollments in this campaign.","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)$"}},"required":["query"]}},{"name":"needleCreateCampaign","title":"Create a campaign","description":"Create a campaign.","category":"Campaigns","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":256},"graph":{"type":"object","properties":{"nodes":{"minItems":2,"type":"array","items":{"oneOf":[{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-zA-Z0-9_-]+$"},"kind":{"type":"string","const":"start"},"label":{"type":"string","maxLength":120}},"required":["id","kind"]},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-zA-Z0-9_-]+$"},"kind":{"type":"string","const":"end"},"label":{"type":"string","maxLength":120}},"required":["id","kind"]},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-zA-Z0-9_-]+$"},"kind":{"type":"string","const":"delay"},"label":{"type":"string","maxLength":120},"duration":{"type":"object","properties":{"days":{"default":0,"type":"integer","minimum":0,"maximum":90},"hours":{"default":0,"type":"integer","minimum":0,"maximum":23},"minutes":{"default":0,"type":"integer","minimum":0,"maximum":59}}}},"required":["id","kind","duration"]},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-zA-Z0-9_-]+$"},"kind":{"type":"string","const":"action"},"label":{"type":"string","maxLength":120},"channel":{"type":"string","enum":["linkedin","instagram"]},"connectedAccountId":{"description":"Account that sends this step.","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)$"},"action":{"type":"string","enum":["linkedin_invitation","linkedin_cancel_invitation","linkedin_message","linkedin_inmail","linkedin_profile_view","linkedin_search","linkedin_comment","linkedin_reaction","linkedin_post_view","linkedin_company_view","linkedin_job_view","linkedin_conversation_view","linkedin_network_view","linkedin_invitation_list","linkedin_invitation_response","linkedin_search_parameter","linkedin_inmail_balance","linkedin_own_profile","instagram_message","instagram_profile_view","instagram_follow","instagram_unfollow","instagram_comment","instagram_reaction","instagram_post","instagram_post_view","instagram_conversation_view","instagram_network_view","instagram_own_profile"]},"content":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"template"},"text":{"type":"string","minLength":1},"subject":{"description":"InMail subject line. Required on linkedin_inmail template steps; omit on other steps.","type":"string","minLength":1}},"required":["kind","text"]},{"type":"object","properties":{"kind":{"type":"string","const":"ai"},"prompt":{"type":"string","minLength":1},"context":{"default":["conversation"],"type":"array","items":{"type":"string","enum":["profile","posts","conversation","lead_properties"]}},"maxChars":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"fallbackText":{"type":"string"},"requiresApproval":{"default":false,"type":"boolean"}},"required":["kind","prompt"]}]},"attachments":{"description":"LinkedIn message and InMail only. Files from POST /api/v1/files; store the returned url, not a signed URL.","maxItems":5,"type":"array","items":{"type":"object","properties":{"url":{"type":"string","maxLength":4096,"format":"uri","description":"Object URL returned by POST /api/v1/files. Not a signed URL and not passed to LinkedIn."},"filename":{"type":"string","minLength":1,"maxLength":255},"contentType":{"type":"string","minLength":1,"maxLength":127},"size":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["url"]}}},"required":["id","kind","channel","action"]},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-zA-Z0-9_-]+$"},"kind":{"type":"string","const":"condition"},"label":{"type":"string","maxLength":120},"channel":{"type":"string","enum":["linkedin","instagram"]},"connectedAccountId":{"description":"Account this check runs against.","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)$"},"test":{"oneOf":[{"type":"object","properties":{"predicate":{"type":"string","const":"is_connection"}},"required":["predicate"]},{"type":"object","properties":{"predicate":{"type":"string","const":"has_attribute"},"attribute":{"type":"string","minLength":1,"maxLength":64},"equals":{"type":"string","maxLength":256}},"required":["predicate","attribute"]}]}},"required":["id","kind","channel","test"]},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-zA-Z0-9_-]+$"},"kind":{"type":"string","const":"wait_until"},"label":{"type":"string","maxLength":120},"channel":{"type":"string","enum":["linkedin","instagram"]},"connectedAccountId":{"description":"Account this wait listens on.","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)$"},"event":{"type":"string","enum":["linkedin_invite_accepted","linkedin_message_received","instagram_message_received"]},"timeout":{"type":"object","properties":{"days":{"default":0,"type":"integer","minimum":0,"maximum":90},"hours":{"default":0,"type":"integer","minimum":0,"maximum":23},"minutes":{"default":0,"type":"integer","minimum":0,"maximum":59}}}},"required":["id","kind","channel","event","timeout"]}]}},"edges":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-zA-Z0-9_-]+$"},"to":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-zA-Z0-9_-]+$"},"label":{"default":"next","type":"string","enum":["next","yes","no","on_event","on_timeout"]}},"required":["from","to"]}}},"required":["nodes","edges"]},"schedule":{"type":"object","properties":{"workingDays":{"default":[1,2,3,4,5],"minItems":1,"type":"array","items":{"type":"integer","minimum":0,"maximum":6}},"startTime":{"default":"09:00","type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$"},"endTime":{"default":"17:00","type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$"}}},"limits":{"type":"object","properties":{"minGapSeconds":{"default":30,"type":"integer","minimum":10,"maximum":300},"maxGapSeconds":{"default":60,"type":"integer","minimum":10,"maximum":300}}},"suppressionPolicy":{"type":"object","properties":{"bypassSuppressionReasons":{"default":[],"type":"array","items":{"type":"string","enum":["manual","unsubscribed","not_interested","existing_customer","open_opportunity","competitor","employee","invalid_recipient","complained","recently_contacted","unresponsive"]}},"cooldownDays":{"default":30,"type":"integer","minimum":0,"maximum":365},"unresponsiveAfterTouches":{"default":3,"type":"integer","minimum":0,"maximum":50},"autoSuppressKeywords":{"default":["unsubscribe","stop contacting","do not contact","remove me","take me off","not interested"],"type":"array","items":{"type":"string"}}}}},"required":["name","graph"]}},{"name":"needleGetCampaign","title":"Get a campaign","description":"Get a campaign by id.","category":"Campaigns","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"campaignId":{"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)$","description":"Campaign id"}},"required":["campaignId"]}},{"name":"needleUpdateCampaign","title":"Update a campaign","description":"Update a campaign.","category":"Campaigns","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"campaignId":{"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)$","description":"Campaign id"},"name":{"type":"string","minLength":1,"maxLength":256},"status":{"type":"string","enum":["active","paused"]},"graph":{"type":"object","properties":{"nodes":{"minItems":2,"type":"array","items":{"oneOf":[{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-zA-Z0-9_-]+$"},"kind":{"type":"string","const":"start"},"label":{"type":"string","maxLength":120}},"required":["id","kind"]},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-zA-Z0-9_-]+$"},"kind":{"type":"string","const":"end"},"label":{"type":"string","maxLength":120}},"required":["id","kind"]},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-zA-Z0-9_-]+$"},"kind":{"type":"string","const":"delay"},"label":{"type":"string","maxLength":120},"duration":{"type":"object","properties":{"days":{"default":0,"type":"integer","minimum":0,"maximum":90},"hours":{"default":0,"type":"integer","minimum":0,"maximum":23},"minutes":{"default":0,"type":"integer","minimum":0,"maximum":59}}}},"required":["id","kind","duration"]},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-zA-Z0-9_-]+$"},"kind":{"type":"string","const":"action"},"label":{"type":"string","maxLength":120},"channel":{"type":"string","enum":["linkedin","instagram"]},"connectedAccountId":{"description":"Account that sends this step.","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)$"},"action":{"type":"string","enum":["linkedin_invitation","linkedin_cancel_invitation","linkedin_message","linkedin_inmail","linkedin_profile_view","linkedin_search","linkedin_comment","linkedin_reaction","linkedin_post_view","linkedin_company_view","linkedin_job_view","linkedin_conversation_view","linkedin_network_view","linkedin_invitation_list","linkedin_invitation_response","linkedin_search_parameter","linkedin_inmail_balance","linkedin_own_profile","instagram_message","instagram_profile_view","instagram_follow","instagram_unfollow","instagram_comment","instagram_reaction","instagram_post","instagram_post_view","instagram_conversation_view","instagram_network_view","instagram_own_profile"]},"content":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"template"},"text":{"type":"string","minLength":1},"subject":{"description":"InMail subject line. Required on linkedin_inmail template steps; omit on other steps.","type":"string","minLength":1}},"required":["kind","text"]},{"type":"object","properties":{"kind":{"type":"string","const":"ai"},"prompt":{"type":"string","minLength":1},"context":{"default":["conversation"],"type":"array","items":{"type":"string","enum":["profile","posts","conversation","lead_properties"]}},"maxChars":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"fallbackText":{"type":"string"},"requiresApproval":{"default":false,"type":"boolean"}},"required":["kind","prompt"]}]},"attachments":{"description":"LinkedIn message and InMail only. Files from POST /api/v1/files; store the returned url, not a signed URL.","maxItems":5,"type":"array","items":{"type":"object","properties":{"url":{"type":"string","maxLength":4096,"format":"uri","description":"Object URL returned by POST /api/v1/files. Not a signed URL and not passed to LinkedIn."},"filename":{"type":"string","minLength":1,"maxLength":255},"contentType":{"type":"string","minLength":1,"maxLength":127},"size":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["url"]}}},"required":["id","kind","channel","action"]},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-zA-Z0-9_-]+$"},"kind":{"type":"string","const":"condition"},"label":{"type":"string","maxLength":120},"channel":{"type":"string","enum":["linkedin","instagram"]},"connectedAccountId":{"description":"Account this check runs against.","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)$"},"test":{"oneOf":[{"type":"object","properties":{"predicate":{"type":"string","const":"is_connection"}},"required":["predicate"]},{"type":"object","properties":{"predicate":{"type":"string","const":"has_attribute"},"attribute":{"type":"string","minLength":1,"maxLength":64},"equals":{"type":"string","maxLength":256}},"required":["predicate","attribute"]}]}},"required":["id","kind","channel","test"]},{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-zA-Z0-9_-]+$"},"kind":{"type":"string","const":"wait_until"},"label":{"type":"string","maxLength":120},"channel":{"type":"string","enum":["linkedin","instagram"]},"connectedAccountId":{"description":"Account this wait listens on.","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)$"},"event":{"type":"string","enum":["linkedin_invite_accepted","linkedin_message_received","instagram_message_received"]},"timeout":{"type":"object","properties":{"days":{"default":0,"type":"integer","minimum":0,"maximum":90},"hours":{"default":0,"type":"integer","minimum":0,"maximum":23},"minutes":{"default":0,"type":"integer","minimum":0,"maximum":59}}}},"required":["id","kind","channel","event","timeout"]}]}},"edges":{"type":"array","items":{"type":"object","properties":{"from":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-zA-Z0-9_-]+$"},"to":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-zA-Z0-9_-]+$"},"label":{"default":"next","type":"string","enum":["next","yes","no","on_event","on_timeout"]}},"required":["from","to"]}}},"required":["nodes","edges"]},"schedule":{"type":"object","properties":{"workingDays":{"default":[1,2,3,4,5],"minItems":1,"type":"array","items":{"type":"integer","minimum":0,"maximum":6}},"startTime":{"default":"09:00","type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$"},"endTime":{"default":"17:00","type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$"}}},"limits":{"type":"object","properties":{"minGapSeconds":{"default":30,"type":"integer","minimum":10,"maximum":300},"maxGapSeconds":{"default":60,"type":"integer","minimum":10,"maximum":300}}},"suppressionPolicy":{"type":"object","properties":{"bypassSuppressionReasons":{"default":[],"type":"array","items":{"type":"string","enum":["manual","unsubscribed","not_interested","existing_customer","open_opportunity","competitor","employee","invalid_recipient","complained","recently_contacted","unresponsive"]}},"cooldownDays":{"default":30,"type":"integer","minimum":0,"maximum":365},"unresponsiveAfterTouches":{"default":3,"type":"integer","minimum":0,"maximum":50},"autoSuppressKeywords":{"default":["unsubscribe","stop contacting","do not contact","remove me","take me off","not interested"],"type":"array","items":{"type":"string"}}}}},"required":["campaignId"]}},{"name":"needleArchiveCampaign","title":"Archive a campaign","description":"Archive a campaign.","category":"Campaigns","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"campaignId":{"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)$","description":"Campaign id"}},"required":["campaignId"]}},{"name":"needleGetCampaignStats","title":"Get campaign stats","description":"Campaign progress, funnel (distinct leads per stage), enrollments, and steps (including current and completed leads per step) for a campaign.","category":"Campaigns","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"campaignId":{"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)$","description":"Campaign id"}},"required":["campaignId"]}},{"name":"needleListCampaignEvents","title":"List campaign events","description":"List a page of campaign events. Use nextCursor as cursor for the next page.","category":"Campaigns","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"campaignId":{"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)$","description":"Campaign id"},"cursor":{"type":"string","minLength":1},"limit":{"type":"integer","minimum":1,"maximum":100}},"required":["campaignId"]}},{"name":"needleListCampaignTasks","title":"List campaign tasks","description":"List a page of the actions this campaign owes its leads, earliest scheduled first. Use nextCursor as cursor for the next page.","category":"Campaigns","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"campaignId":{"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)$","description":"Campaign id"},"cursor":{"type":"string","minLength":1},"limit":{"type":"integer","minimum":1,"maximum":100},"status":{"type":"string","enum":["pending","pending_approval"]}},"required":["campaignId"]}},{"name":"needleListCampaignLeads","title":"List campaign leads","description":"List a page of leads enrolled in a campaign. Use nextCursor as cursor for the next page.","category":"Campaigns","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"campaignId":{"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)$","description":"Campaign id"},"cursor":{"type":"string","minLength":1},"limit":{"type":"integer","minimum":1,"maximum":100}},"required":["campaignId"]}},{"name":"needleEnrollCampaignLeads","title":"Enroll leads","description":"Enroll existing leads in a campaign, by lead id. Create the leads first with needleCreateLead or needleCreateLeads. A lead without a handle for every channel the campaign sends on is skipped as missing_identity. Contactability skips are suppressed (do-not-contact list), recently_contacted, or unresponsive — not every skip means the lead is on the list. Returns accepted or skipped per lead id.","category":"Campaigns","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"campaignId":{"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)$","description":"Campaign id"},"leadIds":{"minItems":1,"maxItems":500,"type":"array","items":{"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)$"},"description":"Leads to enroll, by id. Create them first with POST /api/v1/leads or POST /api/v1/leads/bulk."}},"required":["campaignId","leadIds"]}},{"name":"needleRemoveCampaignLead","title":"Stop a lead in a campaign","description":"Stop a live lead enrollment in a campaign.","category":"Campaigns","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"campaignId":{"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)$","description":"Campaign id"},"leadId":{"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)$","description":"Lead id"}},"required":["campaignId","leadId"]}},{"name":"needleStopCampaignLeads","title":"Stop leads in a campaign in bulk","description":"Stop the live enrollments of up to 500 leads in a campaign, by lead id. Returns stopped or skipped (not_live: nothing live for that lead in this campaign) per lead id in request order; retrying is safe.","category":"Campaigns","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"campaignId":{"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)$","description":"Campaign id"},"leadIds":{"minItems":1,"maxItems":500,"type":"array","items":{"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)$"},"description":"Leads to stop, by id."}},"required":["campaignId","leadIds"]}},{"name":"needleListDrafts","title":"List drafts","description":"List a page of drafted messages, newest first. By default only the ones waiting for a person to review them in the Needle inbox; pass status for sent, failed or discarded ones. Filter by campaignId, leadId or connectedAccountId. Use nextCursor as cursor for the next page.","category":"Drafts","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"cursor":{"type":"string","minLength":1},"limit":{"type":"integer","minimum":1,"maximum":100},"status":{"default":"awaiting_review","description":"Defaults to the drafts waiting for review.","type":"string","enum":["awaiting_review","sent","failed","discarded"]},"campaignId":{"description":"Only drafts from this campaign","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)$"},"leadId":{"description":"Only drafts to this lead","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)$"},"connectedAccountId":{"description":"Only drafts sent from this account","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)$"}}}},{"name":"needleCreateDraft","title":"Create a draft","description":"Draft a message, InMail or connection request (text is its note) to a lead from a connected account. Nothing sends until the user approves it in the Needle inbox, where they can also edit or discard it, so use this instead of sending when the user wants to review first. A conversation (account and lead) has one draft waiting at a time: a new one replaces a waiting one created with this tool, but fails while a draft from a campaign step waits. Write the final words: {{variables}} are not filled in.","category":"Drafts","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"The account that sends it. Its channel must match `action`."},"leadId":{"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)$","description":"The lead it goes to."},"action":{"type":"string","enum":["linkedin_message","linkedin_inmail","linkedin_invitation","instagram_message"],"description":"`linkedin_invitation` sends a connection request with `text` as its note."},"text":{"type":"string","minLength":1,"maxLength":8000,"description":"Sent exactly as written, so {{variables}} are not allowed. Up to 300 characters for a connection note and 1900 for an InMail."},"subject":{"description":"Required for `linkedin_inmail`, not allowed otherwise.","type":"string","minLength":1,"maxLength":200}},"required":["connectedAccountId","leadId","action","text"]}},{"name":"needleGetDraft","title":"Get a draft","description":"Get one draft and where it is in review: awaiting_review, sent, failed or discarded.","category":"Drafts","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"draftId":{"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)$","description":"Draft id"}},"required":["draftId"]}},{"name":"needleWithdrawDraft","title":"Withdraw a draft","description":"Take back a draft before anyone reviewed it, so it never sends. Only for drafts created with needleCreateDraft; a draft a campaign step holds goes away when the lead is removed from the campaign.","category":"Drafts","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"draftId":{"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)$","description":"Draft id"}},"required":["draftId"]}},{"name":"needleSearchEvents","title":"Search events","description":"Search a page of events. Filter by campaign, lead, enrollment, account, type, channel, or date. Use nextCursor as cursor for the next page.","category":"Events","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"types":{"type":"array","items":{"anyOf":[{"type":"string","const":"lead_created","description":"A lead was created, from the app, the API, MCP, an import, or a direct message to someone who was not a lead yet."},{"type":"string","const":"lead_updated","description":"A lead's details or handles changed; `data.changes` lists each changed field."},{"type":"string","const":"lead_deleted","description":"A lead was deleted. Its live campaigns stop with `exitReason` `lead_deleted`."},{"type":"string","const":"lead_enrolled","description":"A lead was added to a campaign."},{"type":"string","const":"lead_skipped","description":"A lead was not added to a campaign; `data.skipReason` says why."},{"type":"string","const":"message_generated","description":"AI wrote a message for a step."},{"type":"string","const":"condition_evaluated","description":"A check in the sequence was evaluated."},{"type":"string","const":"task_held","description":"A step is waiting for approval. Deprecated: use `draft_created`, which is sent alongside it."},{"type":"string","const":"task_approved","description":"A held step was approved. Deprecated: use `draft_approved`, which is sent alongside it."},{"type":"string","const":"draft_created","description":"A drafted message is waiting for a member to review it, created through the API or held by a campaign step."},{"type":"string","const":"draft_approved","description":"A member approved a draft, possibly after editing it (`data.edited`). The message itself is the `linkedin_message_sent` (also for an InMail), `linkedin_invite_sent` or `instagram_message_sent` event that follows, with the same `data.draftId`. An approved InMail to someone out of network without Open Profile goes out as a connection request without a note instead."},{"type":"string","const":"draft_discarded","description":"A draft will not be sent; `data.discardReason` says why."},{"type":"string","const":"draft_failed","description":"An approved draft could not be sent; `data.message` says why."},{"type":"string","const":"task_skipped","description":"A step was skipped; `data.skipReason` says why."},{"type":"string","const":"task_cancelled","description":"A step was cancelled before it ran."},{"type":"string","const":"task_failed","description":"A step failed; `data.errorKind` says why."},{"type":"string","const":"enrollment_waiting","description":"The sequence is waiting, for example for a reply."},{"type":"string","const":"enrollment_completed","description":"The lead reached the end of the sequence."},{"type":"string","const":"enrollment_stopped","description":"The sequence stopped early; `data.exitReason` says why."},{"type":"string","const":"lead_suppressed","description":"A lead matched a [suppression](https://needle.app/docs/suppressions)."},{"type":"string","const":"campaign_status_changed","description":"A campaign's status changed, for example it was started or paused."},{"type":"string","const":"campaign_updated","description":"A campaign's name, sequence, schedule, limits or suppression policy was edited; `data.changedFields` lists which."},{"type":"string","const":"account_connected","description":"A LinkedIn or Instagram account was connected to the workspace for the first time, or again after it was deleted."},{"type":"string","const":"account_reconnected","description":"A disconnected account works again, because a member signed in to it again or LinkedIn or Instagram reports it healthy."},{"type":"string","const":"account_deleted","description":"A connected account was deleted."},{"type":"string","const":"account_paused","description":"A connected account was paused, by its owner or after hitting a limit (`data.errorKind`)."},{"type":"string","const":"account_resumed","description":"A paused connected account was resumed, by its owner or when billing was restored."},{"type":"string","const":"account_disconnected","description":"A connected account stopped working: it needs signing in again (`data.errorKind` is `auth_required`) or LinkedIn or Instagram disconnected it (`disconnected`). Its campaigns wait until it is reconnected."},{"type":"string","const":"account_suspended","description":"A connected account was signed out and stopped, because the workspace's billing lapsed or its owner was removed from the workspace (`data.message`). It has to be connected again to be used."},{"type":"string","const":"account_limits_updated","description":"A connected account's usage limits were changed; `data.changes` lists each limit."},{"type":"string","const":"account_access_granted","description":"A member (`data.member`) was allowed to use a connected account."},{"type":"string","const":"account_access_revoked","description":"A member (`data.member`) can no longer use a connected account. Campaigns they started with it pause."},{"type":"string","const":"account_sharing_changed","description":"A connected account was shared with the whole workspace, or stopped being shared."},{"type":"string","const":"member_invited","description":"Someone was invited to the workspace."},{"type":"string","const":"member_invitation_revoked","description":"An invitation to the workspace was withdrawn."},{"type":"string","const":"member_joined","description":"Someone accepted an invitation and joined."},{"type":"string","const":"member_role_changed","description":"A member's role changed."},{"type":"string","const":"member_removed","description":"An admin removed a member. Their accounts are suspended and their campaigns pause."},{"type":"string","const":"member_left","description":"A member deleted their Needle account."},{"type":"string","const":"api_key_created","description":"An API key was created."},{"type":"string","const":"api_key_revoked","description":"An API key was disabled."},{"type":"string","const":"api_key_enabled","description":"A disabled API key was enabled again."},{"type":"string","const":"api_key_deleted","description":"An API key was deleted."},{"type":"string","const":"webhook_created","description":"A webhook was added."},{"type":"string","const":"webhook_updated","description":"A webhook's URL or headers changed; `data.changedFields` lists which."},{"type":"string","const":"webhook_deleted","description":"A webhook was removed."},{"type":"string","const":"suppression_added","description":"A lead or company was added to the [do-not-contact list](https://needle.app/docs/suppressions) by a member or through the API."},{"type":"string","const":"suppression_removed","description":"An entry was removed from the [do-not-contact list](https://needle.app/docs/suppressions)."},{"type":"string","const":"linkedin_profile_visited","description":"A LinkedIn profile was visited."},{"type":"string","const":"linkedin_invite_sent","description":"A LinkedIn connection request was sent."},{"type":"string","const":"linkedin_invite_withdrawn","description":"A LinkedIn connection request was withdrawn."},{"type":"string","const":"linkedin_message_sent","description":"A LinkedIn message was sent, through Needle or by the account owner in LinkedIn (`data.sentOutsideNeedle`)."},{"type":"string","const":"linkedin_follow_sent","description":"A LinkedIn profile was followed."},{"type":"string","const":"linkedin_unfollowed","description":"A LinkedIn profile was unfollowed."},{"type":"string","const":"linkedin_invite_accepted","description":"A LinkedIn connection request was accepted."},{"type":"string","const":"linkedin_message_received","description":"A LinkedIn reply was received."},{"type":"string","const":"linkedin_post_commented","description":"A comment was posted on LinkedIn."},{"type":"string","const":"linkedin_post_reacted","description":"A reaction was added to a LinkedIn post."},{"type":"string","const":"instagram_message_sent","description":"An Instagram message was sent, through Needle or by the account owner in Instagram (`data.sentOutsideNeedle`)."},{"type":"string","const":"instagram_profile_visited","description":"An Instagram profile was visited."},{"type":"string","const":"instagram_follow_sent","description":"An Instagram profile was followed."},{"type":"string","const":"instagram_unfollowed","description":"An Instagram profile was unfollowed."},{"type":"string","const":"instagram_message_received","description":"An Instagram reply was received."},{"type":"string","const":"instagram_post_commented","description":"A comment was posted on Instagram."},{"type":"string","const":"instagram_post_reacted","description":"An Instagram post was liked."},{"type":"string","const":"instagram_message_reacted","description":"A reaction was added to an Instagram message."},{"type":"string","const":"instagram_post_created","description":"An Instagram post was published."},{"type":"string","description":"A type Needle no longer records, which older events can still have."}]}},"channel":{"type":"string","enum":["linkedin","instagram"]},"campaignId":{"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)$"},"leadId":{"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)$"},"enrollmentId":{"description":"Only events recorded for this campaign enrollment.","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)$"},"accountId":{"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)$"},"actorUserId":{"description":"Only events caused by this member: what they sent, approved or stopped, and what campaigns they started sent.","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)$"},"from":{"type":"string","format":"date","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])))$"},"to":{"type":"string","format":"date","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])))$"},"cursor":{"type":"string","minLength":1},"limit":{"type":"integer","minimum":1,"maximum":100}}}},{"name":"needleListConnectedAccounts","title":"List connected accounts","description":"List a page of connected LinkedIn and Instagram accounts. Use nextCursor as cursor for the next page.","category":"Connected accounts","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"cursor":{"type":"string","minLength":1},"limit":{"type":"integer","minimum":1,"maximum":100}}}},{"name":"needleSearchConnectedAccounts","title":"Search connected accounts","description":"Find connected accounts by display name, handle, or username. Every word in query must match; names or handles starting with it come first. Pass nextCursor as cursor, with the same query, for more. Use the returned id with needleGetConnectedAccount.","category":"Connected accounts","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"query":{"type":"string","minLength":1,"maxLength":200,"description":"Text to match. Every word must appear in the record."},"cursor":{"type":"string","minLength":1},"limit":{"type":"integer","minimum":1,"maximum":100}},"required":["query"]}},{"name":"needleGetConnectedAccount","title":"Get a connected account","description":"Get a connected account and its usage.","category":"Connected accounts","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account id"}},"required":["connectedAccountId"]}},{"name":"needleUpdateConnectedAccount","title":"Update a connected account","description":"Update a connected account.","category":"Connected accounts","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account id"},"paused":{"type":"boolean"},"limitOverrides":{"anyOf":[{"type":"object","propertyNames":{"type":"string","enum":["linkedin_invitation","linkedin_cancel_invitation","linkedin_message","linkedin_inmail","linkedin_profile_view","linkedin_search","linkedin_comment","linkedin_reaction","linkedin_post_view","linkedin_company_view","linkedin_job_view","linkedin_conversation_view","linkedin_network_view","linkedin_invitation_list","linkedin_invitation_response","linkedin_search_parameter","linkedin_inmail_balance","linkedin_own_profile","instagram_message","instagram_profile_view","instagram_follow","instagram_unfollow","instagram_comment","instagram_reaction","instagram_post","instagram_post_view","instagram_conversation_view","instagram_network_view","instagram_own_profile"]},"additionalProperties":{"anyOf":[{"type":"object","properties":{"hour":{"type":"integer","minimum":1,"maximum":1000,"description":"Hourly cap."},"day":{"type":"integer","minimum":1,"maximum":10000,"description":"Daily cap."},"week":{"type":"integer","minimum":1,"maximum":50000,"description":"Weekly cap."}},"description":"Caps to override for one action. Fields you leave out keep the channel default. Caps cannot be removed, only changed."},{"type":"null"}]}},{"type":"null"}],"description":"Per-action caps for this account. Keys merge with existing overrides: set a key to null to restore the channel default for that action, or set the whole field to null to clear every override."}},"required":["connectedAccountId"]}},{"name":"needleDeleteConnectedAccount","title":"Delete a connected account","description":"Delete a connected account. Its owner or a workspace admin can delete it.","category":"Connected accounts","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account id"}},"required":["connectedAccountId"]}},{"name":"needleListConnectedAccountLimits","title":"List connected account limits","description":"Every metered action on a connected account with its channel defaults, the caps currently enforced, the override behind them (if any), and usage so far. Use this to explain a 429 or before changing a cap.","category":"Connected accounts","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account id"}},"required":["connectedAccountId"]}},{"name":"needleUpdateConnectedAccountLimit","title":"Override a connected account limit","description":"Set hourly, daily, or weekly caps for one action on a connected account. Fields left out keep the channel default. Caps can be tightened or loosened but not removed. Going above the default is applied but returns a warning, since it raises the risk of the channel restricting the account; relay it to the user.","category":"Connected accounts","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account id"},"action":{"type":"string","enum":["linkedin_invitation","linkedin_cancel_invitation","linkedin_message","linkedin_inmail","linkedin_profile_view","linkedin_search","linkedin_comment","linkedin_reaction","linkedin_post_view","linkedin_company_view","linkedin_job_view","linkedin_conversation_view","linkedin_network_view","linkedin_invitation_list","linkedin_invitation_response","linkedin_search_parameter","linkedin_inmail_balance","linkedin_own_profile","instagram_message","instagram_profile_view","instagram_follow","instagram_unfollow","instagram_comment","instagram_reaction","instagram_post","instagram_post_view","instagram_conversation_view","instagram_network_view","instagram_own_profile"],"description":"Metered action, e.g. linkedin_profile_view."},"hour":{"type":"integer","minimum":1,"maximum":1000,"description":"Hourly cap."},"day":{"type":"integer","minimum":1,"maximum":10000,"description":"Daily cap."},"week":{"type":"integer","minimum":1,"maximum":50000,"description":"Weekly cap."}},"required":["connectedAccountId","action"]}},{"name":"needleResetConnectedAccountLimit","title":"Reset a connected account limit","description":"Remove the override for one action so the connected account runs on the channel defaults again.","category":"Connected accounts","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account id"},"action":{"type":"string","enum":["linkedin_invitation","linkedin_cancel_invitation","linkedin_message","linkedin_inmail","linkedin_profile_view","linkedin_search","linkedin_comment","linkedin_reaction","linkedin_post_view","linkedin_company_view","linkedin_job_view","linkedin_conversation_view","linkedin_network_view","linkedin_invitation_list","linkedin_invitation_response","linkedin_search_parameter","linkedin_inmail_balance","linkedin_own_profile","instagram_message","instagram_profile_view","instagram_follow","instagram_unfollow","instagram_comment","instagram_reaction","instagram_post","instagram_post_view","instagram_conversation_view","instagram_network_view","instagram_own_profile"],"description":"Metered action, e.g. linkedin_profile_view."}},"required":["connectedAccountId","action"]}},{"name":"needleListConnectedAccountEvents","title":"List connected account events","description":"List a page of events for a connected account. Use nextCursor as cursor for the next page.","category":"Connected accounts","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account id"},"cursor":{"type":"string","minLength":1},"limit":{"type":"integer","minimum":1,"maximum":100}},"required":["connectedAccountId"]}},{"name":"needleListConnectedAccountTasks","title":"List connected account tasks","description":"List a page of the queue for one connected account, earliest scheduled first. Limits and pacing are per account, so this is the order and rate its work will go out at. Use nextCursor as cursor for the next page.","category":"Connected accounts","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account id"},"cursor":{"type":"string","minLength":1},"limit":{"type":"integer","minimum":1,"maximum":100},"status":{"type":"string","enum":["pending","pending_approval"]}},"required":["connectedAccountId"]}},{"name":"needleGetLinkedinProfile","title":"Get a LinkedIn profile","description":"Get a LinkedIn profile by user id or public identifier.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"identity":{"type":"string","minLength":1,"description":"User id (ACoAAA…) or public identifier."},"connectedAccountId":{"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)$","description":"Connected account to act as"}},"required":["identity","connectedAccountId"]}},{"name":"needleSearchLinkedinPeople","title":"Search LinkedIn people","description":"Deprecated. Use needleSearchLinkedinPeopleClassic for standard LinkedIn or needleSearchLinkedinPeopleSalesNavigator for Sales Navigator.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"type":"string"},"keywords":{"type":"string"},"api":{"type":"string"},"searchUrl":{"type":"string"},"cursor":{"type":"string"},"limit":{"type":"number"}}}},{"name":"needleSearchLinkedinPeopleClassic","title":"Search LinkedIn people (Classic)","description":"Search standard LinkedIn people with keywords or filters. Resolve location, industry, company, school, service-category, connections-of, and followers-of ids with needleListLinkedinSearchParameters using service classic. Job titles are keyword-matched here via advancedKeywords.title, not ids.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account to act as"},"keywords":{"type":"string","minLength":1,"maxLength":512},"locations":{"description":"Location ids from the search parameters endpoint with type=LOCATION.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^\\d+$"}},"industries":{"description":"Industry ids from the search parameters endpoint with type=INDUSTRY.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^\\d+$"}},"companies":{"description":"Current-company ids from the search parameters endpoint with type=COMPANY.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^\\d+$"}},"pastCompanies":{"description":"Past-company ids from the search parameters endpoint with type=COMPANY.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^\\d+$"}},"schools":{"description":"School ids from the search parameters endpoint with type=SCHOOL.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^\\d+$"}},"serviceCategories":{"description":"Service-category ids from the search parameters endpoint with type=SERVICE.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^\\d+$"}},"connectionsOf":{"description":"Member ids from the search parameters endpoint with type=CONNECTIONS. Returns people connected to them.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":256}},"followersOf":{"description":"Member ids from the search parameters endpoint with type=PEOPLE. Returns people who follow them.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":256}},"profileLanguages":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^[a-z]{2}$"},"description":"ISO 639-1 profile-language codes from the search parameters endpoint with type=LANGUAGE."},"networkDistances":{"minItems":1,"maxItems":3,"type":"array","items":{"anyOf":[{"type":"number","const":1},{"type":"number","const":2},{"type":"number","const":3}]},"description":"LinkedIn connection degrees: first, second, or third-plus."},"openTo":{"description":"LinkedIn only filters on these two, not on open to work or hiring.","minItems":1,"maxItems":2,"type":"array","items":{"type":"string","enum":["pro_bono","board_member"]}},"advancedKeywords":{"type":"object","properties":{"firstName":{"type":"string","minLength":1,"maxLength":512},"lastName":{"type":"string","minLength":1,"maxLength":512},"title":{"type":"string","minLength":1,"maxLength":512},"company":{"type":"string","minLength":1,"maxLength":512},"school":{"type":"string","minLength":1,"maxLength":512}},"additionalProperties":false,"description":"LinkedIn's Keywords panel: each field matches text against that profile field only."},"searchUrl":{"type":"string","maxLength":4096,"format":"uri","description":"Use a people search URL copied from standard LinkedIn, such as https://www.linkedin.com/search/results/people/?keywords=engineer. The filters it carries replace the filter fields, which must then be left out. Sales Navigator URLs go to POST /api/v1/linkedin/sales-navigator/people/search."},"cursor":{"type":"string","minLength":1,"maxLength":8192},"limit":{"description":"Requested page size, capped at 10 by LinkedIn Classic.","type":"integer","minimum":1,"maximum":100}},"required":["connectedAccountId"],"additionalProperties":false}},{"name":"needleSearchLinkedinPeopleSalesNavigator","title":"Search LinkedIn people (Sales Navigator)","description":"Search Sales Navigator leads with keywords or filters, including current and past company, company headcount and type, function, seniority, years of experience, groups, saved lists and personas, and Spotlights such as changed_jobs. Most filters also take an excluded form. Resolve filter ids with needleListLinkedinSearchParameters using service sales_navigator. Requires a Sales Navigator seat.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account to act as"},"keywords":{"type":"string","minLength":1,"maxLength":512},"firstName":{"description":"Matches the first name on the profile.","type":"string","minLength":1,"maxLength":512},"lastName":{"description":"Matches the last name on the profile.","type":"string","minLength":1,"maxLength":512},"locations":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^\\d+$"},"description":"Geography ids from the search parameters endpoint with type=REGION and service=sales_navigator."},"excludedLocations":{"description":"Geographies to leave out of the results.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^\\d+$"}},"industries":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^\\d+$"},"description":"Industry ids from the search parameters endpoint with type=SALES_INDUSTRY and service=sales_navigator."},"excludedIndustries":{"description":"Industries to leave out of the results.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^\\d+$"}},"companies":{"description":"Current-company ids from the search parameters endpoint with type=COMPANY and service=sales_navigator.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^\\d+$"}},"excludedCompanies":{"description":"Current companies to leave out of the results.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^\\d+$"}},"pastCompanies":{"description":"Past-company ids from the search parameters endpoint with type=COMPANY and service=sales_navigator.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^\\d+$"}},"excludedPastCompanies":{"description":"Past companies to leave out of the results.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^\\d+$"}},"companyLocations":{"description":"Where the company sits, rather than where the person does. Geography ids with type=REGION and service=sales_navigator.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^\\d+$"}},"excludedCompanyLocations":{"description":"Company geographies to leave out of the results.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^\\d+$"}},"companyHeadcounts":{"description":"Employee-count bands of the current company.","minItems":1,"maxItems":8,"type":"array","items":{"type":"string","enum":["1_to_10","11_to_50","51_to_200","201_to_500","501_to_1000","1001_to_5000","5001_to_10000","10001_plus"]}},"companyTypes":{"description":"How the current company is held.","minItems":1,"maxItems":8,"type":"array","items":{"type":"string","enum":["public_company","privately_held","non_profit","educational_institution","partnership","self_employed","self_owned","government_agency"]}},"schools":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^\\d+$"},"description":"School ids from the search parameters endpoint with type=SCHOOL and service=sales_navigator."},"excludedSchools":{"description":"Schools to leave out of the results.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^\\d+$"}},"functions":{"description":"The department someone works in. Function ids from the search parameters endpoint with type=DEPARTMENT and service=sales_navigator.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^\\d+$"}},"excludedFunctions":{"description":"Functions to leave out of the results.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^\\d+$"}},"jobTitles":{"description":"Current job-title ids from the search parameters endpoint with type=JOB_TITLE and service=sales_navigator.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^\\d+$"}},"excludedJobTitles":{"description":"Current job titles to leave out of the results.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^\\d+$"}},"pastJobTitles":{"description":"Job titles someone used to hold. Ids with type=JOB_TITLE and service=sales_navigator.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^\\d+$"}},"excludedPastJobTitles":{"description":"Past job titles to leave out of the results.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^\\d+$"}},"seniorities":{"description":"Seniority levels to search, from owner_partner down to in_training.","minItems":1,"maxItems":10,"type":"array","items":{"type":"string","enum":["owner_partner","cxo","vice_president","director","experienced_manager","entry_level_manager","strategic","senior","entry_level","in_training"]}},"excludedSeniorities":{"description":"Seniority levels to leave out of the results.","minItems":1,"maxItems":10,"type":"array","items":{"type":"string","enum":["owner_partner","cxo","vice_president","director","experienced_manager","entry_level_manager","strategic","senior","entry_level","in_training"]}},"yearsOfExperience":{"description":"Years of experience across someone's whole career.","minItems":1,"maxItems":5,"type":"array","items":{"type":"string","enum":["less_than_1","1_to_2","3_to_5","6_to_10","more_than_10"]}},"yearsAtCompany":{"description":"Years spent at the current company.","minItems":1,"maxItems":5,"type":"array","items":{"type":"string","enum":["less_than_1","1_to_2","3_to_5","6_to_10","more_than_10"]}},"yearsInPosition":{"description":"Years spent in the current position.","minItems":1,"maxItems":5,"type":"array","items":{"type":"string","enum":["less_than_1","1_to_2","3_to_5","6_to_10","more_than_10"]}},"groups":{"description":"LinkedIn groups the person belongs to. Group ids with type=GROUPS and service=sales_navigator.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":256}},"personas":{"description":"Personas saved on the Sales Navigator seat. Ids with type=PERSONA and service=sales_navigator.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":256}},"accountLists":{"description":"Only people at companies on these saved account lists. Ids with type=ACCOUNT_LISTS and service=sales_navigator.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":256}},"excludedAccountLists":{"description":"Saved account lists to leave out of the results.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":256}},"leadLists":{"description":"Only people on these saved lead lists. Ids with type=LEAD_LISTS and service=sales_navigator.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":256}},"excludedLeadLists":{"description":"Saved lead lists to leave out of the results.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":256}},"connectionsOf":{"description":"Member ids from the search parameters endpoint with type=CONNECTIONS. Returns people connected to them.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":256}},"profileLanguages":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^[a-z]{2}$"},"description":"ISO 639-1 profile-language codes from the search parameters endpoint with type=LANGUAGE."},"networkDistances":{"minItems":1,"maxItems":3,"type":"array","items":{"anyOf":[{"type":"number","const":1},{"type":"number","const":2},{"type":"number","const":3}]},"description":"LinkedIn connection degrees: first, second, or third-plus."},"spotlights":{"description":"Sales Navigator's Spotlights: recent signals about the person rather than facts about their profile.","minItems":1,"maxItems":7,"type":"array","items":{"type":"string","enum":["changed_jobs","posted_on_linkedin","mentioned_in_news","following_your_company","viewed_your_profile_recently","past_colleague","shared_experiences"]}},"interactedWith":{"description":"Only people this seat has messaged, or whose profile it opened.","minItems":1,"maxItems":2,"type":"array","items":{"type":"string","enum":["messaged","viewed_profile"]}},"includeSaved":{"description":"Also return people already saved as leads, or at saved accounts.","minItems":1,"maxItems":2,"type":"array","items":{"type":"string","enum":["leads","accounts"]}},"searchUrl":{"type":"string","maxLength":4096,"format":"uri","description":"Use a lead search URL copied from Sales Navigator, such as https://www.linkedin.com/sales/search/people?query=.... The filters it carries replace the filter fields, which must then be left out. Standard LinkedIn URLs go to POST /api/v1/linkedin/people/search."},"cursor":{"type":"string","minLength":1,"maxLength":8192},"limit":{"type":"integer","minimum":1,"maximum":100}},"required":["connectedAccountId"],"additionalProperties":false}},{"name":"needleSendLinkedinMessage","title":"Send a LinkedIn message","description":"Send a LinkedIn message as a connected account. Attach files by passing a url from needleListFiles or from creating a file first.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account to act as"},"identity":{"type":"string","minLength":1,"description":"User id (ACoAAA…) or public identifier."},"text":{"type":"string","minLength":1,"maxLength":8000},"attachments":{"description":"Files from POST /api/v1/files. Pass the returned url, not a signed URL. Needle reads the private object and sends the bytes to LinkedIn.","maxItems":5,"type":"array","items":{"type":"object","properties":{"url":{"type":"string","maxLength":4096,"format":"uri","description":"Object URL returned by POST /api/v1/files. Not a signed URL and not passed to LinkedIn."},"filename":{"type":"string","minLength":1,"maxLength":255},"contentType":{"type":"string","minLength":1,"maxLength":127},"size":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["url"]}}},"required":["connectedAccountId","identity","text"]}},{"name":"needleSendLinkedinInMail","title":"Send a Sales Navigator InMail","description":"Send a LinkedIn InMail. Needs a Sales Navigator seat. Reaches people in your network and out-of-network Open Profiles. Usually costs one credit. Attach files by passing a url from needleListFiles or from creating a file first.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account to act as"},"identity":{"type":"string","minLength":1,"description":"User id (ACoAAA…) or public identifier."},"subject":{"type":"string","minLength":1,"maxLength":200,"description":"InMail subject line shown to the recipient."},"text":{"type":"string","minLength":1,"maxLength":1900},"attachments":{"description":"Files from POST /api/v1/files. Pass the returned url, not a signed URL. Needle reads the private object and sends the bytes to LinkedIn.","maxItems":5,"type":"array","items":{"type":"object","properties":{"url":{"type":"string","maxLength":4096,"format":"uri","description":"Object URL returned by POST /api/v1/files. Not a signed URL and not passed to LinkedIn."},"filename":{"type":"string","minLength":1,"maxLength":255},"contentType":{"type":"string","minLength":1,"maxLength":127},"size":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},"required":["url"]}}},"required":["connectedAccountId","identity","subject","text"]}},{"name":"needleGetLinkedinInMailBalance","title":"Get remaining InMail credits","description":"Read the InMail credits left on a connected account.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account to act as"}},"required":["connectedAccountId"]}},{"name":"needleListLinkedinConversations","title":"List conversations","description":"List LinkedIn conversations. Use a conversationId from here to read its messages.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account to act as"},"cursor":{"type":"string","minLength":1,"maxLength":8192},"limit":{"type":"integer","minimum":1,"maximum":100}},"required":["connectedAccountId"]}},{"name":"needleListLinkedinConversationMessages","title":"List messages in a conversation","description":"List messages in a LinkedIn conversation.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"conversationId":{"type":"string","minLength":1,"description":"conversationId from the conversations listing"},"connectedAccountId":{"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)$","description":"Connected account to act as"},"limit":{"description":"Page size. Defaults to 20.","type":"integer","minimum":1,"maximum":100}},"required":["conversationId","connectedAccountId"]}},{"name":"needleListLinkedinInvitations","title":"List pending invitations","description":"List a page of pending LinkedIn connection invitations from this account. Use nextCursor as cursor for the next page.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"cursor":{"type":"string","minLength":1},"limit":{"type":"integer","minimum":1,"maximum":100},"connectedAccountId":{"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)$","description":"Connected account to act as"}},"required":["connectedAccountId"]}},{"name":"needleSendLinkedinInvitation","title":"Send a connection invitation","description":"Send a LinkedIn connection invitation.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account to act as"},"identity":{"type":"string","minLength":1,"description":"User id (ACoAAA…) or public identifier."},"note":{"type":"string","maxLength":300}},"required":["connectedAccountId","identity"]}},{"name":"needleWithdrawLinkedinInvitation","title":"Withdraw an invitation","description":"Withdraw a pending LinkedIn invitation.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"invitationId":{"type":"string","minLength":1,"description":"invitationId from the sent invitations listing"},"connectedAccountId":{"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)$","description":"Connected account to act as"}},"required":["invitationId","connectedAccountId"]}},{"name":"needleListLinkedinReceivedInvitations","title":"List invitations sent to you","description":"List connection invitations other people sent to this account. Use nextCursor as cursor for the next page.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"cursor":{"type":"string","minLength":1},"limit":{"type":"integer","minimum":1,"maximum":100},"connectedAccountId":{"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)$","description":"Connected account to act as"}},"required":["connectedAccountId"]}},{"name":"needleRespondToLinkedinInvitation","title":"Accept or decline a received invitation","description":"Accept or decline an invitation from the received invitations listing.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"invitationId":{"type":"string","minLength":1,"description":"invitationId from the received invitations listing"},"connectedAccountId":{"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)$","description":"Connected account to act as"},"action":{"type":"string","enum":["accept","decline"]}},"required":["invitationId","connectedAccountId","action"]}},{"name":"needleListLinkedinFollowers","title":"List followers","description":"List followers of the connected account, or of a person or company when identity is given.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account to act as"},"identity":{"description":"Whose followers to read: a person (user id or public identifier) or a company (public identifier, numeric id, or company URL). Omit for the connected account; a company page is readable only by its admins.","type":"string","minLength":1},"cursor":{"type":"string","minLength":1,"maxLength":8192},"limit":{"type":"integer","minimum":1,"maximum":100}},"required":["connectedAccountId"]}},{"name":"needleListLinkedinFollowing","title":"List accounts this account follows","description":"List the people and companies this account follows.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account to act as"},"cursor":{"type":"string","minLength":1,"maxLength":8192},"limit":{"type":"integer","minimum":1,"maximum":100}},"required":["connectedAccountId"]}},{"name":"needleListLinkedinRelations","title":"List first-degree connections","description":"List first-degree LinkedIn connections. Use the returned cursor for the next page.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account to act as"},"cursor":{"type":"string","minLength":1,"maxLength":8192}},"required":["connectedAccountId"]}},{"name":"needleGetLinkedinCompany","title":"Get a LinkedIn company","description":"Get a LinkedIn company by public identifier, numeric id, or company URL such as https://www.linkedin.com/company/heravideo.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"identifier":{"type":"string","minLength":1,"description":"Company public identifier (heravideo), numeric company id, or a LinkedIn company URL such as https://www.linkedin.com/company/heravideo."},"connectedAccountId":{"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)$","description":"Connected account to act as"}},"required":["identifier","connectedAccountId"]}},{"name":"needleListLinkedinCompanyJobs","title":"List jobs posted by a company","description":"List jobs on a LinkedIn company page. Identifier accepts a public identifier, numeric id, or company URL.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"identifier":{"type":"string","minLength":1,"description":"Company public identifier (heravideo), numeric company id, or a LinkedIn company URL such as https://www.linkedin.com/company/heravideo."},"connectedAccountId":{"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)$","description":"Connected account to act as"},"cursor":{"type":"string","minLength":1,"maxLength":8192},"limit":{"type":"integer","minimum":1,"maximum":100}},"required":["identifier","connectedAccountId"]}},{"name":"needleListLinkedinCompanyPosts","title":"List posts from a company page","description":"List posts on a LinkedIn company page. Identifier accepts a public identifier, numeric id, or company URL.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"identifier":{"type":"string","minLength":1,"description":"Company public identifier (heravideo), numeric company id, or a LinkedIn company URL such as https://www.linkedin.com/company/heravideo."},"connectedAccountId":{"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)$","description":"Connected account to act as"},"cursor":{"type":"string","minLength":1,"maxLength":8192},"limit":{"type":"integer","minimum":1,"maximum":100}},"required":["identifier","connectedAccountId"]}},{"name":"needleSearchLinkedinJobs","title":"Search LinkedIn jobs","description":"Search LinkedIn jobs with keywords, a company, or a LinkedIn jobs searchUrl. Do not combine a searchUrl with keywords or company.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account to act as"},"keywords":{"type":"string","minLength":1,"maxLength":512},"companies":{"description":"Companies to search within. Each non-numeric identifier costs one extra lookup call.","minItems":1,"maxItems":10,"type":"array","items":{"type":"string","minLength":1,"description":"Company public identifier (heravideo), numeric company id, or a LinkedIn company URL such as https://www.linkedin.com/company/heravideo."}},"location":{"description":"A single location id from GET /api/v1/linkedin/search/parameters?type=LOCATION. One location per search.","type":"string","pattern":"^\\d+$"},"industries":{"description":"Industry ids from GET /api/v1/linkedin/search/parameters?type=INDUSTRY.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^\\d+$"}},"jobTitles":{"description":"Job title ids from GET /api/v1/linkedin/search/parameters?type=JOB_TITLE.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^\\d+$"}},"jobFunctions":{"description":"Job function ids from GET /api/v1/linkedin/search/parameters?type=JOB_FUNCTION.","minItems":1,"maxItems":20,"type":"array","items":{"type":"string","pattern":"^[a-z]+$"}},"seniority":{"minItems":1,"type":"array","items":{"type":"string","enum":["executive","director","mid_senior","associate","entry","intern"]}},"jobType":{"minItems":1,"type":"array","items":{"type":"string","enum":["full_time","part_time","contract","temporary","volunteer","internship","other"]}},"workplace":{"minItems":1,"type":"array","items":{"type":"string","enum":["on_site","hybrid","remote"]}},"postedWithinDays":{"type":"integer","minimum":1,"maximum":365},"sortBy":{"description":"Defaults to relevance.","type":"string","enum":["relevance","date"]},"searchUrl":{"description":"A LinkedIn jobs search URL, which cannot be combined with the filter fields above. Use it for filters this endpoint does not expose, such as salary.","type":"string","maxLength":4096,"format":"uri"},"cursor":{"type":"string","minLength":1,"maxLength":8192},"limit":{"description":"Page size, capped at 50 for a classic job search. Use cursor for the next page.","type":"integer","minimum":1,"maximum":100}},"required":["connectedAccountId"],"additionalProperties":false}},{"name":"needleGetLinkedinJob","title":"Get a LinkedIn job","description":"Get one LinkedIn job with its full description, applicant count, apply link and hiring team. jobId accepts the id from a job listing or search, or a job URL such as https://www.linkedin.com/jobs/view/4447604185. Salary, seniority, skills and screening questions are not returned for jobs posted by other companies; use service recruiter for jobs posted through LinkedIn Recruiter.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"jobId":{"type":"string","minLength":1,"description":"Numeric job id from a job listing or search, or a job URL such as https://www.linkedin.com/jobs/view/4447604185 (URL-encoded when sent in the path)."},"connectedAccountId":{"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)$","description":"Connected account to act as"},"service":{"description":"recruiter for a job posted through LinkedIn Recruiter, which needs a Recruiter seat on the connected account. Defaults to classic.","type":"string","enum":["classic","recruiter"]}},"required":["jobId","connectedAccountId"]}},{"name":"needleSearchLinkedinCompaniesClassic","title":"Search LinkedIn companies (Classic)","description":"Search LinkedIn companies. Provide either keywords or a LinkedIn company searchUrl, not both.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account to act as"},"keywords":{"type":"string","minLength":1,"maxLength":512},"searchUrl":{"type":"string","maxLength":4096,"format":"uri","description":"A search URL copied from LinkedIn, searching for the same kind of entity this endpoint returns. Filters carried in the URL take precedence."},"cursor":{"type":"string","minLength":1,"maxLength":8192},"limit":{"description":"Page size, capped at 10 for a company keyword search. Use cursor for the next page.","type":"integer","minimum":1,"maximum":100}},"required":["connectedAccountId"],"additionalProperties":false}},{"name":"needleSearchLinkedinPosts","title":"Search LinkedIn posts","description":"Search LinkedIn posts. Provide either keywords or a LinkedIn post searchUrl, not both.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account to act as"},"keywords":{"type":"string","minLength":1,"maxLength":512},"searchUrl":{"type":"string","maxLength":4096,"format":"uri","description":"A search URL copied from LinkedIn, searching for the same kind of entity this endpoint returns. Filters carried in the URL take precedence."},"cursor":{"type":"string","minLength":1,"maxLength":8192},"limit":{"description":"Page size, capped at 49 for a post keyword search. Use cursor for the next page.","type":"integer","minimum":1,"maximum":100}},"required":["connectedAccountId"],"additionalProperties":false}},{"name":"needleListLinkedinPosts","title":"List posts by a person or company","description":"List posts from a person (user id or public identifier) or a company page (numeric id or company URL). remainingUsage is the post-view budget; looking up a handle also spends a profile-view or company-view unit.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account to act as"},"identity":{"type":"string","minLength":1,"description":"Author to read, as a user id or public identifier. For a company page, prefer GET /api/v1/linkedin/companies/{identifier}/posts."},"cursor":{"type":"string","minLength":1,"maxLength":8192},"limit":{"type":"integer","minimum":1,"maximum":100}},"required":["connectedAccountId","identity"]}},{"name":"needleGetLinkedinPost","title":"Get a LinkedIn post","description":"Get one LinkedIn post by the postId returned from a post listing or search.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"postId":{"type":"string","minLength":1,"description":"Post id as returned by a post listing or search. An id copied from a post URL often does not resolve."},"connectedAccountId":{"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)$","description":"Connected account to act as"}},"required":["postId","connectedAccountId"]}},{"name":"needleListLinkedinPostComments","title":"List comments on a post","description":"List comments on a post, or replies to one comment when commentId is given.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"postId":{"type":"string","minLength":1,"description":"Post id as returned by a post listing or search. An id copied from a post URL often does not resolve."},"connectedAccountId":{"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)$","description":"Connected account to act as"},"commentId":{"description":"Read replies to this comment instead of top-level comments.","type":"string","minLength":1},"sortBy":{"type":"string","enum":["MOST_RECENT","MOST_RELEVANT"]},"cursor":{"type":"string","minLength":1,"maxLength":8192},"limit":{"type":"integer","minimum":1,"maximum":100}},"required":["postId","connectedAccountId"]}},{"name":"needleListLinkedinPostReactions","title":"List reactions on a post","description":"List the people who reacted to a LinkedIn post, or to a comment when commentId is given.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"postId":{"type":"string","minLength":1,"description":"Post id as returned by a post listing or search. An id copied from a post URL often does not resolve."},"connectedAccountId":{"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)$","description":"Connected account to act as"},"commentId":{"description":"Read reactions on this comment instead of the ones on the post.","type":"string","minLength":1},"cursor":{"type":"string","minLength":1,"maxLength":8192},"limit":{"type":"integer","minimum":1,"maximum":100}},"required":["postId","connectedAccountId"]}},{"name":"needleCommentOnLinkedinPost","title":"Comment on a post","description":"Comment on a LinkedIn post, or reply to a comment when commentId is given.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"postId":{"type":"string","minLength":1,"description":"Post id as returned by a post listing or search. An id copied from a post URL often does not resolve."},"connectedAccountId":{"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)$","description":"Connected account to act as"},"text":{"type":"string","minLength":1,"maxLength":1250},"commentId":{"description":"Reply to this comment instead of commenting on the post.","type":"string","minLength":1}},"required":["postId","connectedAccountId","text"]}},{"name":"needleReactToLinkedinPost","title":"React to a post","description":"React to a LinkedIn post, or to a comment when commentId is given. Defaults to like.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"postId":{"type":"string","minLength":1,"description":"Post id as returned by a post listing or search. An id copied from a post URL often does not resolve."},"connectedAccountId":{"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)$","description":"Connected account to act as"},"reaction":{"description":"Defaults to like.","type":"string","enum":["like","celebrate","support","love","insightful","funny"]},"commentId":{"description":"React to this comment instead of the post.","type":"string","minLength":1}},"required":["postId","connectedAccountId"]}},{"name":"needleListLinkedinSearchParameters","title":"List LinkedIn search parameters","description":"Resolve LinkedIn filter values from keywords. Each service has its own types: standard LinkedIn resolves LOCATION and INDUSTRY, while Sales Navigator resolves REGION and SALES_INDUSTRY along with DEPARTMENT, GROUPS, PERSONA, ACCOUNT_LISTS and LEAD_LISTS. LANGUAGE lists official ISO 639-1 codes for either and can be filtered by code or name.","category":"LinkedIn","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account to act as"},"type":{"type":"string","enum":["LOCATION","INDUSTRY","COMPANY","SCHOOL","SERVICE","JOB_TITLE","JOB_FUNCTION","CONNECTIONS","PEOPLE","LANGUAGE","REGION","SALES_INDUSTRY","DEPARTMENT","GROUPS","PERSONA","ACCOUNT_LISTS","LEAD_LISTS"],"description":"Kind of filter value to resolve, and it has to be one the chosen service has. Standard LinkedIn takes LOCATION, INDUSTRY, COMPANY, SCHOOL, SERVICE, JOB_TITLE, JOB_FUNCTION, CONNECTIONS, PEOPLE, LANGUAGE. Sales Navigator takes REGION, SALES_INDUSTRY, COMPANY, SCHOOL, JOB_TITLE, DEPARTMENT, GROUPS, PERSONA, ACCOUNT_LISTS, LEAD_LISTS, CONNECTIONS, LANGUAGE. LANGUAGE returns ISO 639-1 codes rather than LinkedIn ids."},"keywords":{"description":"Text to match, such as Berlin for LOCATION or REGION, engineer for JOB_TITLE, or Russian or ru for LANGUAGE. Saved groups, personas and lists are listed whole when this is left out.","type":"string","minLength":1,"maxLength":512},"service":{"description":"Which search to resolve against. Defaults to classic.","type":"string","enum":["classic","sales_navigator"]},"limit":{"type":"integer","minimum":1,"maximum":100}},"required":["connectedAccountId","type"]}},{"name":"needleGetInstagramProfile","title":"Get an Instagram profile","description":"Get an Instagram profile by username without @.","category":"Instagram","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"identity":{"type":"string","minLength":1,"description":"Username without @."},"connectedAccountId":{"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)$","description":"Connected account to act as"}},"required":["identity","connectedAccountId"]}},{"name":"needleGetInstagramAccountProfile","title":"Get the connected account profile","description":"Get the Instagram profile of the connected account, with its follower, following and post counts.","category":"Instagram","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account to act as"}},"required":["connectedAccountId"]}},{"name":"needleSendInstagramMessage","title":"Send an Instagram message","description":"Send an Instagram direct message as a connected account.","category":"Instagram","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account to act as"},"identity":{"type":"string","minLength":1,"description":"Username without @."},"text":{"type":"string","minLength":1,"maxLength":8000},"attachments":{"description":"Files to send alongside the text.","maxItems":10,"type":"array","items":{"type":"object","properties":{"url":{"type":"string","maxLength":4096,"format":"uri","description":"Public https URL to read the file from."},"filename":{"type":"string","minLength":1,"maxLength":255}},"required":["url"],"description":"A JPEG, PNG, WebP, MP4, MOV, M4A or MP3 file. Up to 16 MB, or 100 MB for video."}}},"required":["connectedAccountId","identity","text"]}},{"name":"needleReactToInstagramMessage","title":"React to an Instagram message","description":"Add an emoji reaction to an Instagram direct message.","category":"Instagram","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"messageId":{"type":"string","minLength":1,"description":"messageId from the messages of a conversation."},"connectedAccountId":{"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)$","description":"Connected account to act as"},"reaction":{"type":"string","minLength":1,"maxLength":8,"description":"A single emoji, such as 👍."}},"required":["messageId","connectedAccountId","reaction"]}},{"name":"needleListInstagramConversations","title":"List Instagram conversations","description":"List the Instagram inbox of a connected account, most recent first.","category":"Instagram","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account to act as"},"cursor":{"type":"string","minLength":1,"maxLength":8192},"limit":{"description":"Page size, up to 100. Defaults to 20. A page can hold fewer, so follow cursor until it comes back null.","type":"integer","minimum":1,"maximum":100}},"required":["connectedAccountId"]}},{"name":"needleListInstagramConversationMessages","title":"List messages in a conversation","description":"List messages in an Instagram conversation.","category":"Instagram","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"conversationId":{"type":"string","minLength":1,"description":"conversationId from the conversations listing"},"connectedAccountId":{"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)$","description":"Connected account to act as"},"limit":{"description":"Page size. Defaults to 20.","type":"integer","minimum":1,"maximum":100}},"required":["conversationId","connectedAccountId"]}},{"name":"needleListInstagramConversationParticipants","title":"List the participants of a conversation","description":"List the accounts in an Instagram conversation, with their usernames.","category":"Instagram","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"conversationId":{"type":"string","minLength":1,"description":"conversationId from the conversations listing"},"connectedAccountId":{"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)$","description":"Connected account to act as"}},"required":["conversationId","connectedAccountId"]}},{"name":"needleListInstagramPosts","title":"List the posts of an account","description":"List the posts of an Instagram account, most recent first. A username that does not exist comes back with no posts.","category":"Instagram","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account to act as"},"identity":{"type":"string","minLength":1,"description":"Whose posts to read, as a username without @."},"cursor":{"type":"string","minLength":1,"maxLength":8192},"limit":{"description":"Page size, up to 100. Defaults to 20. A page can hold fewer, so follow cursor until it comes back null.","type":"integer","minimum":1,"maximum":100}},"required":["connectedAccountId","identity"]}},{"name":"needleGetInstagramPost","title":"Get an Instagram post","description":"Get one Instagram post by post id, or by the short code from its URL.","category":"Instagram","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"postId":{"type":"string","minLength":1,"description":"postId from a posts listing, or the short code from the post URL."},"connectedAccountId":{"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)$","description":"Connected account to act as"}},"required":["postId","connectedAccountId"]}},{"name":"needleCreateInstagramPost","title":"Publish an Instagram post","description":"Publish an Instagram feed post or story. At least one image or video URL is required.","category":"Instagram","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account to act as"},"text":{"type":"string","maxLength":2200,"description":"Caption for the post. Write @username to mention someone."},"media":{"minItems":1,"maxItems":10,"type":"array","items":{"type":"object","properties":{"url":{"type":"string","maxLength":4096,"format":"uri","description":"Public https URL to read the file from."},"filename":{"type":"string","minLength":1,"maxLength":255}},"required":["url"],"description":"A JPEG, PNG, WebP, MP4, MOV, M4A or MP3 file. Up to 16 MB, or 100 MB for video."},"description":"Images or videos to publish."},"postType":{"description":"Defaults to feed. A story is visible for 24 hours.","type":"string","enum":["feed","story"]},"location":{"description":"Name of a place to tag.","type":"string","minLength":1,"maxLength":200}},"required":["connectedAccountId","text","media"]}},{"name":"needleListInstagramPostComments","title":"List the comments on a post","description":"List the comments on an Instagram post, or the replies to one comment.","category":"Instagram","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"postId":{"type":"string","minLength":1,"description":"postId from a posts listing, or the short code from the post URL."},"connectedAccountId":{"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)$","description":"Connected account to act as"},"commentId":{"description":"Read the replies to this comment instead of the top-level comments.","type":"string","minLength":1},"cursor":{"type":"string","minLength":1,"maxLength":8192},"limit":{"description":"Page size, up to 100. Defaults to 20. A page can hold fewer, so follow cursor until it comes back null.","type":"integer","minimum":1,"maximum":100}},"required":["postId","connectedAccountId"]}},{"name":"needleCommentOnInstagramPost","title":"Comment on a post","description":"Comment on an Instagram post, or reply to a comment on it. Write @username to mention someone.","category":"Instagram","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"postId":{"type":"string","minLength":1,"description":"postId from a posts listing, or the short code from the post URL."},"connectedAccountId":{"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)$","description":"Connected account to act as"},"text":{"type":"string","minLength":1,"maxLength":2200,"description":"The comment. Write @username to mention someone."},"commentId":{"description":"Reply to this comment instead of commenting on the post.","type":"string","minLength":1}},"required":["postId","connectedAccountId","text"]}},{"name":"needleListInstagramPostReactions","title":"List the likes on a post","description":"List the accounts that liked an Instagram post, or one of its comments.","category":"Instagram","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"postId":{"type":"string","minLength":1,"description":"postId from a posts listing, or the short code from the post URL."},"connectedAccountId":{"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)$","description":"Connected account to act as"},"commentId":{"description":"Read the likes on this comment instead of the ones on the post.","type":"string","minLength":1},"cursor":{"type":"string","minLength":1,"maxLength":8192},"limit":{"description":"Page size, up to 100. Defaults to 20. A page can hold fewer, so follow cursor until it comes back null.","type":"integer","minimum":1,"maximum":100}},"required":["postId","connectedAccountId"]}},{"name":"needleLikeInstagramPost","title":"Like a post","description":"Like an Instagram post, or one of its comments. A like is the only reaction a post takes.","category":"Instagram","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"postId":{"type":"string","minLength":1,"description":"postId from a posts listing, or the short code from the post URL."},"connectedAccountId":{"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)$","description":"Connected account to act as"},"commentId":{"description":"Like this comment instead of the post.","type":"string","minLength":1}},"required":["postId","connectedAccountId"]}},{"name":"needleListInstagramFollowers","title":"List followers","description":"List the followers of an Instagram account. Omit identity for the connected account.","category":"Instagram","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account to act as"},"identity":{"description":"Whose followers to read. Omit for the connected account.","type":"string","minLength":1},"cursor":{"type":"string","minLength":1,"maxLength":8192},"limit":{"description":"Page size, up to 25. A page can hold fewer, so follow cursor until it comes back null.","type":"integer","minimum":1,"maximum":25}},"required":["connectedAccountId"]}},{"name":"needleListInstagramFollowing","title":"List followed accounts","description":"List the accounts an Instagram account follows. Omit identity for the connected account.","category":"Instagram","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account to act as"},"identity":{"description":"Whose followed accounts to read. Omit for the connected account.","type":"string","minLength":1},"cursor":{"type":"string","minLength":1,"maxLength":8192},"limit":{"description":"Page size, up to 25. A page can hold fewer, so follow cursor until it comes back null.","type":"integer","minimum":1,"maximum":25}},"required":["connectedAccountId"]}},{"name":"needleFollowInstagramUser","title":"Follow an Instagram user","description":"Follow an Instagram user as a connected account.","category":"Instagram","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"connectedAccountId":{"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)$","description":"Connected account to act as"},"identity":{"type":"string","minLength":1,"description":"Username without @."}},"required":["connectedAccountId","identity"]}},{"name":"needleUnfollowInstagramUser","title":"Unfollow an Instagram user","description":"Unfollow an Instagram user as a connected account.","category":"Instagram","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"identity":{"type":"string","minLength":1,"description":"Username without @."},"connectedAccountId":{"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)$","description":"Connected account to act as"}},"required":["identity","connectedAccountId"]}},{"name":"needleSearchPlaces","title":"Search places","description":"Build a list of businesses and locations. Pass a query for text search, or a location (and optional type) for nearby search. Page text-search results with the returned cursor. The response includes remainingUsage for this workspace.","category":"Places","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"query":{"description":"Free-text query, e.g. \"dentists in Munich\". Required unless `location` is set.","type":"string","minLength":1,"maxLength":1024},"location":{"description":"Center point. Required unless `query` is set. Without a query this is a nearby search inside the radius.","type":"object","properties":{"latitude":{"type":"number","minimum":-90,"maximum":90},"longitude":{"type":"number","minimum":-180,"maximum":180}},"required":["latitude","longitude"]},"radiusMeters":{"description":"Radius when `location` is set. Defaults to 50 km. Nearby search stays inside this circle; text search is biased toward it.","type":"integer","minimum":1,"maximum":50000},"type":{"description":"A Google Places type such as `restaurant` or `dentist`.","type":"string","minLength":1,"maxLength":64},"language":{"description":"BCP-47 language code for names and addresses.","type":"string","minLength":2,"maxLength":16},"region":{"description":"CLDR region code that biases results, e.g. `DE`.","type":"string","minLength":2,"maxLength":2},"cursor":{"description":"Text-search pagination cursor. Nearby search does not page.","type":"string","minLength":1,"maxLength":8192},"limit":{"type":"integer","minimum":1,"maximum":20}}}},{"name":"needleGetPlace","title":"Get a place","description":"Get place details by Google Place id. The response includes remainingUsage for this workspace.","category":"Places","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"placeId":{"type":"string","minLength":1,"description":"Google Place id"}},"required":["placeId"]}},{"name":"needleComposePreview","title":"Preview an AI-composed message","description":"Preview an AI-composed outreach message without sending it. identity accepts the same forms as leads: LinkedIn public identifier, /in/ path, profile URL, or user id; Instagram username, @handle, or profile URL.","category":"Compose","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"channel":{"type":"string","enum":["linkedin","instagram"]},"connectedAccountId":{"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)$"},"identity":{"type":"string","minLength":1,"description":"LinkedIn public identifier, /in/ path, profile URL, or user id (ACoAAA…); or Instagram username, @handle, or profile URL. Stored as the identifier."},"prompt":{"type":"string","minLength":1},"context":{"default":["conversation"],"type":"array","items":{"type":"string","enum":["profile","posts","conversation","lead_properties"]}},"maxChars":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"leadProperties":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["channel","connectedAccountId","identity","prompt"]}},{"name":"needleListFiles","title":"List files","description":"List a page of files you can use: every workspace file, then your private files. Each item includes scope. Pass a workspace url on a campaign step or a LinkedIn send. Pass your own user url on needleSendLinkedinMessage or needleSendLinkedinInMail. Use nextCursor as cursor for the next page.","category":"Files","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"cursor":{"type":"string","minLength":1},"limit":{"type":"integer","minimum":1,"maximum":100}}}},{"name":"needleCreateFileAccessUrl","title":"Create a file preview URL","description":"Mint a preview URL for a stored file. It redirects to a short-lived signed GET. Do not send it to LinkedIn.","category":"Files","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string","maxLength":4096,"format":"uri"}},"required":["url"]}},{"name":"needleDeleteFile","title":"Delete a file","description":"Delete a private file stored in Needle. Pass the url from needleListFiles or from creating a file. Messages and campaign steps that still reference it will fail when sending.","category":"Files","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string","maxLength":4096,"format":"uri"}},"required":["url"]}},{"name":"needleListSuppressions","title":"List suppressions","description":"List a page of suppression entries. Optionally filter by reason. Use nextCursor as cursor for the next page.","category":"Suppressions","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"cursor":{"type":"string","minLength":1},"limit":{"type":"integer","minimum":1,"maximum":100},"reason":{"type":"string","enum":["manual","unsubscribed","not_interested","existing_customer","open_opportunity","competitor","employee","invalid_recipient","complained","recently_contacted","unresponsive"]}}}},{"name":"needleSearchSuppressions","title":"Search suppressions","description":"Find suppression entries by person, company domain, note, or reason. Every word in query must match; people or domains starting with it come first. Pass nextCursor as cursor, with the same query, for more. Use the returned id with needleDeleteSuppression.","category":"Suppressions","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"query":{"type":"string","minLength":1,"maxLength":200,"description":"Text to match. Every word must appear in the record."},"cursor":{"type":"string","minLength":1},"limit":{"type":"integer","minimum":1,"maximum":100}},"required":["query"]}},{"name":"needleCreateSuppressions","title":"Create suppressions","description":"Create suppression entries for people or companies.","category":"Suppressions","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"entries":{"minItems":1,"maxItems":1000,"type":"array","items":{"oneOf":[{"type":"object","properties":{"scope":{"type":"string","const":"lead"},"leadId":{"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)$"},"reason":{"type":"string","enum":["manual","unsubscribed","not_interested","existing_customer","open_opportunity","competitor","employee","invalid_recipient","complained","recently_contacted","unresponsive"]},"note":{"type":"string","maxLength":500},"expiresAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}},"required":["scope","leadId","reason"]},{"type":"object","properties":{"scope":{"type":"string","const":"company"},"companyDomain":{"type":"string","minLength":1,"maxLength":256},"reason":{"type":"string","enum":["manual","unsubscribed","not_interested","existing_customer","open_opportunity","competitor","employee","invalid_recipient","complained","recently_contacted","unresponsive"]},"note":{"type":"string","maxLength":500},"expiresAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}},"required":["scope","companyDomain","reason"]}]}}},"required":["entries"]}},{"name":"needleCheckSuppressions","title":"Check people and companies against the suppression list","description":"Check whether identities are contactable or suppressed. IdenToolAnnotationWrite,tity accepts the same forms as leads: LinkedIn public identifier, /in/ path, profile URL, or user id; Instagram username, @handle, or profile URL.","category":"Suppressions","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"identities":{"minItems":1,"maxItems":1000,"type":"array","items":{"type":"object","properties":{"channel":{"type":"string","enum":["linkedin","instagram"]},"identity":{"type":"string","minLength":1,"maxLength":512,"description":"LinkedIn public identifier, /in/ path, profile URL, or user id (ACoAAA…); or Instagram username, @handle, or profile URL. Stored as the identifier."},"companyDomain":{"type":"string","maxLength":256},"campaignId":{"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)$"}},"required":["channel","identity"]}}},"required":["identities"]}},{"name":"needleDeleteSuppression","title":"Delete a suppression","description":"Delete a suppression entry.","category":"Suppressions","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"suppressionId":{"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)$","description":"Suppression id"}},"required":["suppressionId"]}},{"name":"needleListWebhooks","title":"List webhooks","description":"List the workspace's webhooks, oldest first, with their delivery status. lastError is null when the last delivery succeeded.","category":"Webhooks","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{}}},{"name":"needleCreateWebhook","title":"Create a webhook","description":"Add an https URL that receives events, signed with a new secret. eventTypes picks the event types: \"all\" (the default, also types added later) or a list. The whsec_ secret is returned only here; show it to the user so they can store it. Up to 5 per workspace. Optional headers, such as an API key the URL requires, are sent with every request. Header values you send pass through your AI app.","category":"Webhooks","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string","maxLength":2048,"format":"uri","description":"An https URL that accepts POST requests."},"headers":{"description":"Extra headers sent with every request, for example an API key your endpoint checks: {\"Authorization\": \"Bearer ...\"}. Up to 5. Names are stored in lower case.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}},"eventTypes":{"description":"The event types this webhook gets: \"all\" (every type, also types added later) or a list. Left out, it is \"all\".","anyOf":[{"type":"string","const":"all"},{"minItems":1,"type":"array","items":{"anyOf":[{"type":"string","const":"lead_created","description":"A lead was created, from the app, the API, MCP, an import, or a direct message to someone who was not a lead yet."},{"type":"string","const":"lead_updated","description":"A lead's details or handles changed; `data.changes` lists each changed field."},{"type":"string","const":"lead_deleted","description":"A lead was deleted. Its live campaigns stop with `exitReason` `lead_deleted`."},{"type":"string","const":"lead_enrolled","description":"A lead was added to a campaign."},{"type":"string","const":"lead_skipped","description":"A lead was not added to a campaign; `data.skipReason` says why."},{"type":"string","const":"message_generated","description":"AI wrote a message for a step."},{"type":"string","const":"condition_evaluated","description":"A check in the sequence was evaluated."},{"type":"string","const":"task_held","description":"A step is waiting for approval. Deprecated: use `draft_created`, which is sent alongside it."},{"type":"string","const":"task_approved","description":"A held step was approved. Deprecated: use `draft_approved`, which is sent alongside it."},{"type":"string","const":"draft_created","description":"A drafted message is waiting for a member to review it, created through the API or held by a campaign step."},{"type":"string","const":"draft_approved","description":"A member approved a draft, possibly after editing it (`data.edited`). The message itself is the `linkedin_message_sent` (also for an InMail), `linkedin_invite_sent` or `instagram_message_sent` event that follows, with the same `data.draftId`. An approved InMail to someone out of network without Open Profile goes out as a connection request without a note instead."},{"type":"string","const":"draft_discarded","description":"A draft will not be sent; `data.discardReason` says why."},{"type":"string","const":"draft_failed","description":"An approved draft could not be sent; `data.message` says why."},{"type":"string","const":"task_skipped","description":"A step was skipped; `data.skipReason` says why."},{"type":"string","const":"task_cancelled","description":"A step was cancelled before it ran."},{"type":"string","const":"task_failed","description":"A step failed; `data.errorKind` says why."},{"type":"string","const":"enrollment_waiting","description":"The sequence is waiting, for example for a reply."},{"type":"string","const":"enrollment_completed","description":"The lead reached the end of the sequence."},{"type":"string","const":"enrollment_stopped","description":"The sequence stopped early; `data.exitReason` says why."},{"type":"string","const":"lead_suppressed","description":"A lead matched a [suppression](https://needle.app/docs/suppressions)."},{"type":"string","const":"campaign_status_changed","description":"A campaign's status changed, for example it was started or paused."},{"type":"string","const":"campaign_updated","description":"A campaign's name, sequence, schedule, limits or suppression policy was edited; `data.changedFields` lists which."},{"type":"string","const":"account_connected","description":"A LinkedIn or Instagram account was connected to the workspace for the first time, or again after it was deleted."},{"type":"string","const":"account_reconnected","description":"A disconnected account works again, because a member signed in to it again or LinkedIn or Instagram reports it healthy."},{"type":"string","const":"account_deleted","description":"A connected account was deleted."},{"type":"string","const":"account_paused","description":"A connected account was paused, by its owner or after hitting a limit (`data.errorKind`)."},{"type":"string","const":"account_resumed","description":"A paused connected account was resumed, by its owner or when billing was restored."},{"type":"string","const":"account_disconnected","description":"A connected account stopped working: it needs signing in again (`data.errorKind` is `auth_required`) or LinkedIn or Instagram disconnected it (`disconnected`). Its campaigns wait until it is reconnected."},{"type":"string","const":"account_suspended","description":"A connected account was signed out and stopped, because the workspace's billing lapsed or its owner was removed from the workspace (`data.message`). It has to be connected again to be used."},{"type":"string","const":"account_limits_updated","description":"A connected account's usage limits were changed; `data.changes` lists each limit."},{"type":"string","const":"account_access_granted","description":"A member (`data.member`) was allowed to use a connected account."},{"type":"string","const":"account_access_revoked","description":"A member (`data.member`) can no longer use a connected account. Campaigns they started with it pause."},{"type":"string","const":"account_sharing_changed","description":"A connected account was shared with the whole workspace, or stopped being shared."},{"type":"string","const":"member_invited","description":"Someone was invited to the workspace."},{"type":"string","const":"member_invitation_revoked","description":"An invitation to the workspace was withdrawn."},{"type":"string","const":"member_joined","description":"Someone accepted an invitation and joined."},{"type":"string","const":"member_role_changed","description":"A member's role changed."},{"type":"string","const":"member_removed","description":"An admin removed a member. Their accounts are suspended and their campaigns pause."},{"type":"string","const":"member_left","description":"A member deleted their Needle account."},{"type":"string","const":"api_key_created","description":"An API key was created."},{"type":"string","const":"api_key_revoked","description":"An API key was disabled."},{"type":"string","const":"api_key_enabled","description":"A disabled API key was enabled again."},{"type":"string","const":"api_key_deleted","description":"An API key was deleted."},{"type":"string","const":"webhook_created","description":"A webhook was added."},{"type":"string","const":"webhook_updated","description":"A webhook's URL or headers changed; `data.changedFields` lists which."},{"type":"string","const":"webhook_deleted","description":"A webhook was removed."},{"type":"string","const":"suppression_added","description":"A lead or company was added to the [do-not-contact list](https://needle.app/docs/suppressions) by a member or through the API."},{"type":"string","const":"suppression_removed","description":"An entry was removed from the [do-not-contact list](https://needle.app/docs/suppressions)."},{"type":"string","const":"linkedin_profile_visited","description":"A LinkedIn profile was visited."},{"type":"string","const":"linkedin_invite_sent","description":"A LinkedIn connection request was sent."},{"type":"string","const":"linkedin_invite_withdrawn","description":"A LinkedIn connection request was withdrawn."},{"type":"string","const":"linkedin_message_sent","description":"A LinkedIn message was sent, through Needle or by the account owner in LinkedIn (`data.sentOutsideNeedle`)."},{"type":"string","const":"linkedin_follow_sent","description":"A LinkedIn profile was followed."},{"type":"string","const":"linkedin_unfollowed","description":"A LinkedIn profile was unfollowed."},{"type":"string","const":"linkedin_invite_accepted","description":"A LinkedIn connection request was accepted."},{"type":"string","const":"linkedin_message_received","description":"A LinkedIn reply was received."},{"type":"string","const":"linkedin_post_commented","description":"A comment was posted on LinkedIn."},{"type":"string","const":"linkedin_post_reacted","description":"A reaction was added to a LinkedIn post."},{"type":"string","const":"instagram_message_sent","description":"An Instagram message was sent, through Needle or by the account owner in Instagram (`data.sentOutsideNeedle`)."},{"type":"string","const":"instagram_profile_visited","description":"An Instagram profile was visited."},{"type":"string","const":"instagram_follow_sent","description":"An Instagram profile was followed."},{"type":"string","const":"instagram_unfollowed","description":"An Instagram profile was unfollowed."},{"type":"string","const":"instagram_message_received","description":"An Instagram reply was received."},{"type":"string","const":"instagram_post_commented","description":"A comment was posted on Instagram."},{"type":"string","const":"instagram_post_reacted","description":"An Instagram post was liked."},{"type":"string","const":"instagram_message_reacted","description":"A reaction was added to an Instagram message."},{"type":"string","const":"instagram_post_created","description":"An Instagram post was published."}]}}]}},"required":["url"]}},{"name":"needleGetWebhook","title":"Get a webhook","description":"Get one webhook with its delivery status.","category":"Webhooks","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"webhookId":{"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)$","description":"Webhook id"}},"required":["webhookId"]}},{"name":"needleUpdateWebhook","title":"Update a webhook","description":"Change the URL, the headers, the event types, or several at once. Only the member who created the webhook can change it. Pending deliveries of event types no longer picked are dropped. Only the headers named change: a value sets or replaces one, null removes it. A new URL removes all saved headers first. The secret stays the same, and pending deliveries go out with the new URL and headers. Header values you send pass through your AI app.","category":"Webhooks","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"webhookId":{"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)$","description":"Webhook id"},"url":{"description":"The new URL. A different URL removes all saved headers first.","type":"string","maxLength":2048,"format":"uri"},"headers":{"description":"Changes only the headers named here: a value sets or replaces that header, null removes it. Headers not named stay, except when url changes: then only the headers sent here are kept.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{"anyOf":[{"type":"string"},{"type":"null"}]}},"eventTypes":{"description":"The new event types: \"all\" or a list. Pending deliveries of types no longer in the list are dropped; added types only get events from now on.","anyOf":[{"type":"string","const":"all"},{"minItems":1,"type":"array","items":{"anyOf":[{"type":"string","const":"lead_created","description":"A lead was created, from the app, the API, MCP, an import, or a direct message to someone who was not a lead yet."},{"type":"string","const":"lead_updated","description":"A lead's details or handles changed; `data.changes` lists each changed field."},{"type":"string","const":"lead_deleted","description":"A lead was deleted. Its live campaigns stop with `exitReason` `lead_deleted`."},{"type":"string","const":"lead_enrolled","description":"A lead was added to a campaign."},{"type":"string","const":"lead_skipped","description":"A lead was not added to a campaign; `data.skipReason` says why."},{"type":"string","const":"message_generated","description":"AI wrote a message for a step."},{"type":"string","const":"condition_evaluated","description":"A check in the sequence was evaluated."},{"type":"string","const":"task_held","description":"A step is waiting for approval. Deprecated: use `draft_created`, which is sent alongside it."},{"type":"string","const":"task_approved","description":"A held step was approved. Deprecated: use `draft_approved`, which is sent alongside it."},{"type":"string","const":"draft_created","description":"A drafted message is waiting for a member to review it, created through the API or held by a campaign step."},{"type":"string","const":"draft_approved","description":"A member approved a draft, possibly after editing it (`data.edited`). The message itself is the `linkedin_message_sent` (also for an InMail), `linkedin_invite_sent` or `instagram_message_sent` event that follows, with the same `data.draftId`. An approved InMail to someone out of network without Open Profile goes out as a connection request without a note instead."},{"type":"string","const":"draft_discarded","description":"A draft will not be sent; `data.discardReason` says why."},{"type":"string","const":"draft_failed","description":"An approved draft could not be sent; `data.message` says why."},{"type":"string","const":"task_skipped","description":"A step was skipped; `data.skipReason` says why."},{"type":"string","const":"task_cancelled","description":"A step was cancelled before it ran."},{"type":"string","const":"task_failed","description":"A step failed; `data.errorKind` says why."},{"type":"string","const":"enrollment_waiting","description":"The sequence is waiting, for example for a reply."},{"type":"string","const":"enrollment_completed","description":"The lead reached the end of the sequence."},{"type":"string","const":"enrollment_stopped","description":"The sequence stopped early; `data.exitReason` says why."},{"type":"string","const":"lead_suppressed","description":"A lead matched a [suppression](https://needle.app/docs/suppressions)."},{"type":"string","const":"campaign_status_changed","description":"A campaign's status changed, for example it was started or paused."},{"type":"string","const":"campaign_updated","description":"A campaign's name, sequence, schedule, limits or suppression policy was edited; `data.changedFields` lists which."},{"type":"string","const":"account_connected","description":"A LinkedIn or Instagram account was connected to the workspace for the first time, or again after it was deleted."},{"type":"string","const":"account_reconnected","description":"A disconnected account works again, because a member signed in to it again or LinkedIn or Instagram reports it healthy."},{"type":"string","const":"account_deleted","description":"A connected account was deleted."},{"type":"string","const":"account_paused","description":"A connected account was paused, by its owner or after hitting a limit (`data.errorKind`)."},{"type":"string","const":"account_resumed","description":"A paused connected account was resumed, by its owner or when billing was restored."},{"type":"string","const":"account_disconnected","description":"A connected account stopped working: it needs signing in again (`data.errorKind` is `auth_required`) or LinkedIn or Instagram disconnected it (`disconnected`). Its campaigns wait until it is reconnected."},{"type":"string","const":"account_suspended","description":"A connected account was signed out and stopped, because the workspace's billing lapsed or its owner was removed from the workspace (`data.message`). It has to be connected again to be used."},{"type":"string","const":"account_limits_updated","description":"A connected account's usage limits were changed; `data.changes` lists each limit."},{"type":"string","const":"account_access_granted","description":"A member (`data.member`) was allowed to use a connected account."},{"type":"string","const":"account_access_revoked","description":"A member (`data.member`) can no longer use a connected account. Campaigns they started with it pause."},{"type":"string","const":"account_sharing_changed","description":"A connected account was shared with the whole workspace, or stopped being shared."},{"type":"string","const":"member_invited","description":"Someone was invited to the workspace."},{"type":"string","const":"member_invitation_revoked","description":"An invitation to the workspace was withdrawn."},{"type":"string","const":"member_joined","description":"Someone accepted an invitation and joined."},{"type":"string","const":"member_role_changed","description":"A member's role changed."},{"type":"string","const":"member_removed","description":"An admin removed a member. Their accounts are suspended and their campaigns pause."},{"type":"string","const":"member_left","description":"A member deleted their Needle account."},{"type":"string","const":"api_key_created","description":"An API key was created."},{"type":"string","const":"api_key_revoked","description":"An API key was disabled."},{"type":"string","const":"api_key_enabled","description":"A disabled API key was enabled again."},{"type":"string","const":"api_key_deleted","description":"An API key was deleted."},{"type":"string","const":"webhook_created","description":"A webhook was added."},{"type":"string","const":"webhook_updated","description":"A webhook's URL or headers changed; `data.changedFields` lists which."},{"type":"string","const":"webhook_deleted","description":"A webhook was removed."},{"type":"string","const":"suppression_added","description":"A lead or company was added to the [do-not-contact list](https://needle.app/docs/suppressions) by a member or through the API."},{"type":"string","const":"suppression_removed","description":"An entry was removed from the [do-not-contact list](https://needle.app/docs/suppressions)."},{"type":"string","const":"linkedin_profile_visited","description":"A LinkedIn profile was visited."},{"type":"string","const":"linkedin_invite_sent","description":"A LinkedIn connection request was sent."},{"type":"string","const":"linkedin_invite_withdrawn","description":"A LinkedIn connection request was withdrawn."},{"type":"string","const":"linkedin_message_sent","description":"A LinkedIn message was sent, through Needle or by the account owner in LinkedIn (`data.sentOutsideNeedle`)."},{"type":"string","const":"linkedin_follow_sent","description":"A LinkedIn profile was followed."},{"type":"string","const":"linkedin_unfollowed","description":"A LinkedIn profile was unfollowed."},{"type":"string","const":"linkedin_invite_accepted","description":"A LinkedIn connection request was accepted."},{"type":"string","const":"linkedin_message_received","description":"A LinkedIn reply was received."},{"type":"string","const":"linkedin_post_commented","description":"A comment was posted on LinkedIn."},{"type":"string","const":"linkedin_post_reacted","description":"A reaction was added to a LinkedIn post."},{"type":"string","const":"instagram_message_sent","description":"An Instagram message was sent, through Needle or by the account owner in Instagram (`data.sentOutsideNeedle`)."},{"type":"string","const":"instagram_profile_visited","description":"An Instagram profile was visited."},{"type":"string","const":"instagram_follow_sent","description":"An Instagram profile was followed."},{"type":"string","const":"instagram_unfollowed","description":"An Instagram profile was unfollowed."},{"type":"string","const":"instagram_message_received","description":"An Instagram reply was received."},{"type":"string","const":"instagram_post_commented","description":"A comment was posted on Instagram."},{"type":"string","const":"instagram_post_reacted","description":"An Instagram post was liked."},{"type":"string","const":"instagram_message_reacted","description":"A reaction was added to an Instagram message."},{"type":"string","const":"instagram_post_created","description":"An Instagram post was published."}]}}]}},"required":["webhookId"]}},{"name":"needleDeleteWebhook","title":"Delete a webhook","description":"Delete a webhook. Only the member who created it or a workspace admin can. Needle stops sending events to it, and its pending deliveries are dropped.","category":"Webhooks","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"webhookId":{"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)$","description":"Webhook id"}},"required":["webhookId"]}},{"name":"needleSearchDocs","title":"Search the Needle docs","description":"Find Needle documentation pages: guides, concepts, every REST API endpoint, and every MCP tool. Pages that match more of the words come first. Read a result with needleReadDocs and its pageId.","category":"Docs","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"query":{"type":"string","minLength":1,"maxLength":200,"description":"Words to look for. Pages that match more of them come first."},"limit":{"description":"Most pages to return. Default 10.","type":"integer","minimum":1,"maximum":20}},"required":["query"]}},{"name":"needleReadDocs","title":"Read the Needle docs","description":"Read one page of the Needle documentation as markdown. Use it to answer how Needle works: its features, integrations, setup, and limits.\nNot sure which page? Search first with needleSearchDocs.\nPages:\n- introduction: What Needle is and the ways to use it: the dashboard, the REST API, and MCP.\n- authentication: Two ways in: API keys for the REST API, sign-in for MCP.\n- agent-onboarding: Where an agent starts: MCP, the REST API, credentials, and common outbound workflows.\n- api-reference/introduction: Every REST API endpoint. Each endpoint has its own page, for example api-reference/create-lead.\n- mcp/introduction: Every MCP tool. Each tool has its own page, for example mcp/needle-create-lead.\n- changelog: Notable changes to the Needle Agents REST API and MCP server.\n- workspaces: Where leads, campaigns, and connected accounts live.\n- leads: People you can enroll in a campaign.\n- campaigns: Sequences this workspace is running.\n- enrollments: A lead moving through a campaign sequence.\n- drafts: Messages that wait for a person to approve them.\n- connected-accounts: LinkedIn and Instagram senders this workspace reaches out from.\n- suppressions: People and companies on the do-not-contact list.\n- events: Activity across campaigns, leads, and connected accounts.\n- webhooks: Receive events at your own URL as they happen.\n- attio: Sync your team's LinkedIn activity to your Attio People.\n- places: Companies and locations you can turn into lead lists.\n- compose: Preview an AI-written message before you send it.\n- agents: Personal agents that work in Slack and Teams.","category":"Docs","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"pageId":{"type":"string","minLength":1,"maxLength":500,"description":"The page's path after /docs/, for example `attio` or `mcp/needle-create-lead`. A full docs URL works too."}},"required":["pageId"]}},{"name":"needleGetOnboardingInfo","title":"Get onboarding info","description":"Get what the user told Needle during onboarding and what it produced: the use case, website, notes, attached documents, the ideal customer profile, the ids of the leads found, the onboarding campaign id, and when onboarding was completed. Fields the user has not reached yet are null or empty.","category":"Onboarding","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{}}},{"name":"needleCreateFileUpload","title":"Create a file upload","description":"Mint a short-lived signed PUT URL, or copy a public file with sourceUrl. Omit scope for a workspace file. Pass scope \"user\" to keep the file visible only to you. PUT bytes to uploadUrl when it is returned, then pass the returned url on needleSendLinkedinMessage or needleSendLinkedinInMail. Campaign steps can attach workspace files only. downloadUrl is a preview link. Do not store uploadUrl.","category":"Files","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"scope":{"description":"workspace shares the file with the organization. user keeps it visible only to you. Omit for a workspace file. Campaign steps can attach workspace files only.","type":"string","enum":["workspace","user"]},"filename":{"type":"string","minLength":1,"maxLength":255},"contentType":{"type":"string","minLength":1,"maxLength":127},"sourceUrl":{"description":"Public https URL. Needle copies the file into a private object and returns the url to attach.","type":"string","maxLength":4096,"format":"uri"}}}},{"name":"needleGetAssistantChat","title":"Get an assistant chat","description":"Read a chat the user had with the assistant inside the Needle web app, to continue it here. When `handoff` is set, the assistant passed the task on: its `brief` holds the goal, the ids involved, what was already found, and what is left. Start from the brief and carry the task out with your Needle tools. Messages hold each turn's text and the tools it called. Calls since the last user message keep their results; earlier ones do not.","category":"Assistant chats","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"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)$"}},"required":["id"]}}],"requestId":"0e9c87aa-abce-45de-910e-97cc3570d564"}