List Management APIs

Guide to managing organization lists with the Vainu List Management API

Endpoints

This document describes the three organization list-management APIs under /api/v3/lists/organizations/

## 1. Combined Vainu List Index
GET /api/v3/lists/organizations/ 
## 2. Static List Management
GET /api/v3/lists/organizations/static/
## 3. Dynamic List Management
GET /api/v3/lists/organizations/dynamic/

What is a Dynamic List?

Is a saved list in Vainu a query has been set such as{"?LTE": {"financial_data.employees.absolute_count": 50}}. The list is dynamic, companies in it are updating to reflect real-time data shifts.

In Vainu Platform found under "My Lists"

What is a Static List?

A static List is static and contains a fixed set of companies (Business IDs) that stay the same unless you manually add or remove them. While "Dynamic Lists" update automatically based on filters and data changes.

In Vainu Platform Static lists can be found under "Custom Lists".

Authentication

Use Vainu API Authentication

Full Code Example Recipe

1) Combined organization lists API

Base path: /api/v3/lists/organizations/

Purpose:

  • Returns organization lists regardless of whether they are static or dynamic.
  • Useful for UI/clients that need a single list index.

Supported operations:

  • GET / list accessible organization lists.
  • GET /{id}/ retrieve one list summary.
  • DELETE /{id}/ delete a list (owner or write access required).
  • POST /{id}/clone/ clone a list (read access is enough for clone action).

Notes:

  • Summary payload includes shared fields such as id, name, type, query, privileges, timestamps.
  • For organization lists, summary also includes country and scoring.
  • This endpoint is for cross-type access; create/update flows are handled via static and dynamic endpoints.

2) Static organization lists API

Base path: /api/v3/lists/organizations/static/

Purpose:

  • Manages static organization lists that store explicit business_ids.

Required create fields:

  • name
  • country (one of tier-1 countries: FI, SE, NO, DK, 'NL')

Optional create/update fields:

  • business_ids: array of prefixed tier-1 business IDs.

Supported operations:

  • GET / list static organization lists.
  • POST / create a static list.
  • GET /{id}/ retrieve details.
  • PATCH /{id}/ partial update.
  • PUT /{id}/ full update.
  • DELETE /{id}/ delete.
  • POST /{id}/clone/ clone list.
  • PATCH /{id}/add/ atomically add business_ids.
  • PATCH /{id}/remove/ atomically remove business_ids.
  • PATCH /{id}/combine/{source_id}/ merge source list IDs into target list.
  • POST /{id}/import_spreadsheet/ import IDs from spreadsheet.
  • POST /{id}/revert_migrate/ restore legacy source when list was created by migration.

Behavior and constraints:

  • country is immutable after creation.
  • Each business_id must match the list country prefix.
  • country and business_ids__in can be used as list filters.

3) Dynamic organization lists API

Base path: /api/v3/lists/organizations/dynamic/

Purpose:

  • Manages dynamic organization lists whose membership is defined by a query.

Required create fields:

  • name
  • country (one of tier-1 countries: FI, SE, NO, DK, NL)
  • query (valid modern query format)

Optional create/update fields:

  • query_metadata
  • scoring

Supported operations:

  • GET / list dynamic organization lists.
  • POST / create a dynamic list.
  • GET /{id}/ retrieve details.
  • PATCH /{id}/ partial update.
  • PUT /{id}/ full update.
  • DELETE /{id}/ delete.
  • POST /{id}/clone/ clone list.
  • POST /{id}/revert_migrate/ restore legacy source when list was created by migration.

Behavior and constraints:

  • query is mandatory and validated.
  • country is immutable after creation.
  • country can be used as a list filter.
  • No atomic add/remove/combine actions, because membership is query-based.

GET /api/v3/lists/organizations/

# Get all Static Organization Lists
GET /api/v3/lists/organizations/static/

# Get all Dynamic Organization Lists
/api/v3/lists/organizations/dynamic/

List Object Specification

All the list endpoints and actions return similar data structure that defines a Vainu List.

{
    "country": "FI",
    "created": "2023-01-31T09:24:30.201000",
    "id": "63d8de4eb7dfe9f5896fa539",
    "last_open_in_ui": "2023-01-31T09:24:30.201000",
    "migrated_from_legacy_list": null,
    "modified": "2023-04-29T11:48:51.054000",
    "name": "Finland + Revenue +1M EUR",
    "privileges": {
        "current": "owner",
        "shared_count": 0
    },
    "query": "{\"?GTE\": {\"financial_data.revenue\": 1000000}}",
    "scoring": null,
    "type": "dynamic-organization-list"
}

Fields and Data Types

