VECK API DocumentationAPI v1
REST API for seamless integration into venture capital monitoring and internal workflows: cards (projects / signals), participants (funds, investors, people), interactions, and reference data for filters. All routes are versioned under /v1/.
Overview
Quick start
Minimal request
- Base URL:
https://api.theveck.com- Header:
Authorization: Token <your_token>on every request- Example:
GET https://api.theveck.com/v1/cards/?limit=10
Authentication
Every endpoint requires a valid API token. Send it in the Authorization header using the Token scheme (see Quick start). Invalid or missing credentials result in 401 (see Error Handling).
Conventions
| Topic | Rule |
|---|---|
| Versioning | All paths use /v1/… |
| JSON bodies | Use Content-Type: application/json when a body is required (e.g. Get Cards List (POST)) |
| List responses | Typically data plus optional pagination and meta (Response Format) |
| Field semantics | Required fields are always present. Optional values may be null; this doc uses `type |
| Response shape | Glossary lists fields with a Presence column (required, optional, nullable, semantic only). |
| Dates | Request filters: YYYY-MM-DD. Response datetimes: ISO 8601 UTC. Details: Date Formats |
Where to read next: endpoint details under Cards and Participants; valid slugs under Reference Data; response field reference under Glossary; errors and payload shape under Notes.
Cards
List and inspect cards (projects / signals): pagination, filters, semantic search, detail and interactions. Use Reference Data below for slug values used in query parameters.
Get Cards List (GET)
GET /v1/cards/
Get a list of signal cards (projects) with pagination, sorting, and filtering support.
Main Parameters
| Parameter | Type | Description |
|---|---|---|
limit | integer | Records per page (max 100, default 20) |
offset | integer | Offset from start (default 0) |
include_total | boolean | Include total count in pagination (true by default). Set false to skip expensive count() on large filtered datasets |
sort | string | Preset or custom sort (default: latest_signal_date:desc) |
include_user_data | boolean | Include favorites, notes, folders |
view | string | Response preset: default (full payload) or compact (lightweight payload) |
fields | string | Optional comma-separated top-level fields, for example fields=id,slug,name,image,similarity |
Sort presets
| Preset | Description |
|---|---|
trending | By interactions count (desc), then latest signal date (desc) |
recent | By creation date (desc) |
most_active | By update date (desc), then interactions count (desc) |
Custom sort: field:direction or field1:dir1,field2:dir2
Available fields: created_at, updated_at, name, interactions_count, latest_signal_date
Directions: asc, desc
Filters
| Parameter | Type | Description |
|---|---|---|
stages | string | Comma-separated stage slugs, for example stages=seed,series_a. Values: stages |
rounds | string | Comma-separated round slugs, for example rounds=raising_now,just_raised. Values: rounds |
categories | string | Comma-separated category slugs, for example categories=ai,saas. Values: categories |
locations | string | Comma-separated location slugs, for example locations=san_francisco_ca,bay_area. Values: locations |
participants | string | Comma-separated participant slugs, for example participants=investor-fund. Values: participants |
display_preference | string | web3, web2, or all |
filter_id | integer | Saved filter ID. Values: saved filters |
folder_ids | string | Comma-separated folder IDs, for example folder_ids=1,2,3. Values: user folders |
search | string | Search by card name/description; with semantic=1 it becomes semantic search |
featured | boolean | Filter featured cards (true / false) |
new | boolean | Only cards created in the last 7 days (true) |
trending | boolean | Filter trending cards (true / false) |
min_signals | integer | Minimum number of interactions |
max_signals | integer | Maximum number of interactions |
Semantic search (cards)
What it is: Semantic search finds cards by meaning and context, not just by exact words. For example, a query like "crypto exchange" can match projects about DeFi or trading platforms even if those exact words are not in the card text. Results are ordered by how closely they match the intent of your query.
-
semantic(boolean-like string) — enables this search mode when used together withsearch:- Allowed values:
1,true,yes(case-insensitive) - Behavior:
- Text from
searchis transformed into semantic vectors by our internal retrieval pipeline. - All other filters (stages, rounds, categories, locations, participants, etc.) are applied first.
- Matching cards with non-null embeddings are ordered by cosine similarity to the query embedding.
- Results are filtered by relevance threshold (default
min_similarity=0.3). - Each result includes a
similarityfield (0.0-1.0) indicating how well it matches the query. - Pagination (
limit,offset) works as usual.
- Text from
- If embeddings are temporarily unavailable, the API may return
503witherror: "semantic_unavailable".
- Allowed values:
-
min_similarity(float) — minimum cosine similarity threshold for semantic search (only used withsemantic=1):- Range:
0.0to1.0(where1.0= perfect match,0.0= no similarity) - Practical range:
0.3to0.9(values above 0.9 are extremely rare and indicate near-perfect matches) - Default:
0.3(filters out clearly irrelevant results while keeping good matches) - Recommended values:
0.7-0.9— very strict (only highly relevant results, fewer matches)0.5-0.7— strict (good quality results)0.3-0.5— default (balanced, filters obviously irrelevant)0.0-0.3— lenient (more results, may include less relevant)
- Higher values = more relevant results, but fewer matches
- Lower values = more results, but may include less relevant ones
- Note: Setting
min_similarityabove0.9will likely return very few or no results, as perfect matches are extremely rare
- Range:
Semantic metadata in response: when semantic=1, response includes meta.semantic with enabled, min_similarity, and ranking so clients can render/debug ranking mode.
Date Filters
| Parameter | Description |
|---|---|
created_after, created_before | Card creation date (format: YYYY-MM-DD) |
updated_after, updated_before | Card update date |
last_interaction_after, last_interaction_before | Last interaction date |
first_interaction_after, first_interaction_before | First interaction date |
Filtering Logic
- Different filter groups are combined with AND (except stages and rounds)
- Values within each group are combined with OR
- Stages and rounds are combined with OR — if both
stagesandroundsare specified, cards matching either the stage OR the round will be returned - When a parent category is specified, all child categories are automatically included
- When a region is specified, cards from all locations in that region are returned
Examples:
stages=seed&rounds=raising_now— returns cards with stageseedOR roundraising_nowstages=seed,series_a&categories=ai— returns cards with stageseedORseries_a, AND categoryai
Example Request
GET /v1/cards/?limit=20&offset=0&sort=trending&categories=ai,saas&stages=seed&include_user_data=true
Authorization: Token <your_token>
Example Response
meta.sort echoes the effective sort preset or custom sort string from the request. meta.fields is the sorted selected field allowlist (view, default set, or fields=). Some keys (e.g. similarity) are only present on each card when semantic search is enabled; they may still appear in meta.fields as part of the default template.
Response fields (cards list)
- Always present in default view (required):
id,slug,name,public_url,interactions_count,trending,stage,round,categories,created_at,updated_at,social_links,open_to_intro,has_intro_request. Thestageandroundobjects always havename;slugmay be null. - User-scoped optional field:
user_datais included in personalized mode (include_user_data=true);noteandfoldersinside it may be null/empty. - May be null (optional):
description,image,url,location,last_round,last_interaction_at,first_interaction_at. Iflocationis present, its subfields (formatted,slug,city,state,country,region,region_slug,type) may be null. - Semantic search only:
similarity(float, 0.0-1.0) — cosine similarity score indicating how well the card matches the semantic query. Only present whensemantic=1is used. Higher values (closer to 1.0) indicate better matches. Practical range: typically 0.3-0.9; values above 0.9 are extremely rare. - Field selection: when
fieldsorview=compactis used, response includes the selected subset of top-level fields.
Get Cards List (POST)
POST /v1/cards/
Same listing and filtering behavior as Get Cards List (GET), but parameters are sent in a JSON body. Use this when filters are too large for a query string (e.g. many categories or participant slugs).
Important: POST accepts the same parameters as GET, but in the JSON body. Lists are arrays, not comma-separated strings.
Request body (JSON)
All parameters mirror GET; passing details:
limit(integer) — number of records per page (maximum 100, default 20)offset(integer) — offset from the start of the list (default 0)include_total(boolean) — include total count in pagination (trueby default)sort(string) — sorting:trending,recent,most_activeor custom formatfield:directioninclude_user_data(boolean) — includes user data (favorites, notes, folders)view(string) —defaultorcompactfields(array[string] or comma-separated string) — top-level fields to returnstages(array[string]) — filter by stages (array):["seed", "series_a"]rounds(array[string]) — filter by rounds (array):["raising_now", "just_raised"]categories(array[string]) — filter by categories (array):["ai", "saas"]locations(array[string]) — filter by locations (array):["san_francisco_ca", "bay_area"]participants(array[string]) — filter by participants (array):["investor-fund"]display_preference(string) — filter by type:web3,web2,allfilter_id(integer) — apply saved user filterfolder_ids(array[integer]) — filter by folders (array):[1, 2, 3]created_after,created_before(string) — filter by creation date (format: YYYY-MM-DD)updated_after,updated_before(string) — filter by update datelast_interaction_after,last_interaction_before(string) — filter by last interaction datefirst_interaction_after,first_interaction_before(string) — filter by first interaction datesearch(string) — optional text query; with"semantic": trueit is used for semantic search over embeddingssemantic(boolean) — enables semantic search when used withsearch; same behavior as in GET cards list
Example Request
Basic POST request:
POST /v1/cards/
Content-Type: application/json
Authorization: Token <your_token>
{
"limit": 20,
"offset": 0,
"sort": "recent"
}
POST with large filter volume:
POST /v1/cards/
Content-Type: application/json
Authorization: Token <your_token>
{
"limit": 50,
"offset": 0,
"sort": "trending",
"stages": ["seed", "series_a", "series_b"],
"categories": ["ai", "saas", "b2b", "fintech", "healthcare"],
"locations": ["san_francisco_ca", "new_york_ny", "london_united_kingdom"],
"participants": ["investor-fund-1", "investor-fund-2", "investor-fund-3"],
"created_after": "2024-01-01",
"folder_ids": [1, 2, 3, 4, 5]
}
POST with custom sorting:
POST /v1/cards/
Content-Type: application/json
Authorization: Token <your_token>
{
"limit": 20,
"offset": 0,
"sort": "name:asc,created_at:desc",
"categories": ["ai", "saas"]
}
Note: Custom sorting is passed as a string in format field:direction,field:direction (same format as in GET request). For example:
"sort": "name:asc"— sort by name ascending"sort": "created_at:desc,interactions_count:desc"— first by creation date (descending), then by interactions count (descending)
Example Response
Response format is identical to GET method (see above).
Get Card by Slug
GET /v1/cards/<slug>/
Get detailed information about a specific card by its slug.
Parameters
| Parameter | Type | Description |
|---|---|---|
include_user_data | boolean | Include favorites, notes, folders |
Response metadata
| Field | Type | Description |
|---|---|---|
meta.include_user_data | boolean | Effective include_user_data for this response |
Example Request
GET /v1/cards/project-slug/?include_user_data=true
Authorization: Token <your_token>
Example Response
Get Card Interactions
GET /v1/cards/<slug>/interactions/
Get all interactions (signals) for a card with pagination.
Parameters
| Parameter | Type | Description |
|---|---|---|
limit | integer | Page size (max 200, default 50) |
offset | integer | Offset from start |
include_total | boolean | Include total in pagination (true by default). false skips count() for faster pages |
Example Request
GET /v1/cards/project-slug/interactions/?limit=50&offset=0
Authorization: Token <your_token>
Example Response
Reference Data
All reference values (stages, rounds, categories, locations, participant types, folders, filters) should be loaded from the meta endpoints below. They return complete slug/ID lists for filters and UI.
Note: Responses may include lightweight counters in meta (e.g. total, us_regions_total, world_regions_total) for caching and UI.
Categories
GET /v1/cards/categories/
Hierarchical categories (parents and children) for categories= filters.
Example response
Stages
GET /v1/cards/stages/
Stage slugs for stages= filters (e.g. seed, series_a).
Example response
Rounds
GET /v1/cards/rounds/
Round slugs for rounds= filters (e.g. raising_now, just_raised).
Example response
Locations
GET /v1/cards/locations/
Regions and cities for locations= filters.
Example response
User Folders
GET /v1/cards/folders/
Folders for the authenticated user; use with folder_ids=.
Example response
Saved Filters
GET /v1/cards/filters/
Saved filters; apply with filter_id.
Example response
Participants
Participants are funds, investors, angels, and related entities. List, fetch by slug, batch-fetch, and resolve type slugs for type= filters.
Get Participants List
GET /v1/participants/
Get list of participants (funds, investors, angels) with pagination and filtering.
Main Parameters
| Parameter | Type | Description |
|---|---|---|
limit | integer | Records per page (max 200, default 50) |
offset | integer | Offset from start |
include_total | boolean | Include total count in pagination (true by default). Set false to skip expensive count() on large filtered datasets |
search | string | Search by name/description; with semantic=1 it becomes semantic search |
sort | string | Preset or custom sort (default: name) |
include_user_data | boolean | Include is_saved |
Sort presets
| Preset | Description |
|---|---|
name | By name (asc, default) |
most_active | By monthly signals (desc), then name (asc) |
Custom sort: field:direction or field1:dir1,field2:dir2
Available fields: name, monthly_signals
Directions: asc, desc
Filters
| Parameter | Type | Description |
|---|---|---|
type | string | Filter by type (fund, investor, angel, etc.). Values: participant types |
web3 | boolean | Filter by web3 focus (web3=true) |
web2 | boolean | Filter by web2 focus (web2=true) |
saved_only | boolean | Show only saved participants |
Semantic search (participants)
What it is: Semantic search finds participants by meaning and context, not just by exact words. For example, "web3 venture fund" can match funds that describe themselves in different terms but have the same focus. Results are ordered by how closely they match the intent of your query.
-
semantic(boolean-like string) — enables this search mode when used together withsearch:- Allowed values:
1,true,yes(case-insensitive) - Behavior:
- Text from
searchis transformed into semantic vectors by our internal retrieval pipeline. - All other filters (type, web3, web2, etc.) are applied first.
- Matching participants with non-null embeddings are ordered by cosine similarity to the query embedding.
- Results are filtered by relevance threshold (default
min_similarity=0.3). - Each result includes a
similarityfield (0.0-1.0) indicating how well it matches the query. - Pagination (
limit,offset) works as usual.
- Text from
- If embeddings are temporarily unavailable, the API may return
503witherror: "semantic_unavailable".
- Allowed values:
-
min_similarity(float) — minimum cosine similarity threshold for semantic search (only used withsemantic=1):- Range:
0.0to1.0(where1.0= perfect match,0.0= no similarity) - Practical range:
0.3to0.9(values above 0.9 are extremely rare and indicate near-perfect matches) - Default:
0.3(filters out clearly irrelevant results while keeping good matches) - Recommended values:
0.7-0.9— very strict (only highly relevant results, fewer matches)0.5-0.7— strict (good quality results)0.3-0.5— default (balanced, filters obviously irrelevant)0.0-0.3— lenient (more results, may include less relevant)
- Higher values = more relevant results, but fewer matches
- Lower values = more results, but may include less relevant ones
- Note: Setting
min_similarityabove0.9will likely return very few or no results, as perfect matches are extremely rare
- Range:
Example Request
GET /v1/participants/?limit=50&offset=0&type=fund&web3=true&sort=most_active
Authorization: Token <your_token>
Example Response
Note: Field is_saved appears only when include_user_data=true is specified in the request.
Get Participant by Slug
GET /v1/participants/<slug>/
Get detailed information about a participant by slug.
Parameters
| Parameter | Type | Description |
|---|---|---|
include_user_data | boolean | Include is_saved and related personalization flag when applicable |
Example Request
GET /v1/participants/investor-fund/?include_user_data=true
Authorization: Token <your_token>
Example Response
Get Multiple Participants
GET /v1/participants/batch/
Get multiple participants by list of slugs (batch operation, maximum 100).
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
slugs | string | yes | Comma-separated slugs, e.g. investor-fund,john-doe |
include_user_data | boolean | no | Include is_saved when applicable |
Example Request
GET /v1/participants/batch/?slugs=investor-fund,john-doe,another-fund
Authorization: Token <your_token>
Example Response
Participant Types
GET /v1/participants/types/
Type slugs for type= filters (fund, investor, angel, …).
Example response
Utilities
Health-style helpers that do not return domain objects.
Validate Token
GET /v1/token/validate/
Check that the Authorization: Token … header is accepted.
Example Request
GET /v1/token/validate/
Authorization: Token <your_token>
Example Response
200 OK with:
Glossary
Field-by-field reference for JSON payloads. Presence: required — always present for that resource/view; optional — may be omitted (e.g. sparse fieldsets); nullable — key may be present with null; semantic only — only when semantic=1 is used with search.
Card Attributes
Basic Fields
| Field | Type | Presence | Description |
|---|---|---|---|
id | integer | required | Unique card ID |
slug | string | required | URL-friendly identifier (e.g. thinkymachines) |
name | string | required | Project/company or person name |
public_url | string | required | Public page on the platform (e.g. https://app.theveck.com/public/thinkymachines) |
description | string | nullable | Detailed project description |
image | string | nullable | Absolute image/logo URL |
url | string | nullable | Website or profile URL |
Status and Metrics
| Field | Type | Presence | Description |
|---|---|---|---|
interactions_count | integer | required | Total signals/interactions for the card |
trending | boolean | required | Whether the card is trending (recent activity) |
stage | object | required | Stage; always includes name; slug may be null. Allowed slugs: stages |
round | object | required | Round; always includes name; slug may be null. Allowed slugs: rounds |
stage / round object
| Field | Type | Presence | Description |
|---|---|---|---|
name | string | required | Human-readable label (e.g. "Seed", "Raising Now") |
slug | string | nullable | Filter slug (e.g. seed, raising_now) |
Categories
| Field | Type | Presence | Description |
|---|---|---|---|
categories | array | required | Category objects; filtering is hierarchical (parent includes children). See categories |
Each category item
| Field | Type | Presence | Description |
|---|---|---|---|
name | string | required | Display name (e.g. "AI") |
slug | string | required | Filter slug (e.g. ai) |
Location
| Field | Type | Presence | Description |
|---|---|---|---|
location | object | nullable | Omitted as null if empty or placeholder-only ("Unknown", etc.). Valid slugs: locations |
When location is an object
| Field | Type | Presence | Description |
|---|---|---|---|
formatted | string | nullable | Full formatted label |
slug | string | nullable | Location slug for filters |
city | string | nullable | City |
state | string | nullable | State / province code |
country | string | nullable | Country name |
region | string | nullable | Region name |
region_slug | string | nullable | Region slug |
type | string | nullable | e.g. city, country |
Dates
| Field | Type | Presence | Description |
|---|---|---|---|
created_at | string (ISO 8601 UTC) | required | Card creation time |
updated_at | string (ISO 8601 UTC) | required | Last update time |
last_round | string (YYYY-MM-DD) | nullable | Last funding round date |
last_interaction_at | string (ISO 8601 UTC) | nullable | Most recent interaction |
first_interaction_at | string (ISO 8601 UTC) | nullable | First interaction |
Social Links
| Field | Type | Presence | Description |
|---|---|---|---|
social_links | array | required | List of link objects |
Each social_links item
| Field | Type | Presence | Description |
|---|---|---|---|
key | string | required | Normalized platform id (e.g. twitter) |
name | string | required | Display name |
url | string | required | Profile URL |
User Data (include_user_data=true)
| Field | Type | Presence | Description |
|---|---|---|---|
user_data | object | optional | Only when personalization is requested |
user_data object
| Field | Type | Presence | Description |
|---|---|---|---|
is_liked | boolean | required | User favorited the card |
has_note | boolean | required | User has a note |
note | object | nullable | Present when has_note is true |
folders | array | required | Folders containing this card (may be empty) |
user_data.note
| Field | Type | Presence | Description |
|---|---|---|---|
text | string | required | Note body |
created_at | string | required | Note created (ISO 8601 UTC) |
updated_at | string | required | Note updated (ISO 8601 UTC) |
Each folder item
| Field | Type | Presence | Description |
|---|---|---|---|
id | integer | required | Folder ID |
name | string | required | Folder name |
List and Detail (common)
| Field | Type | Presence | Description |
|---|---|---|---|
open_to_intro | boolean | required | Card accepts intro requests |
has_intro_request | boolean | required | Current user has an intro request for this card |
Semantic Search
| Field | Type | Presence | Description |
|---|---|---|---|
similarity | float | semantic only | Cosine similarity vs query (0.0–1.0). Typical useful range ~0.3–0.9 |
Card Detail Only
| Field | Type | Presence | Description |
|---|---|---|---|
people | array | optional | Team/contact rows: id, name, type, image, twitter_url, linkedin_url, crunchbase_url, reference_url, github_url, email, bio |
linkedin_data | object | optional | Structured LinkedIn-derived data |
more | object | nullable | Extra project fields |
employment_data | object | nullable | Employment-related fields |
interactions | array | optional | Up to 20 recent interactions (same shape as Interaction Attributes) |
has_more_interactions | boolean | optional | If true, use GET /v1/cards/<slug>/interactions/ for full history |
linkedin_data
| Field | Type | Presence | Description |
|---|---|---|---|
tags | array | optional | { "name", "type" } where type is school, accelerator, or job |
education | array | optional | Strings |
experience | array | optional | Strings (e.g. "Role at Co (dates)") |
Participant Attributes
Basic Fields
| Field | Type | Presence | Description |
|---|---|---|---|
slug | string | required | API identifier (e.g. a16z) |
name | string | required | Display name |
alt_name | string | nullable | Alternate name (e.g. "VC") |
email | string | nullable | Contact email |
image | string | nullable | Logo/avatar URL |
about | string | nullable | Description |
Type and Focus
| Field | Type | Presence | Description |
|---|---|---|---|
type | string | required | e.g. fund, investor, angel. See participant types |
web3 | boolean | required | Web3/crypto focus |
web2 | boolean | required | Web2/traditional focus |
Metrics
| Field | Type | Presence | Description |
|---|---|---|---|
monthly_signals | integer | required | Signals per month |
Semantic Search
| Field | Type | Presence | Description |
|---|---|---|---|
similarity | float | semantic only | Same semantics as card similarity |
Relationships
| Field | Type | Presence | Description |
|---|---|---|---|
associated_with | object | nullable | Parent org when applicable |
self_associated | boolean | required | Often true for funds |
associated_with
| Field | Type | Presence | Description |
|---|---|---|---|
slug | string | required | Parent slug |
name | string | required | Parent name |
User Data (include_user_data=true)
| Field | Type | Presence | Description |
|---|---|---|---|
is_saved | boolean | optional | User saved this participant |
Participant Detail Only (sources)
| Field | Type | Presence | Description |
|---|---|---|---|
sources | array | optional | External profiles |
Each sources item
| Field | Type | Presence | Description |
|---|---|---|---|
slug | string | required | Source id |
type | string | required | e.g. twitter, linkedin |
link | string | required | Full URL |
Interaction Attributes
| Field | Type | Presence | Description |
|---|---|---|---|
id | integer | required | Interaction ID |
created_at | string | required | ISO 8601 UTC |
participant | object | required | Main participant |
associated_participant | object | nullable | Co-participant when applicable |
participant / associated_participant summary object
| Field | Type | Presence | Description |
|---|---|---|---|
name | string | required | Display name |
slug | string | required | Participant slug |
type | string | required | Participant type slug |
Pagination Attributes
| Field | Type | Presence | Description |
|---|---|---|---|
limit | integer | required | Page size |
offset | integer | required | Offset |
total | integer | nullable | null when include_total=false |
has_next | boolean | required | More pages available |
Notes
Cross-cutting behavior for every endpoint: error JSON, successful payload shape, and date formats.
Error Handling
All errors are returned in JSON format:
Main Error Codes
401 Unauthorized— authentication required or invalid token404 Not Found— resource not found400 Bad Request— data validation error429 Too Many Requests— request limit exceeded500 Internal Server Error— internal server error
Example Error Responses
Rate limit exceeded (429) - Paid access:
Rate limit exceeded (429) - Free access:
Response Format
All successful responses contain a data field with data and an optional pagination field for lists. List endpoints may also include meta:
Date Formats
Request parameters (date filters): Use YYYY-MM-DD format (e.g., 2025-01-15)
- Applies to:
created_after,created_before,updated_after,updated_before,last_interaction_after,last_interaction_before,first_interaction_after,first_interaction_before
Response fields (date-time): Use ISO 8601 UTC format with time (e.g., 2025-01-15T10:30:00Z)
- Applies to:
created_at,updated_at,last_interaction_at,first_interaction_at, and all datetime fields in responses
Exception: last_round field in responses uses YYYY-MM-DD format (date only, e.g., 2025-01-15)