{"openapi":"3.1.0","info":{"title":"Rynora API","description":"LinkedIn people, organizations, jobs and contact details, as JSON.","version":"1.0.0"},"paths":{"/api/v2/person/resolve-handle":{"get":{"tags":["Live API - Person"],"summary":"Resolve a handle to an entityId","description":"Turn a public handle into the stable entityId.\n\nCosts a scrape the first time we see somebody, and nothing afterwards. The\nentityId is worth the round trip because it is the one identifier that\nsurvives the person renaming their profile.","operationId":"resolve_handle_api_v2_person_resolve_handle_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"handle","in":"query","required":true,"schema":{"type":"string","description":"The slug from a profile URL","title":"Handle"},"description":"The slug from a profile URL"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/person/enrich":{"get":{"tags":["Live API - Person"],"summary":"Enrich a person (full profile)","description":"The complete profile for one person, fetched live.\n\nThis is the expensive call: about nine navigations with a pause between\neach, so expect minutes rather than milliseconds. It is also what populates\nthe other five endpoints - they are views over what this scrape produced.","operationId":"enrich_api_v2_person_enrich_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"entityId","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque ACoAA... token","title":"Entityid"},"description":"Opaque ACoAA... token"},{"name":"handle","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Public profile slug","title":"Handle"},"description":"Public profile slug"},{"name":"refresh","in":"query","required":false,"schema":{"type":"boolean","description":"Fetch from LinkedIn now. Set false to accept the stored copy, which answers in milliseconds instead of minutes.","default":true,"title":"Refresh"},"description":"Fetch from LinkedIn now. Set false to accept the stored copy, which answers in milliseconds instead of minutes."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/person/employment-history":{"get":{"tags":["Live API - Person"],"summary":"Get full employment history","description":"Every position with its dates, plus the tenure arithmetic a caller would\notherwise have to redo from prose date strings.","operationId":"employment_history_api_v2_person_employment_history_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"entityId","in":"query","required":true,"schema":{"type":"string","description":"The person's opaque LinkedIn token (ACoAA...). Get one from /person/resolve-handle. Preferred over a handle because it survives the person renaming their profile.","title":"Entityid"},"description":"The person's opaque LinkedIn token (ACoAA...). Get one from /person/resolve-handle. Preferred over a handle because it survives the person renaming their profile."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/person/endorsements":{"get":{"tags":["Live API - Person"],"summary":"Get recommendations / endorsements","description":"Recommendations written for this person, with their authors.\n\nMost profiles have none - LinkedIn says so explicitly on the section - so\nan empty list is the ordinary answer rather than a sign of a failed scrape.","operationId":"endorsements_api_v2_person_endorsements_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"entityId","in":"query","required":true,"schema":{"type":"string","description":"The person's opaque LinkedIn token (ACoAA...). Get one from /person/resolve-handle. Preferred over a handle because it survives the person renaming their profile.","title":"Entityid"},"description":"The person's opaque LinkedIn token (ACoAA...). Get one from /person/resolve-handle. Preferred over a handle because it survives the person renaming their profile."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/person/lookalikes":{"get":{"tags":["Live API - Person"],"summary":"Get similar people","description":"Profiles LinkedIn shows alongside this one.\n\nTaken from the related-profiles rail, which LinkedIn renders on every\nprofile page - so it comes free with the enrich rather than costing its\nown navigation.","operationId":"lookalikes_api_v2_person_lookalikes_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"entityId","in":"query","required":true,"schema":{"type":"string","description":"The person's opaque LinkedIn token (ACoAA...). Get one from /person/resolve-handle. Preferred over a handle because it survives the person renaming their profile.","title":"Entityid"},"description":"The person's opaque LinkedIn token (ACoAA...). Get one from /person/resolve-handle. Preferred over a handle because it survives the person renaming their profile."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/person/interests":{"get":{"tags":["Live API - Person"],"summary":"Get a person's interests","description":"What the person follows, grouped by the kind of thing it is.\n\nGrouped rather than returned flat because the categories answer different\nquestions - the companies somebody follows and the newsletters they read\nare not the same signal.","operationId":"interests_api_v2_person_interests_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"entityId","in":"query","required":true,"schema":{"type":"string","description":"The person's opaque LinkedIn token (ACoAA...). Get one from /person/resolve-handle. Preferred over a handle because it survives the person renaming their profile.","title":"Entityid"},"description":"The person's opaque LinkedIn token (ACoAA...). Get one from /person/resolve-handle. Preferred over a handle because it survives the person renaming their profile."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/person/batch/enrich":{"post":{"tags":["Live API - Person"],"summary":"Submit a batch person-enrich job","description":"Enrich a list of people in the background.\n\nThe batch form of `enrich`: accepts entityIds and handles, returns at once\nwith a job token, and resolves them one at a time behind the request. Poll\nthe GET on this path to stream results as they land. One credit per\nprofile that resolves, charged as the worker gets to it; a not-found is\nfree; submitting and polling are free.","operationId":"submit_batch_api_v2_person_batch_enrich_post","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchEnrichRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Live API - Person"],"summary":"Track a batch job and stream its results","description":"Job progress plus the next page of resolved profiles.\n\nFree to poll: each profile was charged as it resolved, so read as often as\nthe rate limit allows. `credits_charged` reports the running total.","operationId":"track_batch_api_v2_person_batch_enrich_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"job_id","in":"query","required":true,"schema":{"type":"string","description":"The token returned by the POST","title":"Job Id"},"description":"The token returned by the POST"},{"name":"after","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"How many results you have already taken. Start at 0, then pass back the next_cursor from your previous poll to receive only what is new.","default":0,"title":"After"},"description":"How many results you have already taken. Start at 0, then pass back the next_cursor from your previous poll to receive only what is new."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/person/batch/jobs":{"get":{"tags":["Live API - Person"],"summary":"List your batch jobs","description":"Every person batch job this key's account has submitted, newest first,\nwith its token - for when the 202 was not kept. Free. Jobs are deleted\nsix hours after submission, so this is a recent-history view, not an\narchive.","operationId":"jobs_api_v2_person_batch_jobs_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(processing|completed|stopped_no_credits)$"},{"type":"null"}],"description":"Only jobs in this state. Omit for all.","title":"Status"},"description":"Only jobs in this state. Omit for all."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/activity/feed":{"get":{"tags":["Live API - Activity"],"summary":"Get a person's activity feed","description":"Recent posts and shares by one person.\n\nServed from the 24-hour activity cache, so paging through it costs nothing\nafter the first page - the whole feed is fetched once and paged locally.","operationId":"feed_api_v2_activity_feed_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"entityId","in":"query","required":true,"schema":{"type":"string","description":"The person's ACoAA... token","title":"Entityid"},"description":"The person's ACoAA... token"},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque pagination token. Omit for the first page, then pass the next_cursor from the previous response. Treat it as a black box: it encodes a position, not a page number.","title":"Cursor"},"description":"Opaque pagination token. Omit for the first page, then pass the next_cursor from the previous response. Treat it as a black box: it encodes a position, not a page number."},{"name":"start","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"description":"Zero-based offset into the result set. An alternative to cursor; both describe the same position.","title":"Start"},"description":"Zero-based offset into the result set. An alternative to cursor; both describe the same position."},{"name":"count","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"How many results to return in this page.","default":10,"title":"Count"},"description":"How many results to return in this page."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/activity/replies/by-author":{"get":{"tags":["Live API - Activity"],"summary":"Get replies written by a person","description":"Comments this person wrote, across LinkedIn - not the comments on one of\ntheir posts.\n\nA different surface from the feed: LinkedIn keeps it on its own activity\ntab, so this costs its own navigation.","operationId":"replies_by_author_api_v2_activity_replies_by_author_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"entityId","in":"query","required":true,"schema":{"type":"string","description":"The person's ACoAA... token","title":"Entityid"},"description":"The person's ACoAA... token"},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque pagination token. Omit for the first page, then pass the next_cursor from the previous response. Treat it as a black box: it encodes a position, not a page number.","title":"Cursor"},"description":"Opaque pagination token. Omit for the first page, then pass the next_cursor from the previous response. Treat it as a black box: it encodes a position, not a page number."},{"name":"start","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"description":"Zero-based offset into the result set. An alternative to cursor; both describe the same position.","title":"Start"},"description":"Zero-based offset into the result set. An alternative to cursor; both describe the same position."},{"name":"count","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"How many results to return in this page.","default":10,"title":"Count"},"description":"How many results to return in this page."},{"name":"refresh","in":"query","required":false,"schema":{"type":"boolean","description":"Skip the cache and fetch now","default":false,"title":"Refresh"},"description":"Skip the cache and fetch now"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/activity/details":{"get":{"tags":["Live API - Activity"],"summary":"Get details of a single activity","description":"Full content and engagement for one post.\n\nAnswered from a cached feed when the post is in one - the feed card and the\npermalink carry the same text and counts, so opening the post again would\nspend a navigation to learn nothing.","operationId":"details_api_v2_activity_details_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"entityId","in":"query","required":true,"schema":{"type":"string","description":"The activity urn","title":"Entityid"},"description":"The activity urn"},{"name":"refresh","in":"query","required":false,"schema":{"type":"boolean","description":"Skip the cache and fetch now","default":false,"title":"Refresh"},"description":"Skip the cache and fetch now"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/activity/reactions":{"get":{"tags":["Live API - Activity"],"summary":"Get reactions on an activity","description":"The people behind a post's reaction count.\n\n`start` moves in tens because that is how LinkedIn pages the reactions\nmodal; a value in between would silently land on a different page than the\ncaller asked for, so it is rejected instead.","operationId":"reactions_api_v2_activity_reactions_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"entityId","in":"query","required":true,"schema":{"type":"string","description":"The activity urn","title":"Entityid"},"description":"The activity urn"},{"name":"start","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Zero-based offset into the result set. An alternative to cursor; both describe the same position.","default":0,"title":"Start"},"description":"Zero-based offset into the result set. An alternative to cursor; both describe the same position."},{"name":"refresh","in":"query","required":false,"schema":{"type":"boolean","description":"Skip the cache and fetch now","default":false,"title":"Refresh"},"description":"Skip the cache and fetch now"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/activity/replies":{"get":{"tags":["Live API - Activity"],"summary":"Get replies (comments) on an activity","description":"The conversation under a post.\n\nLinkedIn renders comments in its own relevance order and hides the rest\nbehind \"Load more comments\", so `date_posted` reverses what was rendered\nrather than re-sorting by a timestamp we do not reliably have - the cards\ncarry \"2w\", not a date.","operationId":"replies_api_v2_activity_replies_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"entityId","in":"query","required":true,"schema":{"type":"string","description":"The activity urn","title":"Entityid"},"description":"The activity urn"},{"name":"sortBy","in":"query","required":false,"schema":{"type":"string","pattern":"^(relevance|date_posted)$","description":"Result order. relevance is LinkedIn's own ranking; date_posted puts the newest first.","default":"relevance","title":"Sortby"},"description":"Result order. relevance is LinkedIn's own ranking; date_posted puts the newest first."},{"name":"count","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"How many results to return in this page.","default":10,"title":"Count"},"description":"How many results to return in this page."},{"name":"start","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Zero-based offset into the result set. An alternative to cursor; both describe the same position.","default":0,"title":"Start"},"description":"Zero-based offset into the result set. An alternative to cursor; both describe the same position."},{"name":"refresh","in":"query","required":false,"schema":{"type":"boolean","description":"Skip the cache and fetch now","default":false,"title":"Refresh"},"description":"Skip the cache and fetch now"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/opportunity/details":{"get":{"tags":["Live API - Opportunity"],"summary":"Get opportunity (job) details","description":"The full posting: title, description, company, location, employment type\nand apply metadata.\n\nCached for seven days rather than a month - a posting closes, and serving a\nclosed one as current is worse than fetching it again.","operationId":"details_api_v2_opportunity_details_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"opportunityEntityId","in":"query","required":true,"schema":{"type":"string","description":"The numeric job id","title":"Opportunityentityid"},"description":"The numeric job id"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/opportunity/similar":{"get":{"tags":["Live API - Opportunity"],"summary":"Get similar opportunities","description":"Postings LinkedIn lists alongside this one.","operationId":"similar_api_v2_opportunity_similar_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"opportunityEntityId","in":"query","required":true,"schema":{"type":"string","description":"The numeric job id, the digits in linkedin.com/jobs/view/<id>. Get one from /discover/opportunities or /organization/opportunities.","title":"Opportunityentityid"},"description":"The numeric job id, the digits in linkedin.com/jobs/view/<id>. Get one from /discover/opportunities or /organization/opportunities."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/opportunity/related-views":{"get":{"tags":["Live API - Opportunity"],"summary":"Get \"people also viewed\" opportunities","description":"Jobs that people who viewed this posting also viewed.\n\nReads the same rail as `similar`, because LinkedIn merged the two. The\n`signal` field says so rather than letting a caller believe they have a\nbehavioural signal distinct from content similarity.","operationId":"related_views_api_v2_opportunity_related_views_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"opportunityEntityId","in":"query","required":true,"schema":{"type":"string","description":"The numeric job id, the digits in linkedin.com/jobs/view/<id>. Get one from /discover/opportunities or /organization/opportunities.","title":"Opportunityentityid"},"description":"The numeric job id, the digits in linkedin.com/jobs/view/<id>. Get one from /discover/opportunities or /organization/opportunities."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/opportunity/hiring-team":{"get":{"tags":["Live API - Opportunity"],"summary":"Get the hiring team for an opportunity","description":"The recruiters and hiring managers attached to a posting.\n\nMost postings have none - LinkedIn only shows contacts when the poster\nopted in - so an empty list is an ordinary answer, not a failed scrape.","operationId":"hiring_team_api_v2_opportunity_hiring_team_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"opportunityEntityId","in":"query","required":true,"schema":{"type":"string","description":"The numeric job id, the digits in linkedin.com/jobs/view/<id>. Get one from /discover/opportunities or /organization/opportunities.","title":"Opportunityentityid"},"description":"The numeric job id, the digits in linkedin.com/jobs/view/<id>. Get one from /discover/opportunities or /organization/opportunities."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/opportunity/by-person":{"get":{"tags":["Live API - Opportunity"],"summary":"Get opportunities posted by a person","description":"Postings where this person is on the hiring team.\n\nA reverse lookup over jobs already fetched, because LinkedIn publishes no\n\"jobs posted by X\" page. So this answers \"which postings we hold name this\nperson\", which grows with the corpus rather than describing everything they\nhave ever posted - the same shape as the employees endpoint.","operationId":"by_person_api_v2_opportunity_by_person_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"personEntityId","in":"query","required":true,"schema":{"type":"string","description":"The poster's ACoAA... token","title":"Personentityid"},"description":"The poster's ACoAA... token"},{"name":"count","in":"query","required":false,"schema":{"type":"integer","maximum":25,"minimum":1,"description":"How many results to return in this page.","default":10,"title":"Count"},"description":"How many results to return in this page."},{"name":"start","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Zero-based offset into the result set. An alternative to cursor; both describe the same position.","default":0,"title":"Start"},"description":"Zero-based offset into the result set. An alternative to cursor; both describe the same position."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/organization/resolve-slug":{"get":{"tags":["Live API - Organization"],"summary":"Resolve a slug to an organization id","description":"Turn a public slug into the numeric id the other endpoints want.\n\nCosts a fetch the first time and nothing afterwards.","operationId":"resolve_slug_api_v2_organization_resolve_slug_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"slug","in":"query","required":true,"schema":{"type":"string","description":"The segment after /company/","title":"Slug"},"description":"The segment after /company/"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/organization/enrich":{"get":{"tags":["Live API - Organization"],"summary":"Enrich an organization (full profile)","description":"The complete company record for a numeric id.","operationId":"enrich_api_v2_organization_enrich_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"id","in":"query","required":true,"schema":{"type":"string","description":"The numeric organization id","title":"Id"},"description":"The numeric organization id"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/organization/headcount":{"get":{"tags":["Live API - Organization"],"summary":"Get organization headcount data","description":"Employee count and the size bucket LinkedIn publishes.\n\nThe per-function distribution the contract mentions is not here: LinkedIn\nputs it behind Sales Navigator's insights, not on the public page, so\nreporting it would mean inventing it.","operationId":"headcount_api_v2_organization_headcount_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"id","in":"query","required":true,"schema":{"type":"string","description":"The organization's numeric LinkedIn page id, e.g. 1000000002. Get one from /organization/resolve-slug. This is the same id a person's positions carry, so it can be passed straight across.","title":"Id"},"description":"The organization's numeric LinkedIn page id, e.g. 1000000002. Get one from /organization/resolve-slug. This is the same id a person's positions carry, so it can be passed straight across."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/organization/similar":{"get":{"tags":["Live API - Organization"],"summary":"Get similar organizations","description":"Companies LinkedIn shows beside this one - its peer rail.","operationId":"similar_api_v2_organization_similar_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"id","in":"query","required":true,"schema":{"type":"string","description":"The organization's numeric LinkedIn page id, e.g. 1000000002. Get one from /organization/resolve-slug. This is the same id a person's positions carry, so it can be passed straight across.","title":"Id"},"description":"The organization's numeric LinkedIn page id, e.g. 1000000002. Get one from /organization/resolve-slug. This is the same id a person's positions carry, so it can be passed straight across."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/organization/affiliated":{"get":{"tags":["Live API - Organization"],"summary":"Get affiliated pages","description":"Subsidiaries, regional pages and showcase pages.\n\nMost companies have none, so an empty list is the ordinary answer - the\ntwo kinds are reported separately because LinkedIn treats them as\ndifferent things.","operationId":"affiliated_api_v2_organization_affiliated_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"id","in":"query","required":true,"schema":{"type":"string","description":"The organization's numeric LinkedIn page id, e.g. 1000000002. Get one from /organization/resolve-slug. This is the same id a person's positions carry, so it can be passed straight across.","title":"Id"},"description":"The organization's numeric LinkedIn page id, e.g. 1000000002. Get one from /organization/resolve-slug. This is the same id a person's positions carry, so it can be passed straight across."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/organization/activities":{"get":{"tags":["Live API - Organization"],"summary":"Get an organization's activity (posts)","description":"A company's recent posts, from the 24-hour activity cache.\n\nPaging is free after the first fetch: the whole feed is stored and paged\nlocally, as it is for a person.","operationId":"activities_api_v2_organization_activities_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"id","in":"query","required":true,"schema":{"type":"string","description":"The organization's numeric LinkedIn page id, e.g. 1000000002. Get one from /organization/resolve-slug. This is the same id a person's positions carry, so it can be passed straight across.","title":"Id"},"description":"The organization's numeric LinkedIn page id, e.g. 1000000002. Get one from /organization/resolve-slug. This is the same id a person's positions carry, so it can be passed straight across."},{"name":"start","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Zero-based offset into the result set. An alternative to cursor; both describe the same position.","default":0,"title":"Start"},"description":"Zero-based offset into the result set. An alternative to cursor; both describe the same position."},{"name":"count","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"How many results to return in this page.","default":25,"title":"Count"},"description":"How many results to return in this page."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/organization/opportunities":{"get":{"tags":["Live API - Organization"],"summary":"Get an organization's opportunities (jobs)","description":"Open postings across one or more organizations.\n\nEach company costs its own navigation, so several ids in one call is\nseveral fetches - the convenience is in the single response, not in a\ncheaper query.","operationId":"opportunities_api_v2_organization_opportunities_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"organizationEntityIds","in":"query","required":true,"schema":{"type":"string","description":"Comma-separated ids","title":"Organizationentityids"},"description":"Comma-separated ids"},{"name":"start","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Zero-based offset into the result set. An alternative to cursor; both describe the same position.","default":0,"title":"Start"},"description":"Zero-based offset into the result set. An alternative to cursor; both describe the same position."},{"name":"count","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"How many results to return in this page.","default":25,"title":"Count"},"description":"How many results to return in this page."},{"name":"refresh","in":"query","required":false,"schema":{"type":"boolean","description":"Skip the cache and fetch now","default":false,"title":"Refresh"},"description":"Skip the cache and fetch now"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/organization/batch/enrich":{"post":{"tags":["Live API - Organization"],"summary":"Submit a batch organization-enrich job","description":"Enrich a list of organizations in the background.\n\nThe batch form of `enrich`: accepts numeric ids and slugs, returns at once\nwith a job token, and resolves them one at a time behind the request. One\ncredit per organization that resolves; a not-found is free; submitting and\npolling are free.","operationId":"submit_batch_api_v2_organization_batch_enrich_post","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchEnrichRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Live API - Organization"],"summary":"Track a batch job and stream its results","description":"Job progress plus the next page of resolved organizations.\n\nA token from the person batch endpoint returns 404 here: it is a different\njob, and answering it in this shape would be worse than not answering.","operationId":"track_batch_api_v2_organization_batch_enrich_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"job_id","in":"query","required":true,"schema":{"type":"string","description":"The token returned by the POST","title":"Job Id"},"description":"The token returned by the POST"},{"name":"after","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"How many results you have already taken. Start at 0, then pass back the next_cursor from your previous poll to receive only what is new.","default":0,"title":"After"},"description":"How many results you have already taken. Start at 0, then pass back the next_cursor from your previous poll to receive only what is new."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/organization/batch/jobs":{"get":{"tags":["Live API - Organization"],"summary":"List your batch jobs","description":"Every organization batch job this key's account has submitted, newest first,\nwith its token - for when the 202 was not kept. Free. Jobs are deleted\nsix hours after submission, so this is a recent-history view, not an\narchive.","operationId":"jobs_api_v2_organization_batch_jobs_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(processing|completed|stopped_no_credits)$"},{"type":"null"}],"description":"Only jobs in this state. Omit for all.","title":"Status"},"description":"Only jobs in this state. Omit for all."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/discover/people":{"get":{"tags":["Live API - Discover"],"summary":"Discover people","description":"Search people by keyword and structured filters.\n\nCached: a miss fetches and stores the deepest set, so a later page of the\nsame query is a read rather than a second search.","operationId":"discover_people_api_v2_discover_people_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"keyword","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Free-text search term.","title":"Keyword"},"description":"Free-text search term."},{"name":"firstName","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated first names. Combine with lastName to identify one person.","title":"Firstname"},"description":"Comma-separated first names. Combine with lastName to identify one person."},{"name":"lastName","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated last names.","title":"Lastname"},"description":"Comma-separated last names."},{"name":"title","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Job title across a person's positions. Partial and typo-tolerant. Combine with organization_slugs and current_only=true to find who holds a role at a company today.","title":"Title"},"description":"Job title across a person's positions. Partial and typo-tolerant. Combine with organization_slugs and current_only=true to find who holds a role at a company today."},{"name":"currentCompany","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Organization id(s)","title":"Currentcompany"},"description":"Organization id(s)"},{"name":"pastCompany","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated organization ids for former employers: alumni and ex-employee sourcing.","title":"Pastcompany"},"description":"Comma-separated organization ids for former employers: alumni and ex-employee sourcing."},{"name":"school","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated school ids.","title":"School"},"description":"Comma-separated school ids."},{"name":"industry","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated industries. Partial match.","title":"Industry"},"description":"Comma-separated industries. Partial match."},{"name":"geoEntityId","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated LinkedIn geo ids for the headquarters.","title":"Geoentityid"},"description":"Comma-separated LinkedIn geo ids for the headquarters."},{"name":"profileLanguage","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated language codes, e.g. en. The language a profile is written in.","title":"Profilelanguage"},"description":"Comma-separated language codes, e.g. en. The language a profile is written in."},{"name":"count","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"How many results to return in this page.","default":20,"title":"Count"},"description":"How many results to return in this page."},{"name":"start","in":"query","required":false,"schema":{"type":"integer","maximum":999,"minimum":0,"description":"Zero-based offset into the result set. An alternative to cursor; both describe the same position.","default":0,"title":"Start"},"description":"Zero-based offset into the result set. An alternative to cursor; both describe the same position."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/discover/organizations":{"get":{"tags":["Live API - Discover"],"summary":"Discover organizations","description":"Search companies by keyword, size, industry and headquarters.\n\nCached for a week: which companies match \"cloud security\" is not a question\nwhose answer moves hour to hour.","operationId":"discover_organizations_api_v2_discover_organizations_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"keyword","in":"query","required":true,"schema":{"type":"string","minLength":1,"description":"Free-text search term.","title":"Keyword"},"description":"Free-text search term."},{"name":"headcountRange","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated size buckets: 1-10, 11-50, 51-200, 201-500, 501-1000, 1001-5000, 5001-10000, 10001+.","title":"Headcountrange"},"description":"Comma-separated size buckets: 1-10, 11-50, 51-200, 201-500, 501-1000, 1001-5000, 5001-10000, 10001+."},{"name":"industry","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated industries. Partial match.","title":"Industry"},"description":"Comma-separated industries. Partial match."},{"name":"geoEntityId","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated LinkedIn geo ids for the headquarters.","title":"Geoentityid"},"description":"Comma-separated LinkedIn geo ids for the headquarters."},{"name":"count","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"How many results to return in this page.","default":25,"title":"Count"},"description":"How many results to return in this page."},{"name":"start","in":"query","required":false,"schema":{"type":"integer","maximum":999,"minimum":0,"description":"Zero-based offset into the result set. An alternative to cursor; both describe the same position.","default":0,"title":"Start"},"description":"Zero-based offset into the result set. An alternative to cursor; both describe the same position."},{"name":"refresh","in":"query","required":false,"schema":{"type":"boolean","description":"Skip the cache and fetch now","default":false,"title":"Refresh"},"description":"Skip the cache and fetch now"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/discover/opportunities":{"get":{"tags":["Live API - Discover"],"summary":"Discover opportunities (jobs)","description":"Search jobs by keyword and filters.\n\nCached for six hours - except when the query is time-scoped. Yesterday's\nanswer to \"posted in the last 24 hours\" is wrong rather than stale, and so\nis a recency sort served from a cache, so those two go straight to\nLinkedIn every time. Everything else pages from one fetch.","operationId":"discover_opportunities_api_v2_discover_opportunities_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"keyword","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Free-text search term.","title":"Keyword"},"description":"Free-text search term."},{"name":"sortBy","in":"query","required":false,"schema":{"type":"string","pattern":"^(relevance|date_posted)$","description":"Result order. relevance is LinkedIn's own ranking; date_posted puts the newest first.","default":"relevance","title":"Sortby"},"description":"Result order. relevance is LinkedIn's own ranking; date_posted puts the newest first."},{"name":"datePosted","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(24h|1week|1month)$"},{"type":"null"}],"description":"Restrict to postings from the last 24h, 1week or 1month. A time-scoped search is never served from cache: a stale answer to it would be wrong rather than merely old.","title":"Dateposted"},"description":"Restrict to postings from the last 24h, 1week or 1month. A time-scoped search is never served from cache: a stale answer to it would be wrong rather than merely old."},{"name":"experience","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated seniority levels: internship, entry_level, associate, mid_senior, director, executive.","title":"Experience"},"description":"Comma-separated seniority levels: internship, entry_level, associate, mid_senior, director, executive."},{"name":"jobTypes","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated employment types: full_time, part_time, contract, temporary, internship, volunteer, other.","title":"Jobtypes"},"description":"Comma-separated employment types: full_time, part_time, contract, temporary, internship, volunteer, other."},{"name":"workplaceTypes","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated: onsite, remote, hybrid.","title":"Workplacetypes"},"description":"Comma-separated: onsite, remote, hybrid."},{"name":"companies","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated organization ids. Get one from /organization/resolve-slug.","title":"Companies"},"description":"Comma-separated organization ids. Get one from /organization/resolve-slug."},{"name":"industries","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated industry names. Partial match against the industry line on the company page.","title":"Industries"},"description":"Comma-separated industry names. Partial match against the industry line on the company page."},{"name":"locations","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated LinkedIn geo ids. Only the first is used: LinkedIn's job search takes a single geo, and sending several returns results for none of them.","title":"Locations"},"description":"Comma-separated LinkedIn geo ids. Only the first is used: LinkedIn's job search takes a single geo, and sending several returns results for none of them."},{"name":"functions","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated LinkedIn job-function codes.","title":"Functions"},"description":"Comma-separated LinkedIn job-function codes."},{"name":"titles","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated LinkedIn title ids.","title":"Titles"},"description":"Comma-separated LinkedIn title ids."},{"name":"easyApply","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"true returns only postings that can be applied to without leaving LinkedIn.","title":"Easyapply"},"description":"true returns only postings that can be applied to without leaving LinkedIn."},{"name":"verifiedJob","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"true returns only postings LinkedIn has verified.","title":"Verifiedjob"},"description":"true returns only postings LinkedIn has verified."},{"name":"count","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"How many results to return in this page.","default":25,"title":"Count"},"description":"How many results to return in this page."},{"name":"start","in":"query","required":false,"schema":{"type":"integer","maximum":999,"minimum":0,"description":"Zero-based offset into the result set. An alternative to cursor; both describe the same position.","default":0,"title":"Start"},"description":"Zero-based offset into the result set. An alternative to cursor; both describe the same position."},{"name":"refresh","in":"query","required":false,"schema":{"type":"boolean","description":"Skip the cache and fetch now","default":false,"title":"Refresh"},"description":"Skip the cache and fetch now"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/contact/email":{"get":{"tags":["Live API - Contact"],"summary":"Find a work email from a name and company domain","description":"Work out the most likely work email for someone, and say how sure it is.\n\nCompany mail follows a house pattern, so this builds the addresses that\npattern could produce for the name given (`first.last@`, `flast@`,\n`first@`, and so on) and asks the domain's mail server which of them it\nwill accept. The conversation stops one command short of sending: no\nmessage is delivered, and the person is not contacted.\n\n**The employer comes from you, and `employment` says whether anything\nsupports it.** This endpoint builds an address at the domain you name; it\ncannot know on its own that the person works there. So `confidence_score`\nanswers \"is this the right shape for an address at this domain\", and\n`employment.status` answers \"is this person even at this domain\":\n\n* `confirmed` - an address is on file for them there.\n* `contradicted` - they are on file at a different employer. The score is\n  capped hard, because a well-shaped address for the wrong company looks\n  exactly like a good answer otherwise.\n* `unknown` - nothing on file either way. The score is capped below the\n  high band: the address is what somebody at that domain would have, and\n  it assumes they are there.\n\n**Read `status` before using the address.**\n\n* `valid` - the mail server accepted this address and rejected one that\n  cannot exist, so it is discriminating between real and fake recipients.\n  This is the only status that means the mailbox was confirmed.\n* `catch_all` - the domain accepted an address made of random hex, so it\n  accepts everything. The address returned is the most common pattern and\n  is unconfirmed.\n* `unverifiable` - the question could not be asked, or the answer means\n  nothing. Outbound port 25 blocked, greylisting, or a provider such as\n  Microsoft 365 that answers 250 for every recipient. `reason` says which.\n* `invalid` - every candidate was rejected, or the domain has no MX record\n  at all and cannot receive mail.\n\n`confidence` compresses that to `high`, `low`, `guess` or `none` for\ncallers who want one field rather than four.\n\nThe store is checked after the probe, not before: a stored address is a\nfact about when it was scraped, and somebody who has since changed jobs\nstill has their old address on file. Anything found there comes back under\n`stored`, and becomes the primary answer only when the probe could not\nproduce a verified one.","operationId":"find_work_email_api_v2_contact_email_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"first_name","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":60,"description":"The person's given name, such as Jane. Accents are folded to ASCII and honorifics (Dr., Prof.) are stripped, so pass it as written on their profile.","title":"First Name"},"description":"The person's given name, such as Jane. Accents are folded to ASCII and honorifics (Dr., Prof.) are stripped, so pass it as written on their profile."},{"name":"last_name","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":60,"description":"The person's family name, such as Doe. Hyphenated names are kept whole (muller-schmidt), and post-nominals (PhD, Jr.) are stripped.","title":"Last Name"},"description":"The person's family name, such as Doe. Hyphenated names are kept whole (muller-schmidt), and post-nominals (PhD, Jr.) are stripped."},{"name":"domain","in":"query","required":true,"schema":{"type":"string","minLength":4,"maxLength":253,"pattern":"^[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*\\.[A-Za-z]{2,}$","description":"The employer's mail domain, such as example.com. This is the domain their email is on, which is often not the domain their website is on - check the MX record if unsure. Do not pass a LinkedIn slug or a full URL.","title":"Domain"},"description":"The employer's mail domain, such as example.com. This is the domain their email is on, which is often not the domain their website is on - check the MX record if unsure. Do not pass a LinkedIn slug or a full URL."},{"name":"verify","in":"query","required":false,"schema":{"type":"boolean","description":"true asks the receiving mail server whether each candidate exists, which is what separates a verified address from a guess. false skips the network entirely and returns the most common pattern, which is fast and free but unconfirmed.","default":true,"title":"Verify"},"description":"true asks the receiving mail server whether each candidate exists, which is what separates a verified address from a guess. false skips the network entirely and returns the most common pattern, which is fast and free but unconfirmed."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/contact/phone":{"get":{"tags":["Live API - Contact"],"summary":"Find a phone number from a name and company domain","description":"Phone numbers held for a person.\n\n**Unlike the email endpoint, this cannot guess.** An email address is\nderivable - companies use a house pattern, so `first.last@domain` is a\nreasonable inference from a name. A phone number has no such structure:\nthere is no function from a name to a number, so this returns what is on\nfile or nothing at all. A `null` here means \"not held\", never \"does not\nexist\".\n\nNumbers come back in E.164 (`+15555550100`) regardless of how they were\nwritten at the source, so they are directly dialable and comparable. A\ncontact can hold more than one, in which case all are returned in the\norder they were recorded.\n\nWhen several people share a name, pass `domain` to disambiguate. Without\nit every match is returned and `matches` tells you how many there were -\ntreat a result with more than one match as ambiguous rather than picking\nthe first.","operationId":"find_phone_api_v2_contact_phone_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"full_name","in":"query","required":true,"schema":{"type":"string","minLength":3,"maxLength":120,"description":"The person's full name, as it appears on their profile. Matched case-insensitively against stored contacts after whitespace is collapsed.","title":"Full Name"},"description":"The person's full name, as it appears on their profile. Matched case-insensitively against stored contacts after whitespace is collapsed."},{"name":"domain","in":"query","required":false,"schema":{"type":"string","minLength":4,"maxLength":253,"pattern":"^[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*\\.[A-Za-z]{2,}$","description":"The employer's domain, used to pick the right person when several share a name. Matched against both the contact's email domain and their employer's website host. Optional: omit it to search on name alone and read the organization on each match.","title":"Domain"},"description":"The employer's domain, used to pick the right person when several share a name. Matched against both the contact's email domain and their employer's website host. Optional: omit it to search on name alone and read the organization on each match."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/contact/reverse/email":{"get":{"tags":["Live API - Contact"],"summary":"Find the person behind an email address","description":"Who an email address belongs to.\n\nA store lookup, not a live one: it answers from contacts already held and\nnever reaches out to verify. An address we do not hold returns `found:\nfalse` - which means it is not in this store, and says nothing about\nwhether the address is real or who owns it.\n\n`is_free_provider` marks gmail, yahoo and the like. A personal address\ntells you far less about somebody's employer than a work address does, and\na caller routing on the organization should check this before trusting it.","operationId":"reverse_email_api_v2_contact_reverse_email_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string","minLength":5,"maxLength":254,"description":"The address to look up. Case and surrounding whitespace are ignored; it is normalised before matching, so Jane.Doe@Example.com and jane.doe@example.com are the same query.","title":"Email"},"description":"The address to look up. Case and surrounding whitespace are ignored; it is normalised before matching, so Jane.Doe@Example.com and jane.doe@example.com are the same query."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/contact/reverse/phone":{"get":{"tags":["Live API - Contact"],"summary":"Find the person behind a phone number","description":"Who a phone number belongs to.\n\nA store lookup over the numbers held against contacts. Both sides are\nnormalised to E.164 first, so the format the caller happens to use does\nnot decide whether there is a match - which is the usual reason a reverse\nlookup wrongly reports nothing.\n\nOne number can return more than one person: shared switchboards and\ncompany main lines are recorded against everyone who listed them. All\nmatches are returned rather than an arbitrary first, and `matches` says\nhow many there were.","operationId":"reverse_phone_api_v2_contact_reverse_phone_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"phone","in":"query","required":true,"schema":{"type":"string","minLength":7,"maxLength":32,"description":"The number to look up, in any format. (555) 555-0100, 555-555-0100 and +15555550100 are the same query: it is converted to E.164 before matching. A ten-digit number with no country code is read as North American.","title":"Phone"},"description":"The number to look up, in any format. (555) 555-0100, 555-555-0100 and +15555550100 are the same query: it is converted to E.164 before matching. A ten-digit number with no country code is read as North American."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/contact/known":{"post":{"tags":["Live API - Contact"],"summary":"Teach the finder an address you know is real","description":"Record an address you know to be correct, and teach the domain's pattern.\n\nThis is the only thing that fixes a domain nothing else can reach. Two\ncases defeat every other method:\n\n* **Nothing is held at the domain.** The finder falls back to how the\n  whole population writes addresses, and the population is not this\n  company. A domain using `first.last` gets guessed as `flast`, because\n  `flast` is what 46% of addresses look like overall.\n* **The domain is catch-all.** Its mail server accepts every recipient,\n  including addresses made of random hex, so probing cannot tell a real\n  mailbox from an invented one. Verification returns `catch_all` and\n  nothing is learned.\n\nOne confirmed address settles both. Two scraped addresses are normally\nneeded before a pattern is trusted - one could be a coincidence, somebody\nwhose name happens to fit another template - but an address a person\nasserts is real is different evidence, so a single one is enough, and it\ntakes precedence over scraped addresses at the same domain.\n\nThe effect is not limited to this person. Recording one address teaches\nthe pattern for **everybody** at that domain, so the next lookup there is\nscored on company evidence rather than a population average.","operationId":"submit_known_email_api_v2_contact_known_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KnownEmail"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"ApiKey":[]},{"HTTPBearer":[]}]}},"/api/v2/watchlist":{"post":{"tags":["Watchlist"],"summary":"Watch Add","description":"Start watching an entity.\n\nIdempotent - re-posting the same URL reactivates it and updates the\ninterval rather than creating a duplicate. The first poll only captures a\nbaseline; changes are reported from the second onwards.","operationId":"watch_add_api_v2_watchlist_post","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WatchEntry"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Watchlist"],"summary":"Watch List","description":"Everything you are watching, oldest first.\n\nScoped to the key that calls it. An operator key, which has no owner, sees\nevery entry regardless of who added it.","operationId":"watch_list_api_v2_watchlist_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"include_inactive","in":"query","required":false,"schema":{"type":"boolean","description":"Include entities removed from the watchlist. Their change history is kept, so this shows what was once watched.","default":false,"title":"Include Inactive"},"description":"Include entities removed from the watchlist. Their change history is kept, so this shows what was once watched."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WatchEntry"},"title":"Response Watch List Api V2 Watchlist Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Watchlist"],"summary":"Watch Remove","description":"Stop watching one entity, or empty the watchlist.\n\nDeactivates rather than deletes: the recorded changes are the valuable\npart and dropping the entries would orphan them. Re-adding any URL later\nreactivates it with its history intact, so this is reversible.\n\nPass `url` to stop one, or `clear=true` to stop all. Passing neither is an\nerror rather than a no-op, and passing both is an error rather than a\nguess at which was meant.\n\n**Costs nothing.** Charging to stop spending quota is backwards - the\nincentive should run towards tidying up a watchlist, not away from it.\n\nScoped to your key: `clear=true` empties your own watchlist, not anybody\nelse's. An operator key, which has no owner, is the exception and clears\neverything.","operationId":"watch_remove_api_v2_watchlist_delete","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"url","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The LinkedIn profile or company URL of the entity to stop watching. Omit it and pass clear=true to empty the whole watchlist instead.","title":"Url"},"description":"The LinkedIn profile or company URL of the entity to stop watching. Omit it and pass clear=true to empty the whole watchlist instead."},{"name":"clear","in":"query","required":false,"schema":{"type":"boolean","description":"true stops watching everything you are watching. Required explicitly: a DELETE that emptied the watchlist merely because a url was left off would turn a mistyped request into a wiped list. Recorded changes are kept either way.","default":false,"title":"Clear"},"description":"true stops watching everything you are watching. Required explicitly: a DELETE that emptied the watchlist merely because a url was left off would turn a mistyped request into a wiped list. Recorded changes are kept either way."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Watch Remove Api V2 Watchlist Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/watchlist/changes":{"get":{"tags":["Watchlist"],"summary":"Watch Changes","description":"Recorded changes, newest first.","operationId":"watch_changes_api_v2_watchlist_changes_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"url","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"History for one entity","title":"Url"},"description":"History for one entity"},{"name":"jobs_only","in":"query","required":false,"schema":{"type":"boolean","description":"Only moves between employers","default":false,"title":"Jobs Only"},"description":"Only moves between employers"},{"name":"posts_only","in":"query","required":false,"schema":{"type":"boolean","description":"Only newly published posts","default":false,"title":"Posts Only"},"description":"Only newly published posts"},{"name":"contacts_only","in":"query","required":false,"schema":{"type":"boolean","description":"Only where an email or phone became visible","default":false,"title":"Contacts Only"},"description":"Only where an email or phone became visible"},{"name":"source","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"profile or activity","title":"Source"},"description":"profile or activity"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"How many results to return in this page.","default":25,"title":"Limit"},"description":"How many results to return in this page."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ChangeSet"},"title":"Response Watch Changes Api V2 Watchlist Changes Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/watchlist/subscribers":{"post":{"tags":["Watchlist"],"summary":"Email watchlist changes to an address","description":"Send an address the changes detected on your watchlist.\n\nEvery poll that finds something emails the people listening to that\nentity. The mail names what moved - a headline edit, a new position, a\npublished post - and links back to the full change log.\n\n**An address receives nothing until it is confirmed.** Anyone can be typed\ninto this endpoint, so a mistyped address would otherwise be mailed on the\nnext poll - somebody who never asked, about people they have never heard\nof. Your own account address is confirmed on sight. Any other address\nstarts pending and is sent nothing at all, not even a confirmation, unless\nyou pass `send_confirmation=true`; otherwise the link comes back to you to\npass on however you already talk to that person.\n\nIdempotent on the address: subscribing twice updates the subscription\nrather than sending everything twice.\n\nEach email carries an unsubscribe link that works without signing in. A\nnotification nobody can stop is a complaint waiting to happen, and in most\njurisdictions a legal problem.\n\nCosts 2 credits. The polling it causes is billed separately, per entity,\nwhen a poll actually runs.","operationId":"subscribe_api_v2_watchlist_subscribers_post","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscribeRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Subscribe Api V2 Watchlist Subscribers Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Watchlist"],"summary":"Who is being emailed","description":"Addresses receiving your watchlist's changes.","operationId":"list_subscribers_api_v2_watchlist_subscribers_get","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true},"title":"Response List Subscribers Api V2 Watchlist Subscribers Get"}}}}}},"delete":{"tags":["Watchlist"],"summary":"Stop emailing an address","description":"Stop notifications to one address. Costs nothing, like any other stop.","operationId":"unsubscribe_address_api_v2_watchlist_subscribers_delete","security":[{"ApiKey":[]},{"HTTPBearer":[]}],"parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string","description":"The address to stop emailing.","title":"Email"},"description":"The address to stop emailing."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Unsubscribe Address Api V2 Watchlist Subscribers Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/watchlist/confirm":{"get":{"tags":["Watchlist"],"summary":"Confirm a subscription","description":"Start receiving watchlist changes at this address.\n\nPublic, for the same reason unsubscribing is: the person confirming owns\nthe inbox, not necessarily an API key.","operationId":"confirm_subscription_api_v2_watchlist_confirm_get","parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string","description":"The token from a confirmation link.","title":"Token"},"description":"The token from a confirmation link."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Confirm Subscription Api V2 Watchlist Confirm Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/watchlist/unsubscribe":{"get":{"tags":["Watchlist"],"summary":"Unsubscribe from an emailed link","description":"Stop notifications using the link in the email.\n\nOn a router without the API key requirement, because the person who wants\nthe mail to stop is often not the person who holds a key.","operationId":"unsubscribe_by_token_api_v2_watchlist_unsubscribe_get","parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string","description":"The token from the unsubscribe link in a notification email.","title":"Token"},"description":"The token from the unsubscribe link in a notification email."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Unsubscribe By Token Api V2 Watchlist Unsubscribe Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/auth/signup":{"post":{"tags":["Accounts"],"summary":"Not open (invitation only)","description":"Accounts are created by invitation.\n\nKept as an endpoint rather than removed so that anything still pointed at\nit gets an explanation instead of a 404, which reads as a broken service\nrather than a closed one.","operationId":"signup_api_v2_auth_signup_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Credentials"}}},"required":true},"responses":{"403":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Signup Api V2 Auth Signup Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/auth/waitlist":{"post":{"tags":["Accounts"],"summary":"Join the waitlist","description":"Register interest while access is invitation-only.\n\nPublic and free: no account is created and nothing is charged - an\ninvitation is sent by hand later. The address is the key: joining again\nkeeps the original position but refreshes the answers, so someone who comes\nback with more to say is not turned away or duplicated.","operationId":"join_waitlist_api_v2_auth_waitlist_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaitlistJoin"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Join Waitlist Api V2 Auth Waitlist Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/auth/invite":{"get":{"tags":["Accounts"],"summary":"What an invitation is for","description":"The address an invitation was issued to, so a form can show it.\n\nDoes not consume the invitation - somebody opening the link, thinking\nbetter of it and returning tomorrow should still be able to use it.\nPublic, because the person holding it has no account yet.","operationId":"read_invite_api_v2_auth_invite_get","parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string","description":"The token from an invitation link.","title":"Token"},"description":"The token from an invitation link."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Read Invite Api V2 Auth Invite Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/auth/accept-invite":{"post":{"tags":["Accounts"],"summary":"Create an account from an invitation","description":"Create the account, and sign the person in.\n\nNo separate confirmation step. Receiving the invitation already proves\ncontrol of the address, and asking somebody to confirm an address we have\njust successfully mailed is asking them to prove the same thing twice.\n\nThe email comes from the invitation rather than from the request, so\naccepting one cannot create an account for a different address.","operationId":"accept_invite_api_v2_auth_accept_invite_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptInvite"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Accept Invite Api V2 Auth Accept Invite Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/auth/signin":{"post":{"tags":["Accounts"],"summary":"Sign in","description":"Exchange email and password for a short-lived session token.","operationId":"signin_api_v2_auth_signin_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Credentials"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Signin Api V2 Auth Signin Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/auth/credits":{"get":{"tags":["Accounts"],"summary":"Your credit balance","description":"What is left, and what a call costs.\n\nFree to read: an exhausted account still needs to be able to see that\nthat is what happened.","operationId":"read_credits_api_v2_auth_credits_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Read Credits Api V2 Auth Credits Get"}}}}},"security":[{"SessionToken":[]},{"ApiKey":[]}]}},"/api/v2/auth/me":{"get":{"tags":["Accounts"],"summary":"Who you are signed in as","description":"The signed-in account, its balance, and whether it may grant credits.\n\nOne call rather than three, because the interface needs all of it on load\nand a page that makes three requests to draw a header is a page that\nflickers.","operationId":"whoami_api_v2_auth_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Whoami Api V2 Auth Me Get"}}}}},"security":[{"SessionToken":[]},{"ApiKey":[]}]}},"/api/v2/auth/credits/history":{"get":{"tags":["Accounts"],"summary":"What your credits went on","description":"Every credit movement on this account, newest first.\n\nA balance on its own cannot answer the question people actually ask when\nit drops, which is not \"how much is left\" but \"what is eating this\". Each\nentry records the endpoint, what it cost, and the balance afterwards, so a\ntotal can be traced back to the calls that produced it.\n\nFree to read, like the balance itself.","operationId":"credit_history_api_v2_auth_credits_history_get","security":[{"SessionToken":[]},{"ApiKey":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"How many entries to return, most recent first.","default":50,"title":"Limit"},"description":"How many entries to return, most recent first."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Credit History Api V2 Auth Credits History Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/auth/credits/breakdown":{"get":{"tags":["Accounts"],"summary":"Where your credits go","description":"Spending grouped by endpoint, dearest first.\n\nThe list in `/credits/history` stops being readable once it is longer than\na screen. This answers the same question at the level somebody can act on:\nwhich endpoint to call less.","operationId":"credit_breakdown_api_v2_auth_credits_breakdown_get","security":[{"SessionToken":[]},{"ApiKey":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"description":"How far back to look.","default":30,"title":"Days"},"description":"How far back to look."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Credit Breakdown Api V2 Auth Credits Breakdown Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/auth/credits/grant":{"post":{"tags":["Accounts"],"summary":"Add credits to an account","description":"Top up an account. Administrators only.\n\nTwo ways to be one, because there are two kinds of caller. A script holds\nan operator key - a key issued to the service rather than to a customer,\nrecognisable by having no owner. A person uses the interface, which\nauthenticates with a session, so an account marked `admin` may grant too.\n\nAn ordinary account cannot grant, including to itself. A balance anybody\ncan refill on their own behalf is a counter rather than a limit.\n\nRecorded on the account's history like any other movement.","operationId":"grant_credits_api_v2_auth_credits_grant_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Grant"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Grant Credits Api V2 Auth Credits Grant Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/auth/credits/request":{"post":{"tags":["Accounts"],"summary":"Ask for more credits","description":"Ask for a top-up.\n\nRecords the request rather than granting it. Asking twice updates the\nrequest instead of adding a second one, so a queue never fills with one\nimpatient person.\n\nFree, and deliberately so: an account with no credits left still has to be\nable to ask for more.","operationId":"ask_for_credits_api_v2_auth_credits_request_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopUpRequest"}}},"required":true},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Ask For Credits Api V2 Auth Credits Request Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SessionToken":[]}]}},"/api/v2/auth/credits/requests":{"get":{"tags":["Accounts"],"summary":"Top-up requests awaiting a decision","description":"Open requests, oldest first. Administrators only.","operationId":"list_requests_api_v2_auth_credits_requests_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response List Requests Api V2 Auth Credits Requests Get"}}}}}}},"/api/v2/auth/keys":{"get":{"tags":["Accounts"],"summary":"List your API keys","description":"Hints only - the keys themselves cannot be read back.","operationId":"list_keys_api_v2_auth_keys_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response List Keys Api V2 Auth Keys Get"}}}}},"security":[{"SessionToken":[]}]},"post":{"tags":["Accounts"],"summary":"Create an API key","operationId":"create_key_api_v2_auth_keys_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeyRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Create Key Api V2 Auth Keys Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SessionToken":[]}]}},"/api/v2/auth/keys/{name}":{"delete":{"tags":["Accounts"],"summary":"Revoke an API key","operationId":"revoke_key_api_v2_auth_keys__name__delete","security":[{"SessionToken":[]}],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","title":"Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Revoke Key Api V2 Auth Keys  Name  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/billing/packs":{"get":{"tags":["Billing"],"summary":"What you can buy","description":"The credit packs on offer, and whether payment is configured at all.\n\nPublic: somebody deciding whether to sign up should be able to see what\ncredits cost without having an account first.","operationId":"packs_api_v2_billing_packs_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Packs Api V2 Billing Packs Get"}}}}}}},"/api/v2/billing/checkout":{"post":{"tags":["Billing"],"summary":"Start a purchase","description":"Create a Stripe checkout session and return where to send the browser.\n\nThe price is read from the pack table here, never from the request. The\naccount is carried in the session's metadata so the webhook knows who\npaid without trusting anything the browser sends back.","operationId":"checkout_api_v2_billing_checkout_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Checkout Api V2 Billing Checkout Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SessionToken":[]}]}},"/api/v2/admin/overview":{"get":{"tags":["Admin"],"summary":"The service at a glance","description":"Accounts, usage, revenue and what the store holds.","operationId":"overview_api_v2_admin_overview_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"default":30,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Overview Api V2 Admin Overview Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/admin/accounts":{"get":{"tags":["Admin"],"summary":"Every account and what it is doing","description":"One row per account, busiest first.\n\nSpending and call counts are per window; balances and key counts are as\nthey stand now.","operationId":"accounts_api_v2_admin_accounts_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"default":30,"title":"Days"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Accounts Api V2 Admin Accounts Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/admin/account":{"get":{"tags":["Admin"],"summary":"One account in detail","description":"Everything held about one account, minus what cannot be shown.\n\nKeys appear as hints rather than keys: they are stored hashed, so even\nthis view cannot reveal one, which is the property that makes a leaked\ndatabase useless.","operationId":"account_api_v2_admin_account_get","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string","description":"The account to look at.","title":"Email"},"description":"The account to look at."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Account Api V2 Admin Account Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Admin"],"summary":"Delete an account and everything it owns","description":"Remove an account, its keys, sessions, watchlist, subscribers and history.\n\nMongo has no cascades, so deleting the account row by hand leaves the keys\nauthenticating, the sessions valid for up to twelve hours, the watchlist\nentries queued for polling and the subscribers still due an email. This\nremoves all of it in one place, which is the only way it stays consistent.\n\n**Not reversible.** Payment records are the exception and are kept:\nStripe holds its own copy regardless, and financial records are the one\ncategory somebody usually has to be able to produce later.","operationId":"delete_account_endpoint_api_v2_admin_account_delete","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string","description":"The account to delete.","title":"Email"},"description":"The account to delete."},{"name":"confirm","in":"query","required":false,"schema":{"type":"boolean","description":"Must be true. A DELETE that removed an account merely because the parameter was left off would turn a mistyped request into a deletion.","default":false,"title":"Confirm"},"description":"Must be true. A DELETE that removed an account merely because the parameter was left off would turn a mistyped request into a deletion."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Delete Account Endpoint Api V2 Admin Account Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/admin/health":{"get":{"tags":["Admin"],"summary":"The machinery","description":"Whether the parts that reach LinkedIn are working.\n\nThe navigation budget is the one number that decides whether anything can\nbe fetched at all, and it is shared across every account - so it belongs\nto the operator rather than to any customer's view.","operationId":"machinery_api_v2_admin_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Machinery Api V2 Admin Health Get"}}}}}}},"/api/v2/admin/invites":{"post":{"tags":["Admin"],"summary":"Invite somebody","description":"Create an invitation and email the link.\n\nRe-inviting an address reissues rather than duplicating, with a fresh\ntoken - so an invitation that was forwarded or leaked from an inbox stops\nworking the moment it is reissued.","operationId":"invite_api_v2_admin_invites_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invitation"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Invite Api V2 Admin Invites Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Admin"],"summary":"Invitations not yet accepted","description":"Outstanding invitations, newest first.\n\nTokens are not listed. An invitation is a way to create an account, so a\nlist of them should not be a list of ways in for whoever reads it.","operationId":"list_invites_api_v2_admin_invites_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Invites Api V2 Admin Invites Get"}}}}}},"delete":{"tags":["Admin"],"summary":"Withdraw an invitation","description":"Withdraw one that has not been accepted. Costs nothing, like any stop.","operationId":"revoke_invite_api_v2_admin_invites_delete","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string","description":"The invited address.","title":"Email"},"description":"The invited address."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Revoke Invite Api V2 Admin Invites Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/admin/waitlist":{"get":{"tags":["Admin"],"summary":"Who has asked for access","description":"The waitlist in arrival order - who to invite, and who is owed the\nearly-access bonus.\n\n`bonus` marks the first few, whose invitation should carry the larger\nstarting balance; `invited` says whether an invitation has gone out yet.","operationId":"list_waitlist_api_v2_admin_waitlist_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response List Waitlist Api V2 Admin Waitlist Get"}}}}}}},"/api/v2/rate-limit":{"get":{"tags":["Accounts"],"summary":"Your remaining scrape allowance","description":"How many new fetches (enrich, discover) you can make right now.\n\nCheap reads from the store do not count; this is the budget for calls that\ngo to LinkedIn. A client planning a bulk run should read this to size its\nbatches rather than discovering the limit by hitting a 429 mid-run.","operationId":"rate_limit_status_api_v2_rate_limit_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v2/playground/call":{"post":{"tags":["Playground"],"summary":"Run an API call as yourself","description":"Issue one request against this service using the signed-in user's key.\n\nReturns the upstream status and body verbatim, so the playground shows\nexactly what an external caller would see.","operationId":"call_api_v2_playground_call_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Call"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SessionToken":[]}]}},"/health":{"get":{"tags":["ops"],"summary":"Health","description":"Liveness, and with a key, capacity.\n\nLeft open so a monitor can watch the service without holding a credential,\nbut the detail is not public: cached-record counts and the LinkedIn account\nin use are operational facts about the business, not a status page.","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}}}}}},"components":{"schemas":{"AcceptInvite":{"properties":{"token":{"type":"string","title":"Token","description":"The token from the invitation link."},"password":{"type":"string","minLength":10,"title":"Password","description":"At least 10 characters."}},"type":"object","required":["token","password"],"title":"AcceptInvite"},"ApiResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"statusCode":{"type":"integer","title":"Statuscode","description":"Mirrors the HTTP status code"},"message":{"type":"string","title":"Message"},"errors":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Errors","description":"Always null on success; carries error_code otherwise"},"data":{"anyOf":[{},{"type":"null"}],"title":"Data","description":"Endpoint-specific payload: object, array, or null"}},"type":"object","required":["success","statusCode","message"],"title":"ApiResponse","description":"The envelope every Data API route returns."},"BatchEnrichRequest":{"properties":{"ids":{"items":{"type":"string"},"type":"array","title":"Ids","description":"Stable identifiers: an entityId (ACoAA...) or object id for a person, a numeric organization id or object id for an organization."},"handles":{"items":{"type":"string"},"type":"array","title":"Handles","description":"Public handles: the slug after /in/ for a person, after /company/ for an organization."}},"type":"object","title":"BatchEnrichRequest"},"Call":{"properties":{"method":{"type":"string","title":"Method","default":"GET"},"path":{"type":"string","title":"Path","description":"A path on this service, e.g. /api/data/v1/people/profile"},"query":{"additionalProperties":true,"type":"object","title":"Query"},"body":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Body"}},"type":"object","required":["path"],"title":"Call"},"ChangeSet":{"properties":{"entity_id":{"type":"string","title":"Entity Id"},"linkedin_url":{"type":"string","title":"Linkedin Url"},"kind":{"type":"string","title":"Kind"},"detected_at":{"title":"Detected At"},"source":{"type":"string","title":"Source","description":"profile or activity","default":"profile"},"has_job_change":{"type":"boolean","title":"Has Job Change","description":"True when someone started or left a role"},"has_new_posts":{"type":"boolean","title":"Has New Posts","default":false},"has_new_contact":{"type":"boolean","title":"Has New Contact","description":"An email or phone became visible - usually means a connection request was accepted","default":false},"count":{"type":"integer","title":"Count"},"changes":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Changes"}},"type":"object","required":["entity_id","linkedin_url","kind","detected_at","has_job_change","count","changes"],"title":"ChangeSet","description":"One poll that found something."},"CheckoutRequest":{"properties":{"pack":{"type":"string","title":"Pack","description":"Which monthly plan to subscribe to: developer, startup, growth, pro, scale."}},"type":"object","required":["pack"],"title":"CheckoutRequest"},"Credentials":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","minLength":10,"title":"Password","description":"At least 10 characters"}},"type":"object","required":["email","password"],"title":"Credentials"},"Grant":{"properties":{"email":{"type":"string","format":"email","title":"Email","description":"The account to credit."},"credits":{"type":"integer","maximum":100000.0,"minimum":-100000.0,"title":"Credits","description":"How many to add. Negative removes them."},"reason":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Reason","description":"Recorded on the account's history, so the change is not a mystery to whoever reads it later."}},"type":"object","required":["email","credits"],"title":"Grant"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"Health":{"properties":{"status":{"type":"string","title":"Status"},"mongo":{"type":"boolean","title":"Mongo"},"can_scrape":{"type":"boolean","title":"Can Scrape"},"account":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account"},"ip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ip"},"session_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Error"},"profiles_cached":{"type":"integer","title":"Profiles Cached","default":0},"companies_cached":{"type":"integer","title":"Companies Cached","default":0},"scrapes_available":{"type":"integer","title":"Scrapes Available","description":"Cache misses the service will accept before the hourly ceiling stops them","default":0},"scrapes_per_hour":{"type":"integer","title":"Scrapes Per Hour","default":0},"scrape_queue":{"type":"integer","title":"Scrape Queue","description":"Requests waiting for the browser","default":0},"scrape_queue_limit":{"type":"integer","title":"Scrape Queue Limit","default":0}},"type":"object","required":["status","mongo","can_scrape"],"title":"Health"},"Invitation":{"properties":{"email":{"type":"string","format":"email","title":"Email","description":"Who to invite."},"note":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Note","description":"A line included in the email, so the invitation does not arrive without context."},"send_email":{"type":"boolean","title":"Send Email","description":"false creates the invitation and returns the link without mailing it, for passing on another way.","default":true}},"type":"object","required":["email"],"title":"Invitation"},"KeyRequest":{"properties":{"name":{"type":"string","maxLength":60,"minLength":1,"title":"Name"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"}},"type":"object","required":["name"],"title":"KeyRequest"},"KnownEmail":{"properties":{"first_name":{"type":"string","maxLength":60,"minLength":1,"title":"First Name","description":"The person's given name, exactly as it corresponds to the address."},"last_name":{"type":"string","maxLength":60,"minLength":1,"title":"Last Name","description":"The person's family name, exactly as it corresponds to the address."},"email":{"type":"string","maxLength":254,"minLength":5,"title":"Email","description":"The address you know is real, such as Jane.Doe@example.com. Case is not significant."},"title":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Title","description":"Their job title, if you have it. Stored but not used for matching."},"organization":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Organization","description":"The employer's name, if you have it. Stored for display on lookups."}},"type":"object","required":["first_name","last_name","email"],"title":"KnownEmail","description":"An address the caller knows is real."},"SubscribeRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email","description":"Where to send change notifications. Does not need an account on this service: the person who wants to hear that somebody changed jobs is often not the person holding the API key."},"urls":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Urls","description":"Limit notifications to these entities. Omit for everything on your watchlist. Narrowing matters more than it looks - somebody tracking twelve people does not want the whole team's watchlist in their inbox."},"send_confirmation":{"type":"boolean","title":"Send Confirmation","description":"true emails the address a confirmation link. false, the default, sends them nothing and returns the link to you instead, so a mistyped address never receives mail from this service at all. Your own account address needs neither: it is confirmed on sight.","default":false}},"type":"object","required":["email"],"title":"SubscribeRequest"},"TopUpRequest":{"properties":{"credits":{"type":"integer","maximum":100000.0,"minimum":1.0,"title":"Credits","description":"How many credits you are asking for."},"note":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Note","description":"What you need them for. Read by whoever decides."}},"type":"object","required":["credits"],"title":"TopUpRequest"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"WaitlistJoin":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"role":{"type":"string","maxLength":80,"minLength":1,"title":"Role","description":"What best describes you."},"use_for":{"type":"string","maxLength":2000,"minLength":1,"title":"Use For","description":"What you'd primarily use Rynora for."},"volume":{"type":"string","maxLength":40,"minLength":1,"title":"Volume","description":"Contacts needed per month."},"current_problem":{"type":"string","maxLength":2000,"minLength":1,"title":"Current Problem","description":"The biggest problem with your current solution."},"current_tool":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Current Tool","description":"How you currently find contact/company data."},"worth_paying":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Worth Paying","description":"What would make Rynora worth paying for."},"willing_to_talk":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Willing To Talk","description":"Open to a 15-minute conversation."},"source":{"anyOf":[{"type":"string","maxLength":60},{"type":"null"}],"title":"Source","description":"Where the request came from, e.g. 'reddit'."}},"type":"object","required":["email","role","use_for","volume","current_problem"],"title":"WaitlistJoin"},"WatchEntry":{"properties":{"linkedin_url":{"type":"string","title":"Linkedin Url"},"kind":{"type":"string","title":"Kind"},"active":{"type":"boolean","title":"Active"},"poll_interval_days":{"type":"number","title":"Poll Interval Days"},"added_at":{"anyOf":[{},{"type":"null"}],"title":"Added At"},"last_checked_at":{"anyOf":[{},{"type":"null"}],"title":"Last Checked At"},"last_changed_at":{"anyOf":[{},{"type":"null"}],"title":"Last Changed At"},"next_check_at":{"anyOf":[{},{"type":"null"}],"title":"Next Check At"},"change_count":{"type":"integer","title":"Change Count","default":0},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"},"track_activity":{"type":"boolean","title":"Track Activity","default":false}},"type":"object","required":["linkedin_url","kind","active","poll_interval_days"],"title":"WatchEntry"},"WatchRequest":{"properties":{"url":{"type":"string","title":"Url","description":"Profile URL, company URL, or company slug"},"kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kind","description":"person or company; inferred if omitted"},"interval_days":{"type":"number","maximum":90.0,"minimum":0.25,"title":"Interval Days","default":1.0},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"},"track_activity":{"type":"boolean","title":"Track Activity","description":"Also record new posts. Off by default: posts appear weekly where job moves appear every few years, so tracking everyone would bury the signal. Costs 2-3 extra navigations per poll.","default":false}},"type":"object","required":["url"],"title":"WatchRequest"}},"securitySchemes":{"ApiKey":{"type":"apiKey","description":"Your lsk_... API key","in":"header","name":"X-API-Key"},"HTTPBearer":{"type":"http","description":"Same key, as Authorization: Bearer","scheme":"bearer"},"SessionToken":{"type":"apiKey","description":"Token from /api/v2/auth/signin","in":"header","name":"X-Session-Token"}}},"tags":[{"name":"Live API - Person","description":"Goes to LinkedIn now. enrich is the fetch - about nine navigations with a pause between each, so minutes rather than milliseconds - and the other five are views over what it brought back. batch/enrich is the same fetch over a list, worked through behind the request."},{"name":"Live API - Activity","description":"Posts, and the people behind their engagement counts. A feed card only renders numbers, so reactions and replies mean opening the post itself."},{"name":"Live API - Opportunity","description":"Job postings, their hiring contacts, and the rail of related roles. One fetch answers four of the five."},{"name":"Live API - Organization","description":"Companies by LinkedIn's numeric page id - the id a person's positions already carry. One fetch answers five of the seven."},{"name":"Live API - Discover","description":"Search across people, organizations and jobs. Filters carry LinkedIn's own ids and are translated into its search parameters rather than applied afterwards."},{"name":"Accounts","description":"Sign up, sign in, and manage your API keys. Read endpoints can be tried without a key; anything that reaches LinkedIn needs one."},{"name":"Watchlist","description":"Entities polled on a schedule, with every change kept."},{"name":"ops","description":"Liveness and capacity."}]}