Skip to documentation
Developer documentation REST API · v1

Your first API request

Bring company intelligence into your own tools. Read company profiles, find jobs, and retrieve research with a single API key.

Base URLhttps://www.enterpriseaitrends.com/api/v1
1

Create 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 key
2

Make a request

Set FDE_API_KEY in your terminal or secret manager, then check the identity associated with your key.

Terminal
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:

200 · JSON
{
  "data": {
    "type": "user",
    "userId": "user_example",
    "email": null,
    "name": null,
    "organizationId": "org_example"
  }
}
3

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.

List companies · cURL
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.

Hosted MCP endpoint · Streamable HTTP
https://mcp.enterpriseaitrends.com/mcp
OAuth rollout: The browser sign-in flow below requires the OAuth release on both the website and MCP server. Until that release is deployed, use the optional API-key setup further down this guide.

Connect 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 Code · OAuth
claude mcp add --transport http --scope user enterprise-ai-trends https://mcp.enterpriseaitrends.com/mcp

Open /mcp in Claude Code, select Enterprise AI Trends, and follow the browser sign-in instructions.

Codex

Codex · OAuth config.toml
[mcp_servers.enterprise-ai-trends]
url = "https://mcp.enterpriseaitrends.com/mcp"
Codex · sign in
codex mcp login enterprise-ai-trends

When 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:

Terminal · API key
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:

Terminal · Claude Code
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:

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

Example 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.”

Available MCP tools
ToolWhat it does
search_jobsFind active roles by keyword, company, location, role category, or remote policy.
get_jobRead a job’s full description using its UUID.
list_companiesBrowse companies with search and classification filters.
get_companyLook up a company by slug or UUID, including tags and active job count.
list_job_categoriesDiscover job categories, their meanings, and client-facing group membership.
list_tagsDiscover the available classification tags and filter values.
get_account_infoRead your identity, organization, capabilities, and remaining rate-limit budget. Credit balances are unavailable.
get_statsRead 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.

FDE jobs at healthcare companies · MCP search_jobs
{
  "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:

Request headers · choose one
X-Api-Key: YOUR_API_KEY

Authorization: Bearer YOUR_API_KEY

Keep 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.

Key types
FieldDescription
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.

Empty list · JSON
{
  "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
  }
}
Pagination metadata
FieldDescription
page / limitnumberThe page number and effective page size after defaults are applied; page is null in cursor mode.
total / totalPagesnumberLegacy 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 / totalScopestringHow results were retrieved (filter, hybrid, substring_fallback, invalid_query) and what total counts (filtered_catalog, ranked_candidates, substring_matches, snapshot_candidates).
totalMatches / totalRelationnumber | null / stringExact 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 | nullTrue 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 / booleanRetrievable 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 | nullMaximum accessible results for this request. Search is capped at 100; filter-only requests have no search cap but still have a tier window.
correctedQuerystring | nullSpelling 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:

Filtered jobs · cURL
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.

Rate-limit response headers
FieldDescription
X-RateLimit-LimitintegerRequest budget for the current window: 100.
X-RateLimit-RemainingintegerRequests remaining in the current window.
Retry-Afterinteger · on 429Seconds to wait before retrying. Pause requests for this duration.
X-Api-Tierstringtoken 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.

401 · JSON
{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid, expired or revoked API key"
  }
}
Common errors
FieldDescription
401 · UNAUTHORIZEDAuthenticationMissing, 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_EXCEEDEDPaginationThe requested page starts beyond the allowed result window. Narrow the query or request an earlier page.
404 · NOT_FOUNDMissing resourceThe requested record or stored research report was not found. Check the identifier; not every company has research.
429 · RATE_LIMITEDRate limitWait for the number of seconds in Retry-After before sending another request.
500 · INTERNALServer errorThe 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.

GET/me

Account 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.

Account and request budget · cURL
curl --fail-with-body \
  -H "X-Api-Key: $FDE_API_KEY" \
  "https://www.enterpriseaitrends.com/api/v1/me"
