Endpoints // Search
Organization search
NewSearch the database for organizations with filters and get full organization profiles back with cursor pagination.
- Credits
- 1 credit per organization delivered. A page with no organization is free.
- Last verified
Introduction
The Organization Search endpoint returns full organization profiles matching a combination of filters. Filters are combined with AND logic. Results are drawn from our cache-based search index. This endpoint never triggers a live fetch.
Every result is a complete profile, the same shape the Company profile endpoint returns, so you do not need a second call to get the full data of a hit. Use the free Organization search count endpoint to check how many organizations match before you spend credits.
Coming from
POST /v2/search/companies? See Migrating company search to organizations.
Authorization
| Name | Type | Required | Description |
|---|---|---|---|
apikey | string | Yes | Your API key from the developer dashboard. Pass it via Authorization: Bearer YOUR_API_KEY header. |
Request body
Every filter is optional, but a request needs at least one, and filters are combined with AND logic. Scalar filters live in the table below; the nested-object filters (employeeCountRange, foundedYear, followersCount, location) are documented as expandable field items right after, and pagination (cursor, perPage) closes the section.
| Name | Type | Required | Description |
|---|---|---|---|
companyName | string | No | Filter by organization name |
companyDomain | string | No | Filter by website domain (e.g. acme.com). Disposable domains are rejected with 422 |
industry | string | string | No | Industry, or array of industries: an organization matches if its industry is any of them. See Industry values for the full list |
specialities | string | string | No | Speciality, or array of specialities: an organization matches if it lists any of them. See Specialities |
maxDataAgeDate | string | No | ISO 8601 datetime. Only returns organizations refreshed after this date. Needs at least one other filter |
cursor | string | No | Opaque cursor returned as metadata.nextCursor; request the next page |
perPage | number | No | Organizations per page (1 to 100, default 25) |
Filter validation: filters are validated before the query runs. Unknown field names, blank values (
"",[]), values outside a closed list (industry,location.countryCode) and inconsistent ranges return HTTP422with the offending field, the reason and suggested values, and cost 0 credits. Unknown fields are rejected rather than ignored, because an ignored filter would return unfiltered results. Each list filter accepts at most 20 values. See Search filter validation.
At least one filter: a body with only
cursorandperPagereturns HTTP422withNO_FILTER_PROVIDED.maxDataAgeDatenarrows a search but selects nothing on its own, so a request whose only filter ismaxDataAgeDatereturnsNO_FILTER_PROVIDEDtoo.followersCountsent as the only filter needs bothminandmax, otherwise the request returnsINCOMPLETE_RANGE_FILTER. None of these requests costs credits.
Note:
industryis matched exactly against the industry list. Case, surrounding spaces, accents and&versusandare normalized for you, and any other unlisted value returns HTTP422withINVALID_FILTER_VALUEand up to three suggested values, never an empty page.
employeeCountRangeobjectFilter by employee count. Both bounds are optional and inclusive, from 0 to 1,000,000,000. Headcount is stored as fixed size brackets (1, 2-10, 11-50, 51-200, 201-500, 501-1000, 1001-5000, 5001-10000, 10001+), not as an exact number, and a range only matches a bracket it fully contains. Send bracket boundaries, otherwise the range contains no bracket, matches nothing and returns an empty data.data array.
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
min | number | Lower bound, inclusive. Must be a bracket start: 1, 2, 11, 51, 201, 501, 1001, 5001, 10001 |
max | number | Upper bound, inclusive. Must be a bracket end: 1, 10, 50, 200, 500, 1000, 5000, 10000. Omit it to include 10001+ |
Examples:
{ "min": 11, "max": 50 }matches the11-50bracket.{ "min": 11, "max": 200 }spans11-50and51-200.{ "min": 10001 }matches10001+.{ "min": 11, "max": 20 }returns an empty array, because no whole bracket fits between 11 and 20.
foundedYearobjectFilter by founding year. Both bounds are optional and inclusive, from 0 to 2100.
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
min | number | Earliest founding year, inclusive |
max | number | Latest founding year, inclusive |
followersCountobjectFilter by follower count. Both bounds are optional and inclusive, from 0 to 1,000,000,000.
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
min | number | Minimum value, inclusive |
max | number | Maximum value, inclusive |
Ranges: bounds are whole numbers,
minmust not be greater thanmax, and a bound outside the accepted interval (for example afoundedYear.maxof2200) returns HTTP422withINVALID_RANGEand the accepted maximum inerror.details. The request costs 0 credits.
locationobjectHeadquarters location filter. Each sub-field is optional and accepts a single string or an array of strings (OR matching), with a maximum of 20 values per sub-field. Beyond that, the request returns HTTP 422 with FILTER_VALUES_LIMIT_EXCEEDED and costs 0 credits: split it into several searches. There is no area field here (unlike the person location filter).
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
country | string | string | Country name in English (e.g. "Germany"). An ISO code sent here is rejected with 422: put codes in countryCode |
countryCode | string | string | ISO 3166-1 alpha-2 country code (e.g. "DE"). Values outside the list are rejected with 422 |
region | string | string | State or region |
city | string | string | City, in its local spelling (e.g. "München") |
Specialities
specialities matches the specialities an organization lists on its profile, such as "SaaS" or "Machine Learning". Matching is word-based, not exact: case and accents are ignored, and every word of a value must appear among the organization's specialities, so "SaaS" also matches an organization that lists "B2B SaaS". A list is OR-matched: an organization matches when it lists at least one of the requested specialities.
Example
curl -X POST https://api.reversecontact.com/v2/search/organizations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"specialities": ["SaaS", "Machine Learning"],
"foundedYear": { "min": 2015 },
"location": { "countryCode": "DE", "city": "München" },
"perPage": 25
}'Tip: a very broad query, such as one common industry on its own, has to rank a very large set of organizations and can be slow or time out with HTTP
504, which costs 0 credits. Pair it with an employee count range, a founding year or a precise location to keep the search fast.
Pagination and credits
Organization search uses cursor pagination. Each response returns up to perPage organizations (1 to 100, default 25) and a metadata.nextCursor value. Pass that value back as cursor in the next request, with the same filters, to get the following page; nextCursor is null on the last page. The cursor is opaque: send it back unchanged, without parsing or altering it. perPage may change from one page to the next.
There is no page parameter. A request that sends page returns HTTP 422 with error.code UNKNOWN_FIELD, and the error names cursor as its replacement.
The cursor does not expire, and a long pause between two pages is fine: the next page picks up where the previous one stopped. If organizations were refreshed in the meantime, one of them can occasionally repeat or be skipped at the page boundary. When the last page is exactly full, its nextCursor is not null yet, and the request it leads to returns an empty page, which costs 0 credits.
An invalid cursor returns HTTP 400 with the message Invalid or expired cursor. This happens when a filter is changed between two pages (keep the filters identical and only add the cursor), or when the cursor is malformed (truncated or altered).
perPage above 100 returns HTTP 422 with error.code PAGINATION_LIMIT_EXCEEDED, and the error.details object identifies the field and maximum, for example { "field": "perPage", "max": 100 }. A perPage that is not a whole number returns HTTP 422 with error.code INVALID_PAGINATION.
Organization search costs 1 credit per organization delivered. Organizations removed for compliance reasons before the response are not billed. A page that returns 25 organizations costs 25 credits, and a page that returns no organization costs 0 credits. Before it runs, a request needs as many credits available as its perPage: with fewer, it returns HTTP 402 with INSUFFICIENT_CREDITS and costs nothing. Check the size of a query first with the free Organization search count endpoint, and lower perPage to control how many credits a single request can spend.
Response structure
Note: This endpoint uses a nested envelope. The top-level V2
datafield wraps an inner search payload that contains the actual results array (data.data) and the pagination info (data.metadata). See the example response for the exact shape.
| Field | Type | Description |
|---|---|---|
success | boolean | true if the request was processed successfully |
error | null | Always null on success |
data.dataobject[]Full organization profiles returned for this page, wrapped under data.data in the envelope. Empty array if no match. Each item is the same full profile shape as the Company profile endpoint; the table below lists its fields.
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
id | string | Reverse Contact company id (com_...). Use it as the id parameter of the Company profile endpoint |
companyName | string | Organization name |
linkedinId | string | Social company identifier |
publicId | string | Universal name / slug (the /company/xxx part of the URL) |
linkedinUrl | string | null | Full Social company URL |
employeesCount | number | null | Exact number of employees |
followersCount | number | null | Number of Social followers |
employeeCountRange | EmployeeCountRange | null | Employee count bracket |
websiteUrl | string | null | Official website URL |
tagline | string | null | Tagline / slogan |
description | string | null | Full description |
industry | string | null | Industry (e.g. "Software Development") |
phone | string | null | Phone number |
specialities | string | Specialities listed on the profile |
logoUrl | string | null | Logo image URL |
foundedOn | FoundedOn | null | Founding year wrapper |
locations | Location | All office locations registered on the profile (can be empty) |
backgroundUrl | string | null | Background / banner image URL |
headquarterobjectHeadquarters location (null if unknown). The location filter matches these fields.
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
street1 | string | null | Primary street address line |
street2 | string | null | Secondary street address line |
postalCode | string | null | Postal code |
city | string | null | City |
geographicArea | string | null | State or region |
country | string | null | Country ISO 3166 code (e.g. "US", "FR") |
employeeCountRangeobjectEmployee count bracket (null if unknown). Note the start / end field names (different from the request RangeFilter, which uses min / max). For the top bracket (10,001+) there is no upper bound, and end is 1 as a sentinel: read any range where end < start as start+ (unbounded). Use employeesCount for the exact headcount when available.
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
start | number | Lower bound of the range |
end | number | Upper bound of the range. If end < start, the bracket is unbounded (start+, i.e. 10,001+) |
foundedOnobjectFounding year (null if unknown)
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
year | number | Four-digit year |
locationsobject[]All office locations registered on the profile (can be empty)
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
street1 | string | null | Street address line 1 |
street2 | string | null | Street address line 2 |
postalCode | string | null | Postal / ZIP code |
city | string | null | City |
state | string | null | State or region (named state here, not geographicArea as in headquarter) |
country | string | null | Country ISO 3166 code (e.g. "US", "FR") |
data.metadataobjectPagination metadata wrapped under data.metadata in the envelope.
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
perPage | number | Organizations requested per page |
count | number | Organizations returned in this page. Use Organization search count for the total matching set |
nextCursor | string | null | Opaque cursor for the next page, null on the last page |
quotasobjectCredits and rate limit usage after this request
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
creditsConsumed | number | Credits consumed by this request |
workspaceobjectWorkspace-level limits
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
id | string | Your workspace identifier |
hasUnlimitedCredits | boolean | Whether workspace credits are unlimited |
allowDailyOvercost | boolean | Whether the workspace may exceed its daily cap |
creditsobjectCredit balance
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
total | number | Total credits in your plan |
used | number | Credits consumed so far |
left | number | Remaining credits |
dailyLimitobjectDaily request limit (null if not configured)
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
limit | number | Maximum requests per day |
used | number | Requests made today |
left | number | Remaining requests today |
nextReset | string | When the daily window resets (ISO 8601) |
minuteRateLimitobjectPer-minute rate limit
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
limit | number | Maximum requests per minute |
used | number | Requests made in the current minute |
left | number | Remaining requests in the current minute |
nextReset | string | When the minute window resets (ISO 8601) |
keyobjectAPI key-level limits (null when request is from dashboard)
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
id | string | API key identifier |
dailyLimitobjectDaily limit for this key (null if not configured)
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
limit | number | Maximum requests per day |
used | number | Requests made today |
left | number | Remaining requests today |
nextReset | string | When the daily window resets (ISO 8601) |
minuteRateLimitobjectMinute rate limit for this key
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
limit | number | Maximum requests per minute |
used | number | Requests made in the current minute |
left | number | Remaining requests in the current minute |
nextReset | string | When the minute window resets (ISO 8601) |
metadataobjectRequest tracking information (not to be confused with data.metadata which is pagination)
Show child attributesHide child attributes
| Field | Type | Description |
|---|---|---|
requestId | string | Unique identifier for this request |
executionTimeMs | number | Total execution time in milliseconds |
Code examples
Code Examples
curl -X POST https://api.reversecontact.com/v2/search/organizations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"industry": ["Software Development", "Technology, Information and Internet"],
"employeeCountRange": { "min": 51, "max": 500 },
"foundedYear": { "min": 2015 },
"location": {
"country": "United States",
"city": ["San Francisco", "Austin"]
},
"perPage": 25
}'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", "Technology, Information and Internet"],
employeeCountRange: { min: 51, max: 500 },
foundedYear: { min: 2015 },
location: { country: "United States", city: ["San Francisco", "Austin"] },
perPage: 25,
cursor
})
});
return response.json();
};
const firstPage = await searchPage();
const organizations = firstPage.data.data;
const { count, nextCursor } = firstPage.data.metadata;
console.log(`Got ${count} organizations, credits used: ${firstPage.quotas.creditsConsumed}`);
if (nextCursor) {
const secondPage = await searchPage(nextCursor);
organizations.push(...secondPage.data.data);
}import requests
response = requests.post(
"https://api.reversecontact.com/v2/search/organizations",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
json={
"industry": ["Software Development", "Technology, Information and Internet"],
"employeeCountRange": {"min": 51, "max": 500},
"foundedYear": {"min": 2015},
"location": {
"country": "United States",
"city": ["San Francisco", "Austin"]
},
"perPage": 25
}
)
payload = response.json()
organizations = payload["data"]["data"]
metadata = payload["data"]["metadata"]
print(f"Got {metadata['count']} organizations, next cursor: {metadata['nextCursor']}")Example response
Example Response
{
"success": true,
"data": {
"data": [
{
"id": "com_01jbd5vewyenebxgaz869ffe5t",
"companyName": "Acme Corp",
"linkedinId": "12345678",
"publicId": "acme",
"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",
"description": "Acme Corp builds collaboration software for enterprise teams. Founded in 2016, it serves over 10,000 customers worldwide.",
"industry": "Software Development",
"phone": "+1 (415) 555-0123",
"specialities": ["SaaS", "Enterprise Software", "Collaboration", "API Integration"],
"headquarter": {
"street1": "1 Market Street",
"street2": "Suite 400",
"postalCode": "94105",
"city": "San Francisco",
"geographicArea": "California",
"country": "US"
},
"logoUrl": "https://media.licdn.com/dms/image/v2/C4D0BAQ.../logo.jpg",
"foundedOn": {
"year": 2016
},
"locations": [
{
"street1": "1 Market Street",
"street2": "Suite 400",
"postalCode": "94105",
"city": "San Francisco",
"state": "California",
"country": "US"
},
{
"street1": "500 Congress Avenue",
"street2": null,
"postalCode": "78701",
"city": "Austin",
"state": "Texas",
"country": "US"
}
],
"backgroundUrl": "https://media.licdn.com/dms/image/v2/D5616AQ.../background.jpg"
}
],
"metadata": {
"perPage": 25,
"count": 1,
"nextCursor": null
}
},
"error": null,
"metadata": {
"requestId": "req_o1r2g3s4e5a6",
"executionTimeMs": 320
},
"quotas": {
"creditsConsumed": 1,
"workspace": {
"id": "ws_abc123",
"credits": {
"total": 10000,
"used": 4522,
"left": 5478
},
"dailyLimit": null,
"minuteRateLimit": {
"limit": 60,
"used": 5,
"left": 55,
"nextReset": "2026-10-16T14:16:00.000Z"
},
"hasUnlimitedCredits": false,
"allowDailyOvercost": false
},
"key": {
"id": "key_abc123",
"dailyLimit": null,
"minuteRateLimit": {
"limit": 60,
"used": 5,
"left": 55,
"nextReset": "2026-10-16T14:16:00.000Z"
}
}
}
}