Your first API request
Bring company intelligence into your own tools. Read company profiles, find jobs, and retrieve research with a single API key.
https://www.enterpriseaitrends.com/api/v1Create an API key
Sign in to your account, then create or select an organization. Under API keys, choose a personal key, give it a name, and select an expiry. Copy the key when it appears; it is only shown once.
Get your API keyMake a request
Set FDE_API_KEY in your terminal or secret manager, then check the identity associated with your key.
export FDE_API_KEY="YOUR_API_KEY"
curl --fail-with-body \
-H "X-Api-Key: $FDE_API_KEY" \
"https://www.enterpriseaitrends.com/api/v1/me"A successful request returns HTTP 200 and a JSON body. For a personal key:
{
"data": {
"type": "user",
"userId": "user_example",
"email": null,
"name": null,
"organizationId": "org_example"
}
}Explore the catalog
Fetch a page of companies. Use an id, slug, or domain from the response to look up a company, find its jobs, or retrieve its research.
curl --fail-with-body \
-H "X-Api-Key: $FDE_API_KEY" \
"https://www.enterpriseaitrends.com/api/v1/companies?limit=5"Get started
MCP
Search jobs and explore companies from your AI assistant. The Model Context Protocol (MCP) gives your assistant tools to read live Enterprise AI Trends data as you chat.
https://mcp.enterpriseaitrends.com/mcpConnect with browser sign-in
Add the hosted URL to your AI client, sign in to Enterprise AI Trends, choose your organization, and approve the requested access. Return to your client when authorization completes. No API key is needed.
Claude Code
claude mcp add --transport http --scope user enterprise-ai-trends https://mcp.enterpriseaitrends.com/mcpOpen /mcp in Claude Code, select Enterprise AI Trends, and follow the browser sign-in instructions.
Codex
[mcp_servers.enterprise-ai-trends]
url = "https://mcp.enterpriseaitrends.com/mcp"codex mcp login enterprise-ai-trendsWhen moving from API keys, remove this server’s existing authentication header or bearer_token_env_var setting so the client can use OAuth.
Claude and ChatGPT
In your client’s custom connector or MCP app settings, add the hosted URL above and choose OAuth if asked. Follow the browser sign-in and approval flow, then enable the connection in your conversation. Custom connections depend on your client’s plan and workspace permissions; ChatGPT may require developer mode and administrator approval.
The client stores your access and refresh tokens. Access tokens last 10 minutes; refresh tokens last up to 30 days and rotate on use. Revoking a refresh token prevents further refreshes; an already issued access token can remain valid until it expires. Removing organization membership stops catalog access when the backing API next checks it.
Optional: connect with an API key
API keys remain available for scripts and clients that support custom headers. Choose either OAuth or an API key for a connection.
1. Create your key
Sign in to your account, create or select an organization, and create a personal API key. Copy it when it appears, then set it in your terminal:
export FDE_API_KEY="YOUR_API_KEY"Send API keys in X-Api-Key. OAuth access tokens use an Authorization: Bearer header. Keep your key out of chat messages and shared configuration files.
2. Connect Claude Code or Codex
Claude Code
Run this command in the terminal where you set your key:
claude mcp add --transport http --scope user enterprise-ai-trends https://mcp.enterpriseaitrends.com/mcp \
--header "X-Api-Key: $FDE_API_KEY"Open Claude Code and use /mcp to check the connection. This command saves the expanded key in your local user configuration. See the Claude Code MCP guide.
Codex
Add this entry to ~/.codex/config.toml:
[mcp_servers.enterprise-ai-trends]
url = "https://mcp.enterpriseaitrends.com/mcp"
env_http_headers = { "X-Api-Key" = "FDE_API_KEY" }Start Codex from the terminal where FDE_API_KEY is set. The Codex app also needs that variable in its own environment. See the Codex MCP guide.
3. Try a prompt
Use Enterprise AI Trends to find remote forward-deployed engineering jobs (role_category: "fde"). Read the descriptions for three relevant roles and show their requirements, company profiles, and application links.You can also ask: “Which company classifications are available?” or “Look up Anthropic and show its active roles.”
| Tool | What it does |
|---|---|
search_jobs | Find active roles by keyword, company, location, role category, or remote policy. |
get_job | Read a job’s full description using its UUID. |
list_companies | Browse companies with search and classification filters. |
get_company | Look up a company by slug or UUID, including tags and active job count. |
list_job_categories | Discover job categories, their meanings, and client-facing group membership. |
list_tags | Discover the available classification tags and filter values. |
get_account_info | Read your identity, organization, capabilities, and remaining rate-limit budget. Credit balances are unavailable. |
get_stats | Read catalog totals and jobs discovered in the last 24 hours, with an explicit UTC window. |
Search tools default to cursor pagination. Continue using meta.nextCursor with the same filters and limit until hasMore is false. Sessions expire after 15 minutes; start a new search after expiry. Supplying page selects legacy page mode. Counts in cursor mode describe visible snapshot candidates, not every relevant job. These tools read catalog data. Keyword and conceptual searches return a ranked selection, not every possible match. The response metadata states the count scope, whether completeness is known, and whether another page is available. Company list management and research report endpoints remain available through the REST API; they are not exposed as MCP tools yet.
Client setup references: ChatGPT, Codex, and Claude Code.
Discover filters before searching
Call list_job_categories, then pass a returned id to search_jobs as role_category. Call list_tags, then pass a returned slug to list_companies, for example market: "healthcare". Multiple slugs within a dimension use OR; dimensions combine with AND. For job search, pass employer tags under company_filters; keep job categories in role_category. These tools return the complete supported vocabulary, not counts or a guarantee of matching records.
{
"role_category": "fde",
"company_filters": {
"market": [
"healthcare"
]
},
"pagination": "cursor"
}This requires the employer’s stored healthcare classification. Adding a search phrase ranks matching jobs by their content; it does not replace the employer tag requirement or infer a missing classification.
Use get_account_info when you need account or request-budget information; no identity preflight is needed before searches. Each tool operation consumes one API request. Protocol authentication does not consume the catalog budget, though API-key provider abuse limits still apply. Budgets are per API instance, not billing credits. On RATE_LIMITED, wait for retryAfter; reconnecting is not a remedy. Disconnecting does not revoke your OAuth grant. Manage or revoke connections in Account settings → Connected apps. Revoking a grant stops future refreshes; an issued access token may remain valid until its ten-minute expiry. Membership removal is checked on subsequent backend requests.
Interpret remote roles and counts
A listing with remotePolicy: "remote" and location “Remote — United States only” passes remote_only. It does not establish eligibility outside the US. Read the source location and full description; structured geographic eligibility remains unknown. Company headquarters do not establish work eligibility.
role_category: "fde" selects FDE roles alone. client_facing: true also includes solutions engineering, customer success, technical account management, sales, and other adjacent categories. FDE counts are included in that broader group. Stats describe active visible catalog records at the stated time, not all jobs worldwide.
Troubleshooting
A 401 Unauthorized response means you should check that your key is present, unexpired, and not revoked. For Codex, check that its process can read FDE_API_KEY. For OAuth, reconnect if authorization expired or was revoked. If browser sign-in is unavailable during rollout, use the optional API-key setup. For rate-limit errors, pause before retrying; see rate limits.
Get started
Authentication
Every endpoint in this reference requires an API key. Send it in one of these headers on each request:
X-Api-Key: YOUR_API_KEY
Authorization: Bearer YOUR_API_KEYKeep the key on your server or in a secret manager. Do not put it in a query string, commit it to source control, or embed it in a public website.
| Field | Description |
|---|---|
Personal keypk_live_… | Bound to your user and one organization. You must remain a member of that organization for the key to work. |
Organization keysk_live_… | Bound to an organization. Organization owners and admins can create these keys for shared integrations. |
Both key types can read the catalog endpoints below. List management requires a personal key. Set an expiry of 7, 30, 90, or 365 days when creating a key (default: 90 days). Revoke a key from your account when you no longer need it. Expired or revoked keys return 401.
Get started
Pagination & filtering
Company and job lists return a data array and a meta object. Single-record endpoints return an object under data. JSON field names use camelCase; query parameters use the names listed in each endpoint.
For stable traversal, start with pagination=cursor. Continue with meta.nextCursor as the cursorparameter, repeating the same filters and limit, until hasMore=false. Do not send a page number. Sessions expire after 15 minutes (410); malformed or mismatched cursors return 400. Restart without a cursor after expiry.
Cursor sessions freeze candidate membership and order. New matches appear in a new session; returned fields stay current, and hidden, deleted, or inactive records are skipped. Updates do not rerank or reapply the original filters. Counts cover visible snapshot candidates; search caps and unknown completeness still apply. Legacy page mode can shift when data changes; totalPages covers only accessible pages.
{
"data": [],
"meta": {
"pagination": "page",
"nextCursor": null,
"page": 1,
"limit": 20,
"total": 0,
"totalPages": 0,
"totalScope": "filtered_catalog",
"searchMode": "filter",
"totalMatches": 0,
"totalRelation": "exact",
"truncated": false,
"accessibleTotal": 0,
"accessibleTotalPages": 0,
"hasMore": false,
"resultWindow": 1000,
"searchLimit": null,
"correctedQuery": null
}
}| Field | Description |
|---|---|
page / limitnumber | The page number and effective page size after defaults are applied; page is null in cursor mode. |
total / totalPagesnumber | Legacy pagination count and page count: filtered rows without search, ranked candidates for hybrid search, or capped substring matches on fallback. These are not globally exhaustive search counts; read totalScope and totalRelation. |
searchMode / totalScopestring | How results were retrieved (filter, hybrid, substring_fallback, invalid_query) and what total counts (filtered_catalog, ranked_candidates, substring_matches, snapshot_candidates). |
totalMatches / totalRelationnumber | null / string | Exact matching count for the stated retrieval mode when relation is exact. Page-mode hybrid search reports null and unknown. Cursor mode reports an exact count of currently visible snapshot candidates, never all relevant catalog matches. Counts describe this catalog and the applied filters, not the global market. |
truncatedboolean | null | True means known results were omitted by a cap/window; false means the stated exact result set is complete; null means completeness is unknown. Reaching the final page does not establish exhaustive search coverage. |
accessibleTotal / accessibleTotalPages / hasMorenumber / number / boolean | Retrievable result count and pages within the window, and whether another page is accessible. Use hasMore rather than legacy totalPages to decide whether to continue. |
resultWindow / searchLimitnumber / number | null | Maximum accessible results for this request. Search is capped at 100; filter-only requests have no search cap but still have a tier window. |
correctedQuerystring | null | Spelling correction attempted by hybrid search. Substring fallback searches the original text, even if a correction was attempted. |
Pages start at 1. Companies default to 50 items per page (maximum 100); jobs default to 20 (maximum 50). Missing values use defaults. Invalid, repeated, zero, negative, or out-of-range values return 400.
A page cannot start at or beyond result 1001. Deeper requests return 400 RESULT_WINDOW_EXCEEDED. Search queries return at most 100 matches. Narrow your filters instead of continuing beyond these limits.
Use --data-urlencode with cURL to safely encode filter values. For example, find remote engineering roles:
curl --fail-with-body --get \
-H "X-Api-Key: $FDE_API_KEY" \
--data-urlencode "role_category=engineering" \
--data-urlencode "remote_only=true" \
--data-urlencode "limit=10" \
"https://www.enterpriseaitrends.com/api/v1/jobs"Get started
Rate limits
The API allows 100 requests per minute. Personal keys share a request budget per user; organization keys have a budget per key. When that budget is exhausted, requests return 429 RATE_LIMITED.
| Field | Description |
|---|---|
X-RateLimit-Limitinteger | Request budget for the current window: 100. |
X-RateLimit-Remaininginteger | Requests remaining in the current window. |
Retry-Afterinteger · on 429 | Seconds to wait before retrying. Pause requests for this duration. |
X-Api-Tierstring | token for authenticated API requests. |
Cache responses where practical and avoid tight retry loops. Key verification also has a shared limit of 600 checks per minute per key across services; exceeding it can return 401. If a valid key starts failing during a burst of requests, pause for a minute before trying again.
Get started
Errors
Check the HTTP status before reading data. API errors use an error object with a stable code and a human-readable message.
{
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid, expired or revoked API key"
}
}| Field | Description |
|---|---|
401 · UNAUTHORIZEDAuthentication | Missing, malformed, invalid, expired, or revoked key; a personal key also fails if its owner leaves the organization. Check your header and key in your account. |
400 · RESULT_WINDOW_EXCEEDEDPagination | The requested page starts beyond the allowed result window. Narrow the query or request an earlier page. |
404 · NOT_FOUNDMissing resource | The requested record or stored research report was not found. Check the identifier; not every company has research. |
429 · RATE_LIMITEDRate limit | Wait for the number of seconds in Retry-After before sending another request. |
500 · INTERNALServer error | The API could not complete the request. Retry after a delay. If it persists, check the identifier and retain the status and response for troubleshooting. |
API reference
Read the catalog
Catalog endpoints use GET and return JSON. Company list management follows the catalog reference. Examples use fictional records and counts; retrieve live identifiers from the list endpoints. Profile and research fields may be null when information is unavailable.
/meAccount and request budget
Read your credential identity, organization, capabilities, and remaining request budget. Call when needed; other endpoints authenticate independently. This request consumes one API unit.
curl --fail-with-body \
-H "X-Api-Key: $FDE_API_KEY" \
"https://www.enterpriseaitrends.com/api/v1/me"| Field | Description |
|---|---|
capabilities / scopesobject / array | Current credential privileges; OAuth remains read-only with no account-management access. |
rateLimitobject | null | limit, remaining (after this request), windowSeconds, nextAvailableAt, and scope. Best-effort per API instance: user bucket for personal/OAuth credentials, credential bucket for organization keys. nextAvailableAt is the next slot release, not a full-budget reset. |
creditsobject | status unavailable and remaining null until billing exists. Never interpreted as zero or unlimited. |
typestring | user for a personal key; organization for an organization key. |
organizationIdstring | null | Organization the key is bound to. |
userIdstring · personal keys | The personal key’s owner. |
email / namestring | null · personal keys | Nullable compatibility fields; profile details are not fetched by this endpoint. |
Example response 200 · application/json
{
"data": {
"type": "user",
"userId": "user_example",
"email": null,
"name": null,
"organizationId": "org_example"
}
}/companiesList companies
Browse active, visible companies or find companies by search and classification tags. Without a search term, results are ordered by active job count, profile completeness, then name.
| Field | Description |
|---|---|
paginationstring | page (default) or cursor. Cursor mode freezes result order for 15 minutes. |
cursorstring | Continue with meta.nextCursor, repeating filters and limit. Cannot combine with page. |
pageinteger | Page number, starting at 1. Default: 1. |
limitinteger | Items per page. Default: 50; maximum: 100. Invalid or larger values return 400. |
searchstring | Search by name or a description of what the company does. Search returns up to 100 ranked matches. |
organization_typestring | Comma-separated tag slugs from GET /tags. Matches any supplied slug within this dimension; separate dimensions must all match. |
ecosystemstring | Comma-separated tag slugs from GET /tags. Matches any supplied slug within this dimension; separate dimensions must all match. |
activitystring | Comma-separated tag slugs from GET /tags. Matches any supplied slug within this dimension; separate dimensions must all match. |
specializationstring | Comma-separated tag slugs from GET /tags. Matches any supplied slug within this dimension; separate dimensions must all match. |
marketstring | Comma-separated tag slugs from GET /tags. Matches any supplied slug within this dimension; separate dimensions must all match. |
customer_segmentstring | Comma-separated tag slugs from GET /tags. Matches any supplied slug within this dimension; separate dimensions must all match. |
delivery_modelstring | Comma-separated tag slugs from GET /tags. Matches any supplied slug within this dimension; separate dimensions must all match. |
revenue_modelstring | Comma-separated tag slugs from GET /tags. Matches any supplied slug within this dimension; separate dimensions must all match. |
listing_statusstring | Comma-separated tag slugs from GET /tags. Matches any supplied slug within this dimension; separate dimensions must all match. |
funding_stagestring | Comma-separated tag slugs from GET /tags. Matches any supplied slug within this dimension; separate dimensions must all match. |
funding_tierstring | Comma-separated tag slugs from GET /tags. Matches any supplied slug within this dimension; separate dimensions must all match. |
curl --fail-with-body \
-H "X-Api-Key: $FDE_API_KEY" \
"https://www.enterpriseaitrends.com/api/v1/companies?limit=1"| Field | Description |
|---|---|
parentCompanyId / entityScopestring | null | Reviewed subdivision identity; a shared host does not imply the same organization. |
classificationAssessmentsobject | null | Per-dimension known, unknown or not_applicable status with an evidence-based reason. Null before ontology assessment. |
idstring | Company UUID. Use this or the slug to retrieve the company. |
name / slugstring | Display name and URL slug. |
domain / website / logoUrlstring | null | Company domain, website URL, and logo URL. |
description / headcountRange / hqLocationstring | null | Company profile and headquarters. Missing profile facts are null. |
totalFunding / latestValuation / annualRevenuestring | null | Display text, not numeric currency values. Do not assume these can be parsed as numbers. |
sourceKind / sourcePlatform / sourceUrlstring | null | Preferred active job source: its kind, platform, and URL. Null when no source is available. |
activeJobCountnumber | Number of active jobs at this company. |
tagsarray<object> | Classification tags, each with dimension, value (display label), and slug (filter value). May be empty. |
matchType / matchStrength / matchedTermsoptional | Ranked search results may add matchType (keyword, semantic, or both), matchStrength (strong, good, or weak), and matchedTerms (string array). These fields are absent from ordinary listings and may be absent on search fallback results. |
Example response 200 · application/json
{
"data": [
{
"id": "3c123740-3ef5-4d1e-b701-08a8f2d30a12",
"name": "Example AI",
"slug": "example-ai",
"domain": "example.com",
"website": "https://example.com",
"logoUrl": null,
"headcountRange": "11-50",
"description": "Tools for building AI applications.",
"hqLocation": "New York, NY",
"totalFunding": null,
"latestValuation": null,
"annualRevenue": null,
"sourceKind": null,
"sourcePlatform": null,
"sourceUrl": null,
"activeJobCount": 1,
"tags": []
}
],
"meta": {
"page": 1,
"limit": 1,
"total": 1,
"totalPages": 1
}
}/companies/{id}Get a company
Retrieve a company’s profile, classification tags, and job count. Use an id or slug returned by the company list.
| Field | Description |
|---|---|
idstring · required | Company UUID or slug. |
Set COMPANY_ID to a value from the corresponding list response before running this request.
curl --fail-with-body \
-H "X-Api-Key: $FDE_API_KEY" \
"https://www.enterpriseaitrends.com/api/v1/companies/$COMPANY_ID"| Field | Description |
|---|---|
parentCompanyId / entityScopestring | null | Reviewed subdivision identity; a shared host does not imply the same organization. |
classificationAssessmentsobject | null | Per-dimension known, unknown or not_applicable status with an evidence-based reason. Null before ontology assessment. |
idstring | Company UUID. Use this or the slug to retrieve the company. |
name / slugstring | Display name and URL slug. |
domain / website / logoUrlstring | null | Company domain, website URL, and logo URL. |
description / headcountRange / hqLocationstring | null | Company profile and headquarters. Missing profile facts are null. |
totalFunding / latestValuation / annualRevenuestring | null | Display text, not numeric currency values. Do not assume these can be parsed as numbers. |
sourceKind / sourcePlatform / sourceUrlstring | null | Preferred active job source: its kind, platform, and URL. Null when no source is available. |
activeJobCountnumber | Number of active jobs at this company. |
tagsarray<object> | Classification tags, each with dimension, value (display label), and slug (filter value). May be empty. |
oneLiner / keyInvestors / linkedinUrl / careersUrlstring | null | Short description, investor information, LinkedIn URL, and careers URL. |
enrichmentUpdatedAt / lastRunAtstring | null | ISO 8601 timestamps for the last profile enrichment and job-source run, respectively. |
Example response 200 · application/json
{
"data": {
"id": "3c123740-3ef5-4d1e-b701-08a8f2d30a12",
"name": "Example AI",
"slug": "example-ai",
"domain": "example.com",
"website": "https://example.com",
"logoUrl": null,
"headcountRange": "11-50",
"description": "Tools for building AI applications.",
"hqLocation": "New York, NY",
"totalFunding": null,
"latestValuation": null,
"annualRevenue": null,
"sourceKind": null,
"sourcePlatform": null,
"sourceUrl": null,
"activeJobCount": 1,
"tags": [],
"oneLiner": "Tools for AI developers.",
"keyInvestors": null,
"linkedinUrl": null,
"careersUrl": "https://example.com/careers",
"enrichmentUpdatedAt": null,
"lastRunAt": null
}
}/jobsList jobs
Find active jobs at visible companies. Without a search term, the most recently observed new jobs come first. Combine filters to narrow the results.
| Field | Description |
|---|---|
paginationstring | page (default) or cursor. Cursor mode freezes result order for 15 minutes. |
cursorstring | Continue with meta.nextCursor, repeating filters and limit. Cannot combine with page. |
pageinteger | Page number, starting at 1. Default: 1. |
limitinteger | Items per page. Default: 20; maximum: 50. Invalid or larger values return 400. |
company_filtersJSON object | Employer metadata, separate from job fields. Example: {"market":["healthcare"],"activity":["software-applications"]}. URL-encode JSON; use dimensions/slugs from /tags. OR within dimensions, AND across dimensions and job filters. Invalid dimensions, slugs, empty arrays, malformed JSON or repeated company_filters return 400. Omit or use {} for no employer filters. Hybrid search applies these exact constraints before ranking. |
found_fromISO timestamp | Inclusive firstSeenAt boundary: when we discovered the job, not when the employer published it. Include Z or an explicit timezone offset. |
found_beforeISO timestamp | Exclusive firstSeenAt boundary. Must be later than found_from. Convert a local calendar day's two midnights to timestamp boundaries, accounting for daylight saving. |
sortnewest | oldest | relevance | Defaults to relevance with search, newest otherwise. Relevance requires search. Newest/oldest with hybrid search sorts only retained ranked candidates (up to 100), not every potential match. Substring fallback uses newest unless oldest is requested. Ties use job UUID. |
searchstring | Search for a role or describe the work you want to find. Search returns up to 100 ranked matches. |
companystring | Exact company slug, such as the slug returned by GET /companies. Not a UUID or domain. |
role_categorystring | Exact category: fde, solutions_engineer, csm, tam, sales_engineer, implementation, professional_services, sales, engineering, product, design, marketing, data, operations, finance, hr, legal, or other. |
client_facingboolean | Set to true for fde, solutions_engineer, csm, tam, sales_engineer, implementation, professional_services, and sales. Ignored when role_category is supplied. |
locationstring | Case-insensitive match within the location text. |
remote_onlyboolean | Set to true to include only jobs whose remotePolicy is remote. Hybrid jobs are excluded. Boolean filters only enable on the literal value true. |
curl --fail-with-body \
-H "X-Api-Key: $FDE_API_KEY" \
"https://www.enterpriseaitrends.com/api/v1/jobs?limit=1"| Field | Description |
|---|---|
geographicEligibilityobject | status is unknown: structured eligibility is not stored. sourceLocationText and sourceUrl preserve source information. Read the job description for country, residency and visa restrictions; never infer worldwide eligibility. |
classificationVersionstring | null | Stored classification version; null for legacy/unknown provenance. No classification confidence score is available. |
id / titlestring | Job UUID and job title. |
roleCategory / departmentstring | null | Role classification and department. |
location / remotePolicystring | null | Source listing location and work arrangement: remote, hybrid, onsite, unknown (or null for missing data). remote_only matches remote exactly, not worldwide eligibility. Location filtering is text matching, not a country/visa eligibility test. |
salaryMin / salaryMaxnumber | null | Published salary range when available. |
salaryCurrencystring | null | Currency associated with the salary range. |
applyUrlstring | URL of the application page. |
firstSeenAt / lastSeenAtstring | ISO 8601 timestamps for when the job was first and last observed; not publication dates. |
companyName / companySlugstring | Employer name and slug. Use companySlug in the company filter. |
companyLogoUrlstring | null | Employer logo. |
companyDomain / companyDescription / companyHqLocation / companyTotalFundingstring | null | Employer profile details. Funding is display text, not a number. |
matchType / matchStrength / matchedTermsoptional | Ranked search results may add matchType (keyword, semantic, or both), matchStrength (strong, good, or weak), and matchedTerms (string array). These fields are absent from ordinary listings and may be absent on search fallback results. |
Example response 200 · application/json
{
"data": [
{
"id": "b17ff1e4-90fc-4a15-b659-521d0773a2b1",
"title": "Software Engineer",
"roleCategory": "engineering",
"department": "Engineering",
"location": "New York, NY",
"remotePolicy": "hybrid",
"salaryMin": null,
"salaryMax": null,
"salaryCurrency": "USD",
"applyUrl": "https://example.com/careers/engineer",
"firstSeenAt": "2026-09-01T12:00:00.000Z",
"lastSeenAt": "2026-09-08T12:00:00.000Z",
"companyName": "Example AI",
"companySlug": "example-ai",
"companyLogoUrl": null,
"companyDomain": "example.com",
"companyDescription": "Tools for building AI applications.",
"companyHqLocation": "New York, NY",
"companyTotalFunding": null
}
],
"meta": {
"page": 1,
"limit": 1,
"total": 1,
"totalPages": 1
}
}/jobs/{id}Get a job
Retrieve a job’s description and application URL. Check status before displaying the listing: a saved job can still be returned after it is no longer active, provided neither the job nor its company is hidden.
| Field | Description |
|---|---|
idstring · required | Job UUID returned by GET /jobs. |
Set JOB_ID to a value from the corresponding list response before running this request.
curl --fail-with-body \
-H "X-Api-Key: $FDE_API_KEY" \
"https://www.enterpriseaitrends.com/api/v1/jobs/$JOB_ID"| Field | Description |
|---|---|
geographicEligibilityobject | status is unknown: structured eligibility is not stored. sourceLocationText and sourceUrl preserve source information. Read the job description for country, residency and visa restrictions; never infer worldwide eligibility. |
classificationVersionstring | null | Stored classification version; null for legacy/unknown provenance. No classification confidence score is available. |
id / titlestring | Job UUID and job title. |
roleCategory / departmentstring | null | Role classification and department. |
location / remotePolicystring | null | Source listing location and work arrangement: remote, hybrid, onsite, unknown (or null for missing data). remote_only matches remote exactly, not worldwide eligibility. Location filtering is text matching, not a country/visa eligibility test. |
salaryMin / salaryMaxnumber | null | Published salary range when available. |
salaryCurrencystring | null | Currency associated with the salary range. |
applyUrlstring | URL of the application page. |
firstSeenAt / lastSeenAtstring | ISO 8601 timestamps for when the job was first and last observed; not publication dates. |
companyName / companySlugstring | Employer name and slug. Use companySlug in the company filter. |
companyLogoUrlstring | null | Employer logo. |
descriptionstring | null | Full job description; may contain HTML. Sanitize before rendering as HTML. |
statusstring | Current job status, such as active. |
companyWebsitestring | null | Employer website. This detail response does not include the list-only companyDomain, companyDescription, companyHqLocation, or companyTotalFunding fields. |
Example response 200 · application/json
{
"data": {
"id": "b17ff1e4-90fc-4a15-b659-521d0773a2b1",
"title": "Software Engineer",
"roleCategory": "engineering",
"department": "Engineering",
"location": "New York, NY",
"remotePolicy": "hybrid",
"salaryMin": null,
"salaryMax": null,
"salaryCurrency": "USD",
"applyUrl": "https://example.com/careers/engineer",
"firstSeenAt": "2026-09-01T12:00:00.000Z",
"lastSeenAt": "2026-09-08T12:00:00.000Z",
"description": "Build tools for AI developers.",
"status": "active",
"companyName": "Example AI",
"companySlug": "example-ai",
"companyLogoUrl": null,
"companyWebsite": "https://example.com"
}
}/job-categoriesDiscover job categories
Complete supported job category vocabulary. No parameters, pagination, or job counts. No metadata backfill is required.
curl --fail-with-body \
-H "X-Api-Key: $FDE_API_KEY" \
"https://www.enterpriseaitrends.com/api/v1/job-categories"| Field | Description |
|---|---|
id / label / descriptionstring | Exact role_category filter identifier, display label, and meaning. |
clientFacingboolean | Membership in the client_facing=true group. An explicit role_category overrides that group filter. |
Example response 200 · application/json
{
"data": [
{
"id": "fde",
"label": "Forward-Deployed Engineer",
"description": "Engineering deployed directly with customers to integrate and deliver solutions.",
"clientFacing": true
},
{
"id": "solutions_engineer",
"label": "Solutions Engineer",
"description": "Technical solution design and architecture for customer needs.",
"clientFacing": true
},
{
"id": "csm",
"label": "Customer Success Manager",
"description": "Customer adoption, success, and ongoing relationship management.",
"clientFacing": true
},
{
"id": "tam",
"label": "Technical Account Manager",
"description": "Technical account ownership and ongoing customer guidance.",
"clientFacing": true
},
{
"id": "sales_engineer",
"label": "Sales Engineer",
"description": "Technical presales, demonstrations, and sales support.",
"clientFacing": true
},
{
"id": "implementation",
"label": "Implementation Engineer",
"description": "Customer onboarding, implementation, and integration delivery.",
"clientFacing": true
},
{
"id": "professional_services",
"label": "Professional Services",
"description": "Consulting and professional service delivery for customers.",
"clientFacing": true
},
{
"id": "sales",
"label": "Sales",
"description": "Sales, account development, business development, and partnerships.",
"clientFacing": true
},
{
"id": "engineering",
"label": "Engineering",
"description": "Software, infrastructure, hardware, and other engineering roles.",
"clientFacing": false
},
{
"id": "product",
"label": "Product",
"description": "Product management and product strategy.",
"clientFacing": false
},
{
"id": "design",
"label": "Design",
"description": "Product, user experience, and other design roles.",
"clientFacing": false
},
{
"id": "marketing",
"label": "Marketing",
"description": "Marketing, communications, and growth.",
"clientFacing": false
},
{
"id": "data",
"label": "Data & Analytics",
"description": "Data science, analytics, and related data roles.",
"clientFacing": false
},
{
"id": "operations",
"label": "Operations",
"description": "Business operations and operational support.",
"clientFacing": false
},
{
"id": "finance",
"label": "Finance",
"description": "Finance and accounting.",
"clientFacing": false
},
{
"id": "hr",
"label": "HR & Recruiting",
"description": "Human resources, recruiting, and people operations.",
"clientFacing": false
},
{
"id": "legal",
"label": "Legal",
"description": "Legal and compliance roles.",
"clientFacing": false
},
{
"id": "other",
"label": "Other",
"description": "Classified roles outside the named categories; not an alias for missing classification.",
"clientFacing": false
}
],
"meta": {
"jobContext": {
"remotePolicyValues": [
"remote",
"hybrid",
"onsite",
"unknown"
],
"remoteOnly": "remote_only=true matches remotePolicy=remote exactly; excludes hybrid, onsite and unknown. It does not establish worldwide eligibility.",
"location": "Source listing text; location filtering is a case-insensitive substring match, not a geographic eligibility test.",
"eligibility": "Structured work eligibility is not available. Review sourceLocationText, the full job description and applyUrl for country, residency, work authorization or visa restrictions. Do not infer eligibility from remote policy or company headquarters.",
"classification": "roleCategory is the catalog classification, not an employer-certified label. Null means unclassified; other is a classified catch-all. classificationVersion may be null for legacy records; no confidence score is available.",
"freshness": "firstSeenAt is catalog discovery time; lastSeenAt is last observed time, not employer publication time or a guarantee the job is still open.",
"roleGroups": "FDE is only role_category=fde. client_facing=true includes FDE and adjacent customer-facing categories; an explicit role_category overrides that group."
},
"version": "job-categories-v1",
"complete": true,
"scope": "supported_vocabulary",
"filterParameter": "role_category",
"filterSemantics": "Exact category identifier. An explicit role_category takes precedence over client_facing=true. Omit both to include unclassified jobs; missing classification is not other."
}
}/statsGet catalog statistics
Get a snapshot of the catalog’s job and company counts. No parameters are required.
curl --fail-with-body \
-H "X-Api-Key: $FDE_API_KEY" \
"https://www.enterpriseaitrends.com/api/v1/stats"| Field | Description |
|---|---|
roleCountsobject | byCategory, fde, and clientFacing counts over active visible catalog jobs. FDE is a subset of client-facing roles, not an additional disjoint category. Null category means unclassified. context includes asOf, applied status/visibility filters, exact relation, and completeness; these are not worldwide market totals. |
totalJobsnumber | Active visible jobs at visible companies. |
jobsFirstSeenLast24Hoursnumber | Visible jobs first discovered in the UTC window [from, before), including inactive jobs. Unlike job search, this discovery count is not active-only. |
asOfISO timestamp | UTC reference time used to calculate the rolling window. |
discoveryWindowobject | from (inclusive), before (exclusive), timezone UTC, statusScope all, visibilityScope visible_jobs_and_employers. before equals asOf; the duration is exactly 24 hours. |
totalCompaniesnumber | Active, visible companies. |
newTodaynumber | Deprecated alias of jobsFirstSeenLast24Hours; retained for compatibility. Not a calendar-day count. |
Example response 200 · application/json
{
"data": {
"totalJobs": 1250,
"totalCompanies": 240,
"newToday": 32,
"jobsFirstSeenLast24Hours": 32,
"asOf": "2026-09-22T12:00:00.000Z",
"discoveryWindow": {
"from": "2026-09-21T12:00:00.000Z",
"before": "2026-09-22T12:00:00.000Z",
"timezone": "UTC",
"statusScope": "all",
"visibilityScope": "visible_jobs_and_employers"
}
}
}/deep-research/{domain}Get company research
Read a company’s existing research report, including its market, products, people, and funding. Coverage varies by company; this request does not generate a new report.
| Field | Description |
|---|---|
domainstring · required | Exact company domain returned by GET /companies, without a scheme or path. |
Set COMPANY_DOMAIN to a value from the corresponding list response before running this request.
curl --fail-with-body \
-H "X-Api-Key: $FDE_API_KEY" \
"https://www.enterpriseaitrends.com/api/v1/deep-research/$COMPANY_DOMAIN"| Field | Description |
|---|---|
companyobject | Company identity: id, name, domain, and slug. |
research.summary / oneLinerstring | null | Company overview and short description. All remaining fields below are inside research. |
foundedYear / employeeCountnumber | null | Founding year and reported employee count. |
hqCity / hqState / hqCountrystring | null | Headquarters details. |
businessModel / marketAnalysis / targetCustomersstring | null | Business model, market context, and customer profile. |
founders / leadershiparray<object> | null | People with name and title. |
keyProducts / competitors / techStack / notableCustomersarray<string> | null | Reported products, competitors, technologies, and customers. |
fundingRoundsarray<object> | null | Entries with date, amount, round, and investors (string array). Dates and amounts are report text. |
recentNewsarray<object> | null | Entries with title, date, and summary; url, id, category, and citations (objects with url and authority) may also be present. |
markdownReport / screenshotUrl / processorTierstring | null | Full report in Markdown, an optional screenshot URL, and the stored research tier. |
lastFullResearchAt / lastFastResearchAt / enrichedAtstring | null | ISO 8601 research timestamps. Use these to assess freshness. |
Example response 200 · application/json
{
"data": {
"company": {
"id": "3c123740-3ef5-4d1e-b701-08a8f2d30a12",
"name": "Example AI",
"domain": "example.com",
"slug": "example-ai"
},
"research": {
"summary": "Tools for building AI applications.",
"oneLiner": null,
"foundedYear": null,
"hqCity": null,
"hqState": null,
"hqCountry": null,
"employeeCount": null,
"businessModel": null,
"founders": null,
"leadership": null,
"marketAnalysis": null,
"targetCustomers": null,
"keyProducts": null,
"recentNews": null,
"competitors": null,
"techStack": null,
"fundingRounds": null,
"notableCustomers": null,
"markdownReport": "# Example AI\n\nTools for building AI applications.",
"screenshotUrl": null,
"processorTier": "base",
"lastFullResearchAt": "2026-09-01T12:00:00.000Z",
"lastFastResearchAt": null,
"enrichedAt": "2026-09-01T12:00:00.000Z"
}
}
}API reference · Personal keys
Manage company lists
Group companies into named lists for research, job hunting, or a report about the companies you follow. These endpoints use /api/lists, outside the catalog’s /api/v1 base path.
pk_live_…). Lists belong to your user, across your organizations. An organization key returns 403. A personal key still requires membership in the organization it was created for.Every JSON read and write is owner-only, including for public lists. Public visibility makes the website page at /lists/{slug} shareable; it does not grant other API callers access. Website sessions can use these endpoints too; session writes require a matching Origin header.
Set FDE_API_KEY to your personal key. After creating a list, set LIST_ID to its returned UUID. Set COMPANY_ID to a UUID from the catalog’s company list.
/api/listsGet your lists
Returns a data array of your lists, with the default list first and then the most recently updated lists. Up to 100 lists are returned; this endpoint is not paginated. Add ?companyId=UUID to include a hasCompany boolean on each list.
curl --fail-with-body -X GET \
-H "X-Api-Key: $FDE_API_KEY" \
"https://www.enterpriseaitrends.com/api/lists"Example response 200 · JSON
{
"data": [
{
"id": "db113740-3ef5-4d1e-b701-08a8f2d30a12",
"name": "AI infrastructure",
"slug": "ai-infrastructure-a94c12",
"description": "Companies to follow",
"visibility": "private",
"isDefault": false,
"itemCount": 1,
"createdAt": "2026-09-08T12:00:00.000Z",
"updatedAt": "2026-09-08T12:00:00.000Z"
}
]
}/api/listsCreate a list
Supply name (required, 1–80 characters after trimming), description (optional, up to 500 characters or null), and visibility (private or public; defaults to private). Names must be unique within your account. You can have up to 100 lists, including Saved.
curl --fail-with-body -X POST \
-H "X-Api-Key: $FDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"AI infrastructure","description":"Companies to follow","visibility":"private"}' \
"https://www.enterpriseaitrends.com/api/lists"/api/lists/{id}Get a list
Returns the list’s metadata under data. Use the id from a create or list response, not the shareable URL slug.
curl --fail-with-body -X GET \
-H "X-Api-Key: $FDE_API_KEY" \
"https://www.enterpriseaitrends.com/api/lists/$LIST_ID"Example response 200 · JSON
{
"data": {
"id": "db113740-3ef5-4d1e-b701-08a8f2d30a12",
"name": "AI infrastructure",
"slug": "ai-infrastructure-a94c12",
"description": "Companies to follow",
"visibility": "private",
"isDefault": false,
"itemCount": 1,
"createdAt": "2026-09-08T12:00:00.000Z",
"updatedAt": "2026-09-08T12:00:00.000Z"
}
}/api/lists/{id}Edit a list
Supply at least one of name, description, or visibility, using the same validation as creation. Set description to null or an empty string to clear it. Renaming keeps the list’s slug and shared URL unchanged. Returns the updated list under data.
curl --fail-with-body -X PATCH \
-H "X-Api-Key: $FDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Companies to research","description":null}' \
"https://www.enterpriseaitrends.com/api/lists/$LIST_ID"/api/lists/{id}Delete a list
Deletes the list and its memberships. Company records are retained. Returns { data: { deleted: true } }. Repeating the deletion returns 404 because the list no longer exists.
curl --fail-with-body -X DELETE \
-H "X-Api-Key: $FDE_API_KEY" \
"https://www.enterpriseaitrends.com/api/lists/$LIST_ID"/api/lists/{id}/items/{companyId}Add a company
Add an active, visible company by UUID. No body is required. A list holds up to 1,000 companies. Repeating an add succeeds even when the list is full, without duplicating the membership or changing its position.
curl --fail-with-body -X PUT \
-H "X-Api-Key: $FDE_API_KEY" \
"https://www.enterpriseaitrends.com/api/lists/$LIST_ID/items/$COMPANY_ID"Example response 200 · JSON
{
"data": {
"listId": "db113740-3ef5-4d1e-b701-08a8f2d30a12",
"companyId": "3c123740-3ef5-4d1e-b701-08a8f2d30a12",
"added": true
}
}/api/lists/{id}/items/{companyId}Remove a company
Remove a membership without deleting the company. No body is required. Returns { data: { listId, companyId, added: false } }. Removing an already-absent company succeeds as long as you still own the list.
curl --fail-with-body -X DELETE \
-H "X-Api-Key: $FDE_API_KEY" \
"https://www.enterpriseaitrends.com/api/lists/$LIST_ID/items/$COMPANY_ID"/api/lists/saveSave or unsave in your default list
Supply companyId (UUID) and saved (boolean). Ensures a default Saved list exists, then adds or removes the company. If you already have a list named Saved, it becomes the default. Renaming a default list keeps it as the quick-save destination. Implicit creation obeys the 100-list limit, and adding obeys the 1,000-company limit.
curl --fail-with-body -X POST \
-H "X-Api-Key: $FDE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"companyId":"3c123740-3ef5-4d1e-b701-08a8f2d30a12","saved":true}' \
"https://www.enterpriseaitrends.com/api/lists/save"Example response 200 · JSON
{
"data": {
"listId": "db113740-3ef5-4d1e-b701-08a8f2d30a12",
"listSlug": "saved-a94c12",
"saved": true
}
}/api/lists/{id}/itemsRead the companies in a list
Use this endpoint to build a report or fetch the profiles in a saved list. Results are ordered by when the company was added (newest first), then by company UUID to break ties.
Pass page (default 1, range 1–1,000) and limit (default 50, range 1–100). Both must be positive integers. Invalid, repeated, or out-of-range pagination values return 400. A page beyond the available results returns an empty array and the same total.
curl --fail-with-body -X GET \
-H "X-Api-Key: $FDE_API_KEY" \
"https://www.enterpriseaitrends.com/api/lists/$LIST_ID/items?page=1&limit=50"The data array contains company profiles. meta contains page, limit, total, and totalPages. Alternatively, use pagination=cursor and follow meta.nextCursor with the same limit (no page parameter). Sessions last 15 minutes, preserve the initial membership order, and recheck ownership, membership, and visibility on every request. New members appear in a new session. In page mode, pagination is consistent while membership is unchanged; additions or removals between requests can shift pages.
{
"data": [
{
"id": "3c123740-3ef5-4d1e-b701-08a8f2d30a12",
"name": "Example AI",
"slug": "example-ai",
"domain": "example.com",
"website": "https://example.com",
"logoUrl": null,
"description": "Tools for AI developers.",
"oneLiner": null,
"hqLocation": null,
"totalFunding": null,
"latestValuation": null,
"headcountRange": null,
"activeJobCount": 1,
"addedAt": "2026-09-08T12:00:00.000Z"
}
],
"meta": {
"page": 1,
"limit": 50,
"total": 1,
"totalPages": 1
}
}Only active, visible companies are returned. List metadata’s itemCount counts all saved memberships, including unavailable companies; the paginated total counts only the companies you can retrieve.
List response fields
List metadata includes id, name, slug, description (string or null), visibility (private or public), isDefault (boolean), and ISO 8601 createdAt and updatedAt timestamps. List and detail reads include itemCount; create and update responses instead include the owner’s userId.
Member records include company identity, website and profile fields, activeJobCount (number), and addedAt (ISO 8601). Profile facts may be null; funding and valuation are display strings rather than numeric amounts.
Limits and errors
All successful list operations return HTTP 200 with a data value. Errors use { error: { code, message } }. List responses are not cached.
| Status / code | What to do |
|---|---|
400 · BAD_REQUEST | Check the JSON body, UUIDs, names, description, visibility, and pagination. Supply at least one supported field when editing. |
401 · UNAUTHORIZED | Supply a valid personal key or sign in. Expired/revoked keys and keys whose owners lost organization membership fail authentication. |
403 · FORBIDDEN | Use a personal key instead of an organization key. For session writes, send the site’s Origin. |
404 · NOT_FOUND | The list is missing or belongs to another user, or the company cannot be added. Private list existence is not disclosed. |
409 · DUPLICATE | Choose another name; you already own a list with that name. |
413 · PAYLOAD_TOO_LARGE | Keep JSON request bodies within 16 KiB. |
422 · LIMIT_EXCEEDED | Remove a list or company before creating another. Existing-member add retries still succeed at capacity. |
429 · RATE_LIMITED | Wait for the number of seconds in Retry-After before retrying. |
500 · INTERNAL | The request could not complete. Retry after a delay; verify a create succeeded before retrying it to avoid duplicate-name errors. |
List endpoints share a separate budget of 100 requests per 60-second window per user, across personal keys and sessions. The budget is shared across server instances. Read X-RateLimit-Limit and X-RateLimit-Remaining; 429 responses also include Retry-After. Authentication and origin failures occur before this budget is charged.