Response fields · inside data
FieldDescription
capabilities / scopesobject / arrayCurrent credential privileges; OAuth remains read-only with no account-management access.
rateLimitobject | nulllimit, 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.
creditsobjectstatus unavailable and remaining null until billing exists. Never interpreted as zero or unlimited.
typestringuser for a personal key; organization for an organization key.
organizationIdstring | nullOrganization the key is bound to.
userIdstring · personal keysThe personal key’s owner.
email / namestring | null · personal keysNullable compatibility fields; profile details are not fetched by this endpoint.
Example response 200 · application/json
Account and request budget · JSON
{
  "data": {
    "type": "user",
    "userId": "user_example",
    "email": null,
    "name": null,
    "organizationId": "org_example"
  }
}
An organization key returns { "data": { "type": "organization", "organizationId": "org_example" } }.
GET/companies

List 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.

Query parameters
FieldDescription
paginationstringpage (default) or cursor. Cursor mode freezes result order for 15 minutes.
cursorstringContinue with meta.nextCursor, repeating filters and limit. Cannot combine with page.
pageintegerPage number, starting at 1. Default: 1.
limitintegerItems per page. Default: 50; maximum: 100. Invalid or larger values return 400.
searchstringSearch by name or a description of what the company does. Search returns up to 100 ranked matches.
organization_typestringComma-separated tag slugs from GET /tags. Matches any supplied slug within this dimension; separate dimensions must all match.
ecosystemstringComma-separated tag slugs from GET /tags. Matches any supplied slug within this dimension; separate dimensions must all match.
activitystringComma-separated tag slugs from GET /tags. Matches any supplied slug within this dimension; separate dimensions must all match.
specializationstringComma-separated tag slugs from GET /tags. Matches any supplied slug within this dimension; separate dimensions must all match.
marketstringComma-separated tag slugs from GET /tags. Matches any supplied slug within this dimension; separate dimensions must all match.
customer_segmentstringComma-separated tag slugs from GET /tags. Matches any supplied slug within this dimension; separate dimensions must all match.
delivery_modelstringComma-separated tag slugs from GET /tags. Matches any supplied slug within this dimension; separate dimensions must all match.
revenue_modelstringComma-separated tag slugs from GET /tags. Matches any supplied slug within this dimension; separate dimensions must all match.
listing_statusstringComma-separated tag slugs from GET /tags. Matches any supplied slug within this dimension; separate dimensions must all match.
funding_stagestringComma-separated tag slugs from GET /tags. Matches any supplied slug within this dimension; separate dimensions must all match.
funding_tierstringComma-separated tag slugs from GET /tags. Matches any supplied slug within this dimension; separate dimensions must all match.
List companies · cURL
curl --fail-with-body \
  -H "X-Api-Key: $FDE_API_KEY" \
  "https://www.enterpriseaitrends.com/api/v1/companies?limit=1"
Response fields · inside data
FieldDescription
parentCompanyId / entityScopestring | nullReviewed subdivision identity; a shared host does not imply the same organization.
classificationAssessmentsobject | nullPer-dimension known, unknown or not_applicable status with an evidence-based reason. Null before ontology assessment.
idstringCompany UUID. Use this or the slug to retrieve the company.
name / slugstringDisplay name and URL slug.
domain / website / logoUrlstring | nullCompany domain, website URL, and logo URL.
description / headcountRange / hqLocationstring | nullCompany profile and headquarters. Missing profile facts are null.
totalFunding / latestValuation / annualRevenuestring | nullDisplay text, not numeric currency values. Do not assume these can be parsed as numbers.
sourceKind / sourcePlatform / sourceUrlstring | nullPreferred active job source: its kind, platform, and URL. Null when no source is available.
activeJobCountnumberNumber 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 / matchedTermsoptionalRanked 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
List companies · 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
  }
}
GET/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.

Path parameters
FieldDescription
idstring · requiredCompany UUID or slug.

Set COMPANY_ID to a value from the corresponding list response before running this request.

Get a company · cURL
curl --fail-with-body \
  -H "X-Api-Key: $FDE_API_KEY" \
  "https://www.enterpriseaitrends.com/api/v1/companies/$COMPANY_ID"
