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.

Response200GET /v1/emails/verifyjson
{  "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.

Releases18 releases · 72 changes

Filter changes by type

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.

  1. Company search returns companies without a description

    CompaniesAction neededContracts 572 changes · latest

    Company 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 description in company search results as nullable, for example by hiding that line when it is null.

    • Changeddescription in data.companies on GET /v1/companies/search and GET /v1/companies/by-domain is now string | 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, returned 500 internal_error for the whole page. It now returns the page.

    Reference:Company searchFind by website domain

  2. Job search takes location and company IDs, and gains four filters

    JobsAction neededContracts 55–567 changes

    Job 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 in location, not a place name. Replace companySlug with companyIds, using data.publicId from company details.

    • ChangedGET /v1/jobs/search accepts only one location ID in location, such as geo_6yITcz for United States. Get it from GET /v1/search/locations (data.locations[].id). A place name, a raw number or several IDs return 400 invalid_request before any credit is used.
    • RemovedcompanySlug on GET /v1/jobs/search. Sending it returns 400 invalid_request.
    • AddedcompanyIds on GET /v1/jobs/search: up to 10 company IDs separated by commas, such as company_4T4tWj for 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 returns 400 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=true and under10Applicants=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, or false, returns 400 invalid_request; leave a flag out to turn it off.
    • AddedEach job in data.jobs has companyLogoUrl, 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 returns 400 invalid_request on GET /v1/jobs/search, GET /v1/profiles/search and GET /v1/companies/search instead of a retryable 500 internal_error.

    Reference:Job searchLocation searchCompany details

  3. Disposable addresses get an answer on email verify and find

    EmailAction neededContracts 544 changes

    Email 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 disposable reason wherever you switch over verification reasons.

    • ChangedGET /v1/emails/verify returns invalid with the reason disposable and isDisposable: true for a disposable address. The charge is kept.
    • ChangedGET /v1/emails/find stops at the first disposable answer with not_found, no address, isDisposable: true and a verification.reason of disposable.
    • FixedA disposable address no longer returns a retryable 503 on either route.
    • AddedNew verification reason disposable. If your client lists or labels reasons, add it.

    Reference:Verify emailFind email

  4. Yahoo addresses get a clear error on email verify and find

    EmailAction neededContracts 533 changes

    The 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_unverifiable error code. It is not retryable, so do not retry it.

    • ChangedGET /v1/emails/verify for an address at yahoo.*, ymail.com or rocketmail.com, and GET /v1/emails/find for one of those domains, now return 422 with the error code email_unverifiable.
    • ChangedThe error has no Retry-After header and the credits are refunded. X-Credits-Remaining and 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

  5. Email verify, email finder and website text

    Email · WebsiteContracts 516 changes

    Check 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.

    • AddedGET /v1/emails/verify, 2 credits. Returns one status (valid, invalid or unverifiable) with a stable reason, plus isCatchAll and isDisposable.
    • AddedGET /v1/emails/find, 10 credits. Send a first name, an optional last name and a domain. Returns a status (found, catch_all, not_found or no_mx), the address when one is accepted, and how many candidates were checked. A search that reaches a conclusion keeps the charge, including catch_all, not_found and no_mx.
    • AddedGET /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.
    • Added503 capacity_exceeded with a Retry-After header, returned when the verification provider has no capacity. The credits are refunded.
    • ChangedEmail results are never cached, so meta has no cache status. Usage reports list these calls under the emailCheck endpoint.
    • ChangedIf your client switches over error codes or operation IDs, add the new values: capacity_exceeded, verifyEmail, findEmail and getWebsiteText.

    Reference:Verify emailFind emailWebsite text

  6. Website content and email discovery

    WebsiteContracts 504 changes

    Fetch the HTML of any public web page, or find the email addresses a company publishes on its website.

    • AddedGET /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.
    • AddedGET /v1/websites/emails, 5 credits. Reads up to eight pages and stops at the first page with addresses. stopReason explains 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 websiteContentCredits and websiteEmailsCredits. Profile and company prices keep their meaning.

    Reference:Website contentWebsite emails

  7. Free disposable email check

    EmailContracts 481 change

    Check whether an address uses a throwaway email domain before you create an account for it.

    • AddedGET /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

  8. The API now sets page sizes

    Pagination · SearchAction neededContracts 444 changes

    Page 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, maxPages and fetchAll from every request, even when you send the old default value.

    • RemovedThe count, limit, maxPages and fetchAll query parameters. A request that sends any of them gets 400 invalid_request before any credits are charged. For example, GET /v1/profiles/search?keywords=engineer&offset=0&limit=3 becomes GET /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.
    • Changedoffset, start, cursor, filters and sorting work as before. Follow nextOffset, nextStart or nextCursor when the response has one. count and limit are still returned in meta.paging.

    Reference:Pagination

  9. New API key format

    API keysAction neededContracts 424 changes

    Every 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 accessDelivery set to pending while 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 with applied mean 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

  10. Company people and company posts get new paging

    Companies · PaginationAction neededContracts 40–418 changes

    Company people returns smaller records and a real total. Company posts pages with a cursor.

    What to doStop sending groupingType to company people, and read each person from id, headline and profilePictureUrl only.

    • ChangedGET /v1/companies/people takes slug and start (default 0) and returns 10 people per page. It always returns the all-employees list.
    • ChangedEach person has only id, headline and profilePictureUrl. All three are always present and can be null.
    • Addedmeta.paging on company people has start, count, total and hasMore. total is 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 returns total 0.
    • ChangedIf the provider gives no valid total, the lookup fails instead of returning a made-up number.
    • RemovedgroupingType on company people. Sending it now returns 400.
    • AddedGET /v1/companies/posts takes an optional cursor. filter accepts ALL, IMAGES, VIDEOS, DOCUMENTS and ARTICLES, and the first request can start anywhere from 0 to 10000.
    • Addedmeta.paging on company posts adds returned, hasMore and nextCursor. Pass nextCursor back unchanged with the same slug and filter, and leave start out. Stop when hasMore is false and nextCursor is null.
    • Added400 invalid_cursor and 400 cursor_expired, returned before any credits are charged. Start again without a cursor after one.

    Reference:Company peoplePagination

  11. Cursor paging for profile comments and reactions

    Profiles · PaginationContracts 38–395 changes

    Page 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.

    • AddedGET /v1/profiles/comments and GET /v1/profiles/reactions take an optional cursor next to username. Responses add meta.paging with count, returned, hasMore and nextCursor.
    • AddedTo get the next page, repeat the same username with the nextCursor from the last response, unchanged. Stop when hasMore is false and nextCursor is null. A cursor belongs to one account and one endpoint, and a chain lasts at most 15 minutes.
    • Added400 invalid_cursor and 400 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

  12. Profile details: experience renamed, contact removed

    ProfilesAction neededContracts 373 changes

    Profile details now returns work history as `experience` and no longer carries contact data.

    What to doRead data.experience instead of data.positions. For contact data, call the profile contact endpoint.

    • ChangedAll three profile details routes (/v1/profiles/details/by-url, /by-username and /by-id) return work history in data.experience instead of data.positions. The items and the array and null behavior are the same.
    • Removeddata.contact from every profile details response. Use GET /v1/profiles/contact/by-url or /by-username.
    • ChangedThe standalone full experience response still uses data.positions.

    Reference:Profile details

  13. Job search returns flat job records

    JobsAction neededContracts 364 changes

    Each 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.jobs and stop reading data.result.items, attributes and links.

    • ChangedGET /v1/jobs/search returns data.jobs. Each job has title, url, companyName, companyUrl, location, postedAt, isPromoted and isEasyApply.
    • ChangedcompanyName, companyUrl, location and postedAt are null when unavailable. Posting dates are UTC. isPromoted and isEasyApply show the badges on the job card. URLs have no tracking parameters. No results is data.jobs: [].
    • Removeddata.feature, data.result and the attributes and links wrappers on this endpoint. Other job endpoints are unchanged.
    • ChangedPaging stays in meta.paging. count is the page size, 10, and data.jobs.length is how many jobs came back. When hasMore is true, ask for start plus count. Remove duplicates across pages by url. The credit cost is unchanged.

    Reference:Job search

  14. Stable profile IDs across endpoints

    Profiles · IDsAction neededContracts 334 changes

    The 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 id and people search publicId can be null when the provider gives no stable identifier. A username, URL, name or numeric member ID cannot be turned into a profile ID.
    • AddedGET /v1/posts/reactions/by-url and /by-slug return reactor.publicId for profile reactors. reactor.url can now be null. At least one of the two is always there, so use publicId for the lookup when url is null.

    Reference:Profile details

  15. Paging moved to meta.paging

    PaginationAction neededContracts 321 change

    Every list response now keeps its results in `data` and its paging in `meta`.

    What to doRead paging from meta.paging instead of data.paging.

    • ChangedThe former data.paging object is now meta.paging, next to meta.creditCost. Collections and resource fields stay in data. Request parameters are unchanged.

    Reference:Pagination

  16. Profile details stops bundling contact data

    ProfilesAction neededContracts 26–274 changes

    Profile 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 includeContact from every profile details request, even includeContact=false.

    • RemovedincludeContact on profile details. Both true and false now return 400 invalid_request before 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-url or /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.
    • AddedGET /v1/profiles/company-interests/by-url, /by-username and /by-id.

    Reference:Profile details

  17. Seven helper routes retired

    Jobs · SearchAction neededContracts 244 changes

    Seven 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/filters and /assets/images/{token}.jpg. Requests return the standard route-not-found 404.
    • ChangedGET /v1/jobs/search and GET /v1/jobs/details are not affected. Image URLs in responses keep using image.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

  18. One route per identifier type

    Profiles · Companies · PostsAction neededContracts 194 changes

    Profile, 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-id or /by-slug. For example, GET /v1/profiles/details?username=jane-doe becomes GET /v1/profiles/details/by-username?username=jane-doe.

    • RemovedThe generic profile, company and post lookup routes, such as /v1/profiles/details, /v1/companies/details and /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-username and /by-id. The /by-id routes need the publicId query 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

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 endpoints

    Profile 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 endpoints

    Company details by URL, slug or ID. Lookup by domain and search by keyword. People, posts, products, open jobs and similar companies.

  • Jobs

    2 endpoints

    Search job postings by keyword and location. Open one posting by its URL for the full details.

  • Posts and search

    14 endpoints

    Post details, comments and reactions. Search by keyword or hashtag. Lookups for locations, industries, service categories and schools, and typeahead suggestions.

  • Email

    3 endpoints

    Check 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 endpoints

    Get 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_cursor and cursor_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_exceeded and the 422 email_unverifiable on 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-Id header. 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.