Migrations & changes
Migrating company search to organizations
NewMove company search calls from /v2/search/companies to /v2/search/organizations.
- Last verified
Company search has a new home: POST /v2/search/organizations. It returns full organization profiles instead of search hits, paginates with cursors instead of page numbers, accepts three new filters, and ships with a free count endpoint.
The previous endpoint, POST /v2/search/companies, is deprecated since October 16, 2026. It keeps working for now and no retirement date is announced yet, but it is no longer documented in the endpoint catalog. Once it is retired, calls to /v2/search/companies and /v2/search/companies/available-fields will return 410 Gone with the error code ENDPOINT_GONE, error.details.alternative naming the endpoint to call instead and error.details.docs linking this guide. This guide covers everything that changes when you move to /v2/search/organizations.
What changes
| Area | POST /v2/search/companies | POST /v2/search/organizations |
|---|---|---|
| Path | /v2/search/companies | /v2/search/organizations |
| Results | Search hits (name, size, industry, city and country) | Full organization profiles, the same shape as the Company profile endpoint |
| Pagination | page and perPage (default 100) | cursor and perPage (default 25) |
| Metadata | currentPage, pageNumber, perPage, total | perPage, count, nextCursor |
| Total matches | data.metadata.total on every response | Free count endpoint |
| Pricing | 1 credit per page | 1 credit per organization delivered |
| Filters | companyName, companyDomain, industry, employeeCountRange, location, maxDataAgeDate | The same, plus specialities, foundedYear and followersCount |
| Available fields | GET /v2/search/companies/available-fields | GET /v2/search/organizations/available-fields |
Paths
| Before | After |
|---|---|
POST /v2/search/companies | POST /v2/search/organizations |
GET /v2/search/companies/available-fields | GET /v2/search/organizations/available-fields |
| (no equivalent) | POST /v2/search/organizations/count |
The method and the Authorization: Bearer YOUR_API_KEY header stay the same. Only the path changes.
Results are full profiles
The previous endpoint returned a light search hit, and the documented flow was to chain into the Company profile endpoint for the full data of a hit. Organization search returns complete profiles directly, so the second call is no longer needed.
Before, a hit looked like this:
{
"id": "com_01jbd5vewyenebxgaz869ffe5t",
"name": "Acme Corp",
"publicId": "acme",
"linkedinId": "12345678",
"linkedinUrl": "https://www.social.com/company/acme",
"employeesCount": 452,
"followersCount": 28512,
"employeeCountRange": { "start": 201, "end": 500 },
"websiteUrl": "https://www.acmecorp.com",
"tagline": "Building the future of work",
"industry": "Software Development",
"companyUpdateDate": "2026-03-18T09:12:44.000Z",
"location": { "city": "San Francisco", "country": "US" }
}After, each item of data.data is a full organization profile. Most fields keep their name (id, publicId, linkedinId, linkedinUrl, employeesCount, followersCount, employeeCountRange, websiteUrl, tagline, industry), three change, and the profile adds description, phone, specialities, logoUrl, backgroundUrl, foundedOn and locations:
| Search hit | Full profile |
|---|---|
name | companyName |
location.city, location.country | headquarter.city, headquarter.country (still an ISO code), next to the street, postal code and region of the headquarters |
companyUpdateDate | Not part of the full profile. Filter on freshness with maxDataAgeDate, or read lastUpdate from the free Company profile status endpoint |
If you chained Company profile calls after a search, drop them: the data is already in the search response.
Pagination moves from pages to cursors
The previous endpoint used page (1 to 50) and perPage (1 to 100, default 100), and reported currentPage, pageNumber and total in data.metadata. Organization search uses cursor pagination:
perPagestays, with a new default of25(still 1 to 100).pageis gone, and sending it returns422withUNKNOWN_FIELD. Send thenextCursorvalue from the previous response ascursorto get the next page, with the same filters.nextCursorisnullon the last page.- The cursor is opaque: send it back unchanged, without parsing or altering it.
- The 50-page limit is gone: a cursor reaches every matching organization.
Before:
const response = await fetch("https://api.reversecontact.com/v2/search/companies", {
method: "POST",
headers: { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" },
body: JSON.stringify({ industry: "Software Development", page: 2, perPage: 100 })
});
const payload = await response.json();
const hits = payload.data.data;
console.log(`Page ${payload.data.metadata.currentPage} of ${payload.data.metadata.pageNumber}, ${payload.data.metadata.total} total`);After:
const searchPage = async (cursor) => {
const response = await fetch("https://api.reversecontact.com/v2/search/organizations", {
method: "POST",
headers: { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" },
body: JSON.stringify({ industry: "Software Development", perPage: 25, cursor })
});
return response.json();
};
const page = await searchPage();
console.log(`${page.data.metadata.count} organizations in this page`);
if (page.data.metadata.nextCursor) {
const nextPage = await searchPage(page.data.metadata.nextCursor);
}Totals move to the count endpoint
The previous data.metadata.total field is gone: data.metadata.count is the number of organizations in the current page, not the size of the whole matching set. To size a query, call the free Organization search count endpoint with the same filters:
curl -X POST https://api.reversecontact.com/v2/search/organizations/count \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "industry": "Software Development" }'The response is data.count, the total number of matching organizations across all pages, and it costs 0 credits.
Pricing changes
The previous endpoint charged 1 credit per page, whatever the page contained. Organization search charges 1 credit per organization delivered: a page that returns 25 organizations costs 25 credits, and a page that returns no organization costs 0 credits. Rejected filters still cost 0 credits.
Three consequences for your migration:
perPageis now a credit control. Lower it to cap what a single request can spend.- A request needs as many credits available as its
perPagebefore it runs, otherwise it returns402withINSUFFICIENT_CREDITS. Only the organizations delivered are then charged. - Size queries first with the free count endpoint instead of reading
metadata.totalfrom a billed page.
Filter changes
Existing filters keep their names and their values: companyName, companyDomain, industry (from the same industry list), employeeCountRange (the same headcount brackets), location (country, countryCode, region and city, matched on the headquarters) and maxDataAgeDate. Organization search also accepts filters the previous endpoint did not have:
| Filter | What it does |
|---|---|
specialities | Match the specialities listed on the organization profile, one value or a list (OR-matched) |
foundedYear | Keep organizations founded within a year range, from 0 to 2100 |
followersCount | Keep organizations within a follower count range |
Two rules are stricter. A request needs at least one filter, and maxDataAgeDate cannot be that only filter: both return 422 with NO_FILTER_PROVIDED. Validation is otherwise unchanged in spirit: unknown fields, blank values and values outside a closed list return 422 with suggestions and cost 0 credits. Every filter is documented on the Organization search page.
Available fields moves too
If you discover filters dynamically, switch GET /v2/search/companies/available-fields to GET /v2/search/organizations/available-fields. The response keeps its shape, with two differences: data.entity is "organization", and data.fields lists cursor instead of page, next to every accepted filter and the allowedValues of closed vocabularies such as industries.
Migration checklist
- Replace the search path with
POST /v2/search/organizationsand the available-fields path withGET /v2/search/organizations/available-fields. - Replace
pagewith cursor handling: loop whiledata.metadata.nextCursoris notnull. - Review your
perPage: the default is now25, each delivered organization costs 1 credit, and the balance must coverperPagebefore the call. - Replace
data.metadata.totalreads with a call toPOST /v2/search/organizations/count. - Map the renamed fields:
namebecomescompanyName,locationbecomesheadquarter, andcompanyUpdateDateis gone. - Drop the Company profile calls you used to chain after a search: results are already full profiles.
- Make sure every request carries at least one filter other than
maxDataAgeDate.
FAQ
Does /v2/search/companies still work?
Yes, for now. POST /v2/search/companies is deprecated since October 16, 2026, has left the documentation and has no retirement date yet. Once it is retired, it will return 410 Gone with the error code ENDPOINT_GONE and name POST /v2/search/organizations in error.details.alternative, so move to POST /v2/search/organizations now.
How do I get the total number of matching organizations with /v2/search/organizations?
POST /v2/search/organizations does not return a total: data.metadata.count is only the number of organizations in the current page. Call POST /v2/search/organizations/count with the same filters to get data.count, the total number of matching organizations across all pages, for 0 credits. See Organization search count.
How many credits does an organization search cost?
POST /v2/search/organizations charges 1 credit per organization delivered: a page that returns 25 organizations costs 25 credits, and a page that returns no organization costs 0 credits. Rejected filters also cost 0 credits, and lowering perPage caps what a single request can spend.
Which result fields change name in /v2/search/organizations?
In POST /v2/search/organizations results, name becomes companyName and location becomes headquarter, whose country is still an ISO code. companyUpdateDate is not part of the full profile: filter with maxDataAgeDate, or read lastUpdate from the free Company profile status endpoint.
Do I still need to call the Company profile endpoint after an organization search?
No. Each item of data.data in a POST /v2/search/organizations response is already a full organization profile, with description, specialities, headquarter, locations, foundedOn and the other Company profile fields, so the Company profile calls you chained after a search can be dropped. See Company profile.