Response fields · inside data
FieldDescription
parentCompanyId / entityScopestring | nullReviewed subdivision identity; a shared host does not imply the same organization.
classificationAssessmentsobject | nullPer-dimension known, unknown or not_applicable status with an evidence-based reason. Null before ontology assessment.
idstringCompany UUID. Use this or the slug to retrieve the company.
name / slugstringDisplay name and URL slug.
domain / website / logoUrlstring | nullCompany domain, website URL, and logo URL.
description / headcountRange / hqLocationstring | nullCompany profile and headquarters. Missing profile facts are null.
totalFunding / latestValuation / annualRevenuestring | nullDisplay text, not numeric currency values. Do not assume these can be parsed as numbers.
sourceKind / sourcePlatform / sourceUrlstring | nullPreferred active job source: its kind, platform, and URL. Null when no source is available.
activeJobCountnumberNumber 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 | nullShort description, investor information, LinkedIn URL, and careers URL.
enrichmentUpdatedAt / lastRunAtstring | nullISO 8601 timestamps for the last profile enrichment and job-source run, respectively.
Example response 200 · application/json
Get a company · 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
  }
}
Returns 404 NOT_FOUND if the company does not exist or is not active and visible.
GET/jobs

List 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.

Query parameters
FieldDescription
paginationstringpage (default) or cursor. Cursor mode freezes result order for 15 minutes.
cursorstringContinue with meta.nextCursor, repeating filters and limit. Cannot combine with page.
pageintegerPage number, starting at 1. Default: 1.
limitintegerItems per page. Default: 20; maximum: 50. Invalid or larger values return 400.
company_filtersJSON objectEmployer 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 timestampInclusive firstSeenAt boundary: when we discovered the job, not when the employer published it. Include Z or an explicit timezone offset.
found_beforeISO timestampExclusive 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 | relevanceDefaults 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.
searchstringSearch for a role or describe the work you want to find. Search returns up to 100 ranked matches.
companystringExact company slug, such as the slug returned by GET /companies. Not a UUID or domain.
role_categorystringExact category: fde, solutions_engineer, csm, tam, sales_engineer, implementation, professional_services, sales, engineering, product, design, marketing, data, operations, finance, hr, legal, or other.
client_facingbooleanSet to true for fde, solutions_engineer, csm, tam, sales_engineer, implementation, professional_services, and sales. Ignored when role_category is supplied.
locationstringCase-insensitive match within the location text.
remote_onlybooleanSet to true to include only jobs whose remotePolicy is remote. Hybrid jobs are excluded. Boolean filters only enable on the literal value true.
List jobs · cURL
curl --fail-with-body \
  -H "X-Api-Key: $FDE_API_KEY" \
  "https://www.enterpriseaitrends.com/api/v1/jobs?limit=1"
Response fields · inside data
FieldDescription
geographicEligibilityobjectstatus 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 | nullStored classification version; null for legacy/unknown provenance. No classification confidence score is available.
id / titlestringJob UUID and job title.
roleCategory / departmentstring | nullRole classification and department.
location / remotePolicystring | nullSource 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 | nullPublished salary range when available.
salaryCurrencystring | nullCurrency associated with the salary range.
applyUrlstringURL of the application page.
firstSeenAt / lastSeenAtstringISO 8601 timestamps for when the job was first and last observed; not publication dates.
companyName / companySlugstringEmployer name and slug. Use companySlug in the company filter.
companyLogoUrlstring | nullEmployer logo.
companyDomain / companyDescription / companyHqLocation / companyTotalFundingstring | nullEmployer profile details. Funding is display text, not a number.
matchType / matchStrength / matchedTermsoptionalRanked 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
List jobs · 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
  }
}
GET/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.

Path parameters
FieldDescription
idstring · requiredJob UUID returned by GET /jobs.

Set JOB_ID to a value from the corresponding list response before running this request.

Get a job · cURL
curl --fail-with-body \
  -H "X-Api-Key: $FDE_API_KEY" \
  "https://www.enterpriseaitrends.com/api/v1/jobs/$JOB_ID"