FieldTypeNullableDescription
countrystringNoCountry database code, for example FI, SE, NO, DK,ML.
createdstring (datetime)NoISO 8601 timestamp when list was created.
idstringNoUnique list identifier. Use this for editing lists.
last_open_in_uistring (datetime)YesLast UI open timestamp. May be null.
migrated_from_legacy_liststring or nullYesLegacy list reference when migrated, otherwise null.
modifiedstring (datetime)NoISO 8601 timestamp of latest list update.
namestringNoHuman-readable list name.
privilegesobjectNoAccess rights for current user and sharing metadata.
privileges.currentstringNoCurrent user role for this list, for example owner.
privileges.shared_countintegerNoNumber of users the list is shared with.
querystringYesSerialized query string used by dynamic lists.
typestringNoList type, for example dynamic-organization-list or static-organization-list.

Simple Example to get ALL lists:

import requests

BASE_URL = "https://api.vainu.io/api/v3/lists/organizations/"

response = requests.get(BASE_URL, headers=headers)
response.raise_for_status()

lists = response.json()
print(f"Found {len(lists)} lists")

Create a Dynamic List


access_token = ACCESS_TOKEN  # https://developers.vainu.com/v3/docs/authentication 
payload = {
    "name": "Swedish Manufacturers",
    "country": "SE",
    "query": json.dumps({
        "?ALL": [
            {
                "?IN": {"official_industries.code": ["25"]},
            },
        ],
    }),
}

response = requests.post(
    dynamic_list_v3_endpoint,
    headers={"Authorization": f"Bearer {access_token}"},
    json=payload,
)
assert response.status_code == 201
pprint.pprint(response.json())
# Example response:
"""
{'country': 'SE',
 'created': '2026-04-20T12:37:24.397523',
 'id': '69e61e048c5d1ae30b426a1b',
 'last_open_in_ui': '2026-04-20T12:37:24.397156',
 'migrated_from_legacy_list': None,
 'modified': '2026-04-20T12:37:24.403035',
 'name': 'Swedish Finnish manufacturers',
 'owner': '[email protected]',
 'permissions_full': [],
 'permissions_readonly': [],
 'privileges': {'current': 'owner', 'shared_count': 0},
 'query': '{"?ALL": [{"?IN": {"official_industries.code": ["25"]}}]}',
 'query_metadata': None,
 'scoring': None,
 'type': 'dynamic-organization-list'}
"""

Get all static lists

STATIC_LISTS_URL = "https://api.vainu.io/api/v3/lists/organizations/static/"

response = requests.get(STATIC_LISTS_URL, headers=headers)
response.raise_for_status()

static_lists = response.json()

Get a single static list

Python example:

list_id = static_lists[0]["id"]
STATIC_LISTS_URL = "https://api.vainu.io/api/v3/lists/organizations/static/"
response = requests.get(
    f"{STATIC_LISTS_URL}{list_id}/",
    headers=headers,
)
response.raise_for_status()

static_list = response.json()

Add business IDs to a static list

PATCH /api/v3/lists/organizations/static/{list_id}/add/

Request body is a JSON array of business IDs.

Python example:

business_ids_to_add = ["FI21197914", "FI17101289"]
STATIC_LISTS_URL = "https://api.vainu.io/api/v3/lists/organizations/static/"

response = requests.patch(
    f"{STATIC_LISTS_URL}{list_id}/add/",
    headers=headers,
    json=business_ids_to_add,
)

# API returns 204 No Content on success
if response.status_code != 204:
    response.raise_for_status()

Remove business IDs from a static list

PATCH /api/v3/lists/organizations/static/{list_id}/remove/

Request body is a JSON array of business IDs.

Python example:

business_ids_to_remove = ["FI21197914", "FI17101289"]

response = requests.patch(
    f"{STATIC_LISTS_URL}{list_id}/remove/",
    headers=headers,
    json=business_ids_to_remove,
)

# API returns 204 No Content on success
if response.status_code != 204:
    response.raise_for_status()

Rename a static list

PATCH /api/v3/lists/organizations/static/{list_id}/

Python example:

response = requests.patch(
    f"{STATIC_LISTS_URL}{list_id}/",
    headers=headers,
    json={"name": "New List Name"},
)
response.raise_for_status()

Clear all business IDs from a static list

PATCH /api/v3/lists/organizations/static/{list_id}/

Set business_ids to an empty array to remove all members.


Python example:

response = requests.patch(
    f"{STATIC_LISTS_URL}{list_id}/",
    headers=headers,
    json={"business_ids": []},
)
response.raise_for_status()

.

Response Notes

  • List fetch endpoints return JSON data.
  • Add/remove operations return 204 No Content on success.
  • Patch operations on the list itself (for example renaming) return JSON with status 200 when successful.