ChangelogLast update October 4, 2026 · 58 endpoints
EnvoAPI changelog: API updates and release notes
Every change to the EnvoAPI public API, newest first. Each entry says what changed, what new endpoints cost in credits, and what to update in your code. Breaking changes are marked, with the exact fields and routes affected.
{ "data": { "email": "[email protected]", "user": "Jane Doe", "domain": "example.com", "mx": "mx.example.com", "status": "valid", "reason": "accepted", "isCatchAll": false, "isDisposable": false }, "meta": { "creditCost": 2 }}Latest new endpoint: verify an email address, 2 credits, added in contracts 51. The data is made up.
Newest first. Entries marked “Action needed” change a request or response you may already use. Open one for the exact fields.
Added A new endpoint, field or error code you can use.
Changed An existing request or response now behaves differently.
Removed A route, parameter or field that no longer works.
Fixed A defect corrected. Nothing to change on your side.
Company search returns companies without a description
CompaniesAction neededContracts 572 changes · latestCompany search no longer fails when a company card has no industry or location line. That company now comes back with a null description.
What to doTreat
descriptionin company search results as nullable, for example by hiding that line when it is null.- Changed
descriptionindata.companiesonGET /v1/companies/searchandGET /v1/companies/by-domainis nowstring | null. It is null when the company card has no industry or location line, and it is never omitted. - FixedA search that matched such a company, such as
keywords=fpt, returned500 internal_errorfor the whole page. It now returns the page.
Reference:Company searchFind by website domain
- Changed
Job search takes location and company IDs, and gains four filters
JobsAction neededContracts 55–567 changesJob search now scopes by one location ID and up to 10 company IDs. New filters cover workplace type, employment type, Easy Apply and early applicants, and each job carries the company logo.
What to doSend a
geo_ID from location search inlocation, not a place name. ReplacecompanySlugwithcompanyIds, usingdata.publicIdfrom company details.- Changed
GET /v1/jobs/searchaccepts only one location ID inlocation, such asgeo_6yITczfor United States. Get it fromGET /v1/search/locations(data.locations[].id). A place name, a raw number or several IDs return400 invalid_requestbefore any credit is used. - Removed
companySlugonGET /v1/jobs/search. Sending it returns400 invalid_request. - Added
companyIdsonGET /v1/jobs/search: up to 10 company IDs separated by commas, such ascompany_4T4tWjfor Microsoft. Jobs at any of the listed companies match. More than 10 IDs, a repeated ID or a value that is not a company ID returns400 invalid_request. - AddedFour optional filters on
GET /v1/jobs/search:employmentType(full_time,part_time,contract,temporary,volunteer,internship,other),workplaceType(on_site,remote,hybrid),easyApply=trueandunder10Applicants=true. - AddedSeveral values in one filter match any of them, such as
workplaceType=remote,hybrid. Different filters must all match. An unknown or repeated value, orfalse, returns400 invalid_request; leave a flag out to turn it off. - AddedEach job in
data.jobshascompanyLogoUrl, a protected image URL like other logo fields. It is null when the card has no logo or the logo has expired, and it is never omitted. - FixedA location ID with the right shape but outside the ID range, such as
geo_BBBBBB, now returns400 invalid_requestonGET /v1/jobs/search,GET /v1/profiles/searchandGET /v1/companies/searchinstead of a retryable500 internal_error.
Reference:Job searchLocation searchCompany details
- Changed
Disposable addresses get an answer on email verify and find
EmailAction neededContracts 544 changesEmail verify and email find now return a result for disposable mailboxes instead of a retryable error. The charge is kept.
What to doHandle the new
disposablereason wherever you switch over verification reasons.- Changed
GET /v1/emails/verifyreturnsinvalidwith the reasondisposableandisDisposable: truefor a disposable address. The charge is kept. - Changed
GET /v1/emails/findstops at the first disposable answer withnot_found, no address,isDisposable: trueand averification.reasonofdisposable. - FixedA disposable address no longer returns a retryable
503on either route. - AddedNew verification reason
disposable. If your client lists or labels reasons, add it.
Reference:Verify emailFind email
- Changed
Yahoo addresses get a clear error on email verify and find
EmailAction neededContracts 533 changesThe verification provider cannot check Yahoo mailboxes. Email verify and email find now say so with a clear error, and the credits are refunded.
What to doHandle the
email_unverifiableerror code. It is not retryable, so do not retry it.- Changed
GET /v1/emails/verifyfor an address at yahoo.*, ymail.com or rocketmail.com, andGET /v1/emails/findfor one of those domains, now return 422 with the error codeemail_unverifiable. - ChangedThe error has no
Retry-Afterheader and the credits are refunded.X-Credits-Remainingand the rate-limit headers are still sent. - AddedNew error code
email_unverifiable. If your client switches over error codes, add it.
Reference:Verify emailFind emailErrors
- Changed
Email verify, email finder and website text
Email · WebsiteContracts 516 changesCheck that a mailbox exists, find a person's work email from a name and a domain, and read the visible text of any public web page.
- Added
GET /v1/emails/verify, 2 credits. Returns onestatus(valid,invalidorunverifiable) with a stablereason, plusisCatchAllandisDisposable. - Added
GET /v1/emails/find, 10 credits. Send a first name, an optional last name and a domain. Returns astatus(found,catch_all,not_foundorno_mx), the address when one is accepted, and how many candidates were checked. A search that reaches a conclusion keeps the charge, includingcatch_all,not_foundandno_mx. - Added
GET /v1/websites/text, 2 credits. Returns the final URL, the page title and the visible text of the page, after JavaScript has run when it is needed. It uses the same fetch as website content, at the same price. - Added
503 capacity_exceededwith aRetry-Afterheader, returned when the verification provider has no capacity. The credits are refunded. - ChangedEmail results are never cached, so
metahas no cache status. Usage reports list these calls under theemailCheckendpoint. - ChangedIf your client switches over error codes or operation IDs, add the new values:
capacity_exceeded,verifyEmail,findEmailandgetWebsiteText.
Reference:Verify emailFind emailWebsite text
- Added
Website content and email discovery
WebsiteContracts 504 changesFetch the HTML of any public web page, or find the email addresses a company publishes on its website.
- Added
GET /v1/websites/content, 2 credits. Takes a public HTTP(S)url. Returns the final URL, the page title when there is one, and the HTML. - Added
GET /v1/websites/emails, 5 credits. Reads up to eight pages and stops at the first page with addresses.stopReasonexplains an empty or partial result, and the charge is kept. - ChangedUsage reports can now show
websiteLookup. If your client switches over usage endpoints or operation IDs, add the new values. - ChangedPlan catalog responses may include
websiteContentCreditsandwebsiteEmailsCredits. Profile and company prices keep their meaning.
Reference:Website contentWebsite emails
- Added
Free disposable email check
EmailContracts 481 changeCheck whether an address uses a throwaway email domain before you create an account for it.
- Added
GET /v1/emails/disposable, no credits. Checks the normalized domain only. It does not check that the mailbox exists or can receive mail.
Reference:Check disposable email
- Added
The API now sets page sizes
Pagination · SearchAction neededContracts 444 changesPage size is now fixed by the API instead of by each request. Requests that still send the old size parameters are rejected.
What to doRemove
count,limit,maxPagesandfetchAllfrom every request, even when you send the old default value.- RemovedThe
count,limit,maxPagesandfetchAllquery parameters. A request that sends any of them gets400 invalid_requestbefore any credits are charged. For example,GET /v1/profiles/search?keywords=engineer&offset=0&limit=3becomesGET /v1/profiles/search?keywords=engineer&offset=0. - ChangedPage sizes are fixed. People search, combined search and hashtag post search return 3 results per page. Other lists that used to take a size return 10. Post reactions return one provider page, with no automatic fetching of more pages.
- ChangedA cursor issued with a different page size returns
invalid_cursor. Start that chain again without a cursor. Cursors that match the new page size keep working. - Changed
offset,start,cursor, filters and sorting work as before. FollownextOffset,nextStartornextCursorwhen the response has one.countandlimitare still returned inmeta.paging.
Reference:Pagination
- RemovedThe
New API key format
API keysAction neededContracts 424 changesEvery API key now has one format. Keys issued before this release stop working, so each app has to switch to a replacement key.
What to doCopy the replacement key from your API key list in the dashboard and replace the saved key in every app that calls EnvoAPI.
- ChangedAPI keys are now
envo_followed by 66 characters, 71 in total. There is no visible version prefix. - ChangedCreating or revoking a key can return 202 with
accessDeliveryset topendingwhile the change is still being delivered. Do not assume a 202 key is usable yet or that a 202 revocation has taken effect. 201 and 200 withappliedmean the change is done. - RemovedThe per-key lookup permission. Every key on an account now has the same access.
- ChangedOld key IDs still identify past usage and audit records. Replacement keys get new IDs and keep the original names.
Reference:Authentication
- ChangedAPI keys are now
Company people and company posts get new paging
Companies · PaginationAction neededContracts 40–418 changesCompany people returns smaller records and a real total. Company posts pages with a cursor.
What to doStop sending
groupingTypeto company people, and read each person fromid,headlineandprofilePictureUrlonly.- Changed
GET /v1/companies/peopletakesslugandstart(default 0) and returns 10 people per page. It always returns the all-employees list. - ChangedEach person has only
id,headlineandprofilePictureUrl. All three are always present and can be null. - Added
meta.pagingon company people hasstart,count,totalandhasMore.totalis the provider's count of people across all pages, not the number on this page, and it can change between requests. A company with no people returnstotal0. - ChangedIf the provider gives no valid total, the lookup fails instead of returning a made-up number.
- Removed
groupingTypeon company people. Sending it now returns 400. - Added
GET /v1/companies/poststakes an optionalcursor.filteracceptsALL,IMAGES,VIDEOS,DOCUMENTSandARTICLES, and the first request can start anywhere from 0 to 10000. - Added
meta.pagingon company posts addsreturned,hasMoreandnextCursor. PassnextCursorback unchanged with the sameslugandfilter, and leavestartout. Stop whenhasMoreis false andnextCursoris null. - Added
400 invalid_cursorand400 cursor_expired, returned before any credits are charged. Start again without a cursor after one.
Reference:Company peoplePagination
- Changed
Cursor paging for profile comments and reactions
Profiles · PaginationContracts 38–395 changesPage through a profile's comments and reactions with a cursor. Each response says whether there is more and gives you the cursor for the next page.
- Added
GET /v1/profiles/commentsandGET /v1/profiles/reactionstake an optionalcursornext tousername. Responses addmeta.pagingwithcount,returned,hasMoreandnextCursor. - AddedTo get the next page, repeat the same
usernamewith thenextCursorfrom the last response, unchanged. Stop whenhasMoreis false andnextCursoris null. A cursor belongs to one account and one endpoint, and a chain lasts at most 15 minutes. - Added
400 invalid_cursorand400 cursor_expired, returned before any credits are charged. Start again without a cursor after one. - ChangedEvery successful page costs the normal lookup price, including an empty page.
- ChangedReactions to comments are not returned, but they still take up space in the page, so a short or empty reactions page can still have a next cursor. Do not use the number of results to decide you are done.
Reference:Pagination
- Added
Profile details: experience renamed, contact removed
ProfilesAction neededContracts 373 changesProfile details now returns work history as `experience` and no longer carries contact data.
What to doRead
data.experienceinstead ofdata.positions. For contact data, call the profile contact endpoint.- ChangedAll three profile details routes (
/v1/profiles/details/by-url,/by-usernameand/by-id) return work history indata.experienceinstead ofdata.positions. The items and the array and null behavior are the same. - Removed
data.contactfrom every profile details response. UseGET /v1/profiles/contact/by-urlor/by-username. - ChangedThe standalone full experience response still uses
data.positions.
Reference:Profile details
- ChangedAll three profile details routes (
Job search returns flat job records
JobsAction neededContracts 364 changesEach job from job search is now an object with named fields, so you read the title, company and location directly.
What to doRead jobs from
data.jobsand stop readingdata.result.items,attributesandlinks.- Changed
GET /v1/jobs/searchreturnsdata.jobs. Each job hastitle,url,companyName,companyUrl,location,postedAt,isPromotedandisEasyApply. - Changed
companyName,companyUrl,locationandpostedAtare null when unavailable. Posting dates are UTC.isPromotedandisEasyApplyshow the badges on the job card. URLs have no tracking parameters. No results isdata.jobs: []. - Removed
data.feature,data.resultand theattributesandlinkswrappers on this endpoint. Other job endpoints are unchanged. - ChangedPaging stays in
meta.paging.countis the page size, 10, anddata.jobs.lengthis how many jobs came back. WhenhasMoreis true, ask forstartpluscount. Remove duplicates across pages byurl. The credit cost is unchanged.
Reference:Job search
- Changed
Stable profile IDs across endpoints
Profiles · IDsAction neededContracts 334 changesThe same person now gets the same `profile_` ID in profile details, company people, people search and post reactions.
What to doValidate IDs with
^profile_[A-Za-z0-9]{39}$, allow null IDs, and drop any profile IDs you saved before this release. Look the profile up again by URL or username to get its new ID.- ChangedA profile ID is
profile_followed by exactly 39 letters and numbers, and it is case-sensitive. The same LinkedIn profile gives the same ID on every endpoint that returns one. - ChangedOld IDs cannot be converted, and there are no aliases. A profile ID is an EnvoAPI lookup input, not a LinkedIn username or URL. It does not prove the profile exists or give access to it.
- ChangedCompany people
idand people searchpublicIdcan be null when the provider gives no stable identifier. A username, URL, name or numeric member ID cannot be turned into a profile ID. - Added
GET /v1/posts/reactions/by-urland/by-slugreturnreactor.publicIdfor profile reactors.reactor.urlcan now be null. At least one of the two is always there, so usepublicIdfor the lookup whenurlis null.
Reference:Profile details
- ChangedA profile ID is
Paging moved to meta.paging
PaginationAction neededContracts 321 changeEvery list response now keeps its results in `data` and its paging in `meta`.
What to doRead paging from
meta.paginginstead ofdata.paging.- ChangedThe former
data.pagingobject is nowmeta.paging, next tometa.creditCost. Collections and resource fields stay indata. Request parameters are unchanged.
Reference:Pagination
- ChangedThe former
Profile details stops bundling contact data
ProfilesAction neededContracts 26–274 changesProfile details now returns profile data only. Contact data has its own endpoint, and company interests get routes by URL, username and ID.
What to doRemove
includeContactfrom every profile details request, evenincludeContact=false.- Removed
includeContacton profile details. Bothtrueandfalsenow return400 invalid_requestbefore the lookup starts. - ChangedProfile details is charged at the base profile price and never fetches contact data. Get contact data from
GET /v1/profiles/contact/by-urlor/by-username, which keep their own price. - ChangedSkills in profile details are plain arrays of strings. Certification fields the provider does not have are left out.
- Added
GET /v1/profiles/company-interests/by-url,/by-usernameand/by-id.
Reference:Profile details
- Removed
Seven helper routes retired
Jobs · SearchAction neededContracts 244 changesSeven GET routes are removed. Job search and job details are still available.
What to doRemove calls to the routes below before you update your client.
- Removed
/v1/search/home,/v1/search/filters,/v1/jobs/filters,/v1/jobs/feed,/v1/jobs/deep-link,/v1/jobs/deep-link/filtersand/assets/images/{token}.jpg. Requests return the standard route-not-found 404. - Changed
GET /v1/jobs/searchandGET /v1/jobs/detailsare not affected. Image URLs in responses keep usingimage.envoapi.com. - ChangedThe retired operation IDs stay valid in usage reports, so past events, activity and totals can still be read.
- AddedCompany jobs paging is part of this release.
Reference:Job searchCompany jobs
- Removed
One route per identifier type
Profiles · Companies · PostsAction neededContracts 194 changesProfile, company and post lookups now have one route for each way to identify the record. Query parameter names and responses stay the same.
What to doAdd the suffix that matches the identifier you send:
/by-url,/by-username,/by-idor/by-slug. For example,GET /v1/profiles/details?username=jane-doebecomesGET /v1/profiles/details/by-username?username=jane-doe.- RemovedThe generic profile, company and post lookup routes, such as
/v1/profiles/details,/v1/companies/detailsand/v1/posts/comments. They return 404 without starting a lookup. - AddedAn identifier-specific route for each of them. Profile details, for example, has
/by-url,/by-usernameand/by-id. The/by-idroutes need thepublicIdquery parameter. - ChangedStandalone profile sections such as experience, skills, education and contact no longer accept an ID. If you only have a profile ID, get the profile details by ID first, then use its URL or username.
- ChangedOther endpoints keep their inputs, paths, responses and credit prices.
Reference:API reference
- RemovedThe generic profile, company and post lookup routes, such as
Dates are the UTC publish dates of each contract version.Latest: Contracts 57 · October 4, 2026
What the API covers today
58 endpoints in six groups. Each group links to the page that shows its requests, responses and prices.
Profiles
25 endpointsProfile details by URL, username or ID. Contact data, work history, education, skills, certifications, courses, volunteer work and company interests. Posts, comments and reactions. Similar profiles and people search.
Companies
11 endpointsCompany details by URL, slug or ID. Lookup by domain and search by keyword. People, posts, products, open jobs and similar companies.
Jobs
2 endpointsSearch job postings by keyword and location. Open one posting by its URL for the full details.
Posts and search
14 endpointsPost details, comments and reactions. Search by keyword or hashtag. Lookups for locations, industries, service categories and schools, and typeahead suggestions.
Email
3 endpointsCheck if a domain is disposable (free), verify a mailbox (2 credits) and find a work email from a name and a domain (10 credits).
Website
3 endpointsGet the HTML of a page (2 credits), its visible text (2 credits), or the email addresses a site publishes (5 credits).
What to expect when something changes
These are the behaviors the contract documents for the changes on this page.
- A removed route returns 404. The request does not start a lookup.
- A removed parameter returns 400. The error code is
invalid_request, and it comes before any credits are charged. - A bad or expired cursor returns 400. The codes are
invalid_cursorandcursor_expired. Both come before any credits are charged, so start again without a cursor. - Email errors from the provider are refunded. That covers the 503
capacity_exceededand the 422email_unverifiableon email verify and email find. - Past usage stays readable. Retired operation IDs still show up in usage reports, so old events and totals do not disappear.
- Every response has an
X-Request-Idheader. Send it to us when a response does not look right.
Changelog questions
What does “Action needed” mean?
It marks a release that changes a request or a response you may already use, such as a renamed field or a removed parameter. The entry starts with what to do. Releases without the badge only add something new.
What do Added, Changed and Removed mean?
Added is a new endpoint, field or error code you can use. Changed is an existing request or response that now behaves differently. Removed is a route, parameter or field that no longer works. Fixed marks a defect that was corrected, with nothing to change on your side.
What is a contracts version?
Each release is a numbered version of the EnvoAPI API contract, the written description of every route, request, response and error. A new number means the contract changed. The dates on this page are the UTC dates those versions were published.
Does the /v1 path change when the API changes?
No. Every change on this page was made inside /v1, including the ones marked Action needed. That is why each of those entries names the exact routes, parameters and fields to update.
Am I charged when a request fails after a change?
Not for the errors on this page. A removed parameter, a bad cursor or an expired cursor returns 400 before any credits are charged, and the Yahoo 422 and the capacity 503 on the email routes are refunded. The error list for each endpoint in the API reference shows the rest.
How do I get notified about changes?
Subscribe to the changelog feed at /changelog.xml in any RSS reader. Each release in the feed links back to its entry on this page.
Where can I see what each endpoint costs?
Every endpoint in the API reference shows its credit cost, and every successful response reports it in meta.creditCost. Plans and credit packs are on the pricing page.
Build on the current API, not the one from last month.
The API reference always shows the current request, response and credit cost for every endpoint. Start there, then check this page before each release of your own.
Found a response that does not match the reference? Tell us and include the X-Request-Id header. Contact the team.