Response fields · inside data
FieldDescription
geographicEligibilityobjectstatus 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 | nullStored classification version; null for legacy/unknown provenance. No classification confidence score is available.
id / titlestringJob UUID and job title.
roleCategory / departmentstring | nullRole classification and department.
location / remotePolicystring | nullSource 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 | nullPublished salary range when available.
salaryCurrencystring | nullCurrency associated with the salary range.
applyUrlstringURL of the application page.
firstSeenAt / lastSeenAtstringISO 8601 timestamps for when the job was first and last observed; not publication dates.
companyName / companySlugstringEmployer name and slug. Use companySlug in the company filter.
companyLogoUrlstring | nullEmployer logo.
descriptionstring | nullFull job description; may contain HTML. Sanitize before rendering as HTML.
statusstringCurrent job status, such as active.
companyWebsitestring | nullEmployer website. This detail response does not include the list-only companyDomain, companyDescription, companyHqLocation, or companyTotalFunding fields.
Example response 200 · application/json
Get a job · 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"
  }
}
Returns 404 NOT_FOUND if no visible job matches the UUID or its company is hidden. Use a UUID returned by the list endpoint; malformed identifiers are not a supported lookup.
GET/tags

List classification tags

Get the available classification labels, grouped by dimension. Use the slug rather than the display value when filtering companies. No parameters are required.

List classification tags · cURL
curl --fail-with-body \
  -H "X-Api-Key: $FDE_API_KEY" \
  "https://www.enterpriseaitrends.com/api/v1/tags"
Response fields
FieldDescription
dataobjectA map of dimension names to arrays of { value, slug }. All supported dimensions are included. Metadata describes dimension labels, meaning, cardinality, and OR-within/AND-across filtering. Vocabulary is independent of current record counts.
value / slugstringHuman-readable label and the corresponding filter value.
Example response 200 · application/json
List classification tags · JSON
{
  "data": {
    "market": [
      {
        "value": "Healthcare",
        "slug": "healthcare"
      }
    ],
    "funding_stage": [
      {
        "value": "Series A",
        "slug": "series-a"
      }
    ]
  }
}
Company filters use the shared ontology dimensions returned by the tags endpoint. This example shows a subset of possible dimensions; fetch the endpoint for current values.
GET/job-categories

Discover job categories

Complete supported job category vocabulary. No parameters, pagination, or job counts. No metadata backfill is required.

Discover job categories · cURL
curl --fail-with-body \
  -H "X-Api-Key: $FDE_API_KEY" \
  "https://www.enterpriseaitrends.com/api/v1/job-categories"
Response fields · inside data
FieldDescription
id / label / descriptionstringExact role_category filter identifier, display label, and meaning.
clientFacingbooleanMembership in the client_facing=true group. An explicit role_category overrides that group filter.
Example response 200 · application/json
Discover job categories · 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."
  }
}
Fetch /job-categories, then GET /jobs?role_category=fde&pagination=cursor. Unknown category identifiers return 400. Missing job classification is not the other category; omit category filters to include unclassified jobs.
GET/stats

Get catalog statistics

Get a snapshot of the catalog’s job and company counts. No parameters are required.

Get catalog statistics · cURL
curl --fail-with-body \
  -H "X-Api-Key: $FDE_API_KEY" \
  "https://www.enterpriseaitrends.com/api/v1/stats"
Response fields · inside data
FieldDescription
roleCountsobjectbyCategory, 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.
totalJobsnumberActive visible jobs at visible companies.
jobsFirstSeenLast24HoursnumberVisible jobs first discovered in the UTC window [from, before), including inactive jobs. Unlike job search, this discovery count is not active-only.
asOfISO timestampUTC reference time used to calculate the rolling window.
discoveryWindowobjectfrom (inclusive), before (exclusive), timezone UTC, statusScope all, visibilityScope visible_jobs_and_employers. before equals asOf; the duration is exactly 24 hours.
totalCompaniesnumberActive, visible companies.
newTodaynumberDeprecated alias of jobsFirstSeenLast24Hours; retained for compatibility. Not a calendar-day count.
Example response 200 · application/json
Get catalog statistics · 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"
    }
  }
}
GET/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.

Path parameters
FieldDescription
domainstring · requiredExact 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.

Get company research · cURL
curl --fail-with-body \
  -H "X-Api-Key: $FDE_API_KEY" \
  "https://www.enterpriseaitrends.com/api/v1/deep-research/$COMPANY_DOMAIN"
Response fields · inside data
FieldDescription
companyobjectCompany identity: id, name, domain, and slug.
research.summary / oneLinerstring | nullCompany overview and short description. All remaining fields below are inside research.
foundedYear / employeeCountnumber | nullFounding year and reported employee count.
hqCity / hqState / hqCountrystring | nullHeadquarters details.
businessModel / marketAnalysis / targetCustomersstring | nullBusiness model, market context, and customer profile.
founders / leadershiparray<object> | nullPeople with name and title.
keyProducts / competitors / techStack / notableCustomersarray<string> | nullReported products, competitors, technologies, and customers.
fundingRoundsarray<object> | nullEntries with date, amount, round, and investors (string array). Dates and amounts are report text.
recentNewsarray<object> | nullEntries with title, date, and summary; url, id, category, and citations (objects with url and authority) may also be present.
markdownReport / screenshotUrl / processorTierstring | nullFull report in Markdown, an optional screenshot URL, and the stored research tier.
lastFullResearchAt / lastFastResearchAt / enrichedAtstring | nullISO 8601 research timestamps. Use these to assess freshness.
Example response 200 · application/json
Get company research · 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"
    }
  }
}
Returns 404 NOT_FOUND when the domain is unknown or the company has no stored report. A company listing does not guarantee research coverage.

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.

Use a personal key (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.

GET/api/lists

Get 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.

Get your lists · cURL
curl --fail-with-body -X GET \
  -H "X-Api-Key: $FDE_API_KEY" \
  "https://www.enterpriseaitrends.com/api/lists"
Example response 200 · JSON
Get your lists · 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"
    }
  ]
}
POST/api/lists

Create 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.

Create a list · cURL
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"
GET/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.

Get a list · cURL
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
Get a list · 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"
  }
}
PATCH/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.

Edit a list · cURL
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"
DELETE/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.

Delete a list · cURL
curl --fail-with-body -X DELETE \
  -H "X-Api-Key: $FDE_API_KEY" \
  "https://www.enterpriseaitrends.com/api/lists/$LIST_ID"
PUT/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.

Add a company · cURL
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
Add a company · JSON
{
  "data": {
    "listId": "db113740-3ef5-4d1e-b701-08a8f2d30a12",
    "companyId": "3c123740-3ef5-4d1e-b701-08a8f2d30a12",
    "added": true
  }
}
DELETE/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.

Remove a company · cURL
curl --fail-with-body -X DELETE \
  -H "X-Api-Key: $FDE_API_KEY" \
  "https://www.enterpriseaitrends.com/api/lists/$LIST_ID/items/$COMPANY_ID"
POST/api/lists/save

Save 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.

Save or unsave in your default list · cURL
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
Save or unsave in your default list · JSON
{
  "data": {
    "listId": "db113740-3ef5-4d1e-b701-08a8f2d30a12",
    "listSlug": "saved-a94c12",
    "saved": true
  }
}
GET/api/lists/{id}/items

Read 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.

List companies · cURL
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.

List members · JSON
{
  "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.

List API errors
Status / codeWhat to do
400 · BAD_REQUESTCheck the JSON body, UUIDs, names, description, visibility, and pagination. Supply at least one supported field when editing.
401 · UNAUTHORIZEDSupply a valid personal key or sign in. Expired/revoked keys and keys whose owners lost organization membership fail authentication.
403 · FORBIDDENUse a personal key instead of an organization key. For session writes, send the site’s Origin.
404 · NOT_FOUNDThe list is missing or belongs to another user, or the company cannot be added. Private list existence is not disclosed.
409 · DUPLICATEChoose another name; you already own a list with that name.
413 · PAYLOAD_TOO_LARGEKeep JSON request bodies within 16 KiB.
422 · LIMIT_EXCEEDEDRemove a list or company before creating another. Existing-member add retries still succeed at capacity.
429 · RATE_LIMITEDWait for the number of seconds in Retry-After before retrying.
500 · INTERNALThe 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.

Ready to connect? Create an API key