Access our full article archive with comprehensive metadata and content
Organization API key for authentication
Everything you need to start using the In Practise API
All API requests require a Bearer token in the Authorization header. Use your organisation's API key, which can be found in your organisation settings or at the top of this page.
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://inpractise.com/api/v1/search/articles?query=Microsofthttps://inpractise.com/api/v1Each endpoint has its own rate limit, tracked per API key over a rolling 24-hour window. Limits are configurable per subscription; the values below are your organisation's effective limits. Rate limit headers are included in every response.
| Endpoint | Limit / 24h |
|---|---|
| GET /api/v1/articles | 200 |
| GET /api/v1/search/articles | 5,000 |
| GET /api/v1/search/companies | 5,000 |
| GET /api/v1/articles/:slugOrId | 1,000 |
| GET /api/v1/core-data | 5,000 |
| GET/PUT/DELETE /api/v1/watchlist | 5,000 each |
Response Headers
X-RateLimit-Limit — Maximum requests allowedX-RateLimit-Remaining — Requests remaining in current window
All errors return a JSON object with error (human-readable message) and code (machine-readable code).
| Status | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid parameters |
| 403 | UNAUTHORIZED | Missing Authorization header |
| 403 | INVALID_API_KEY | API key not found |
| 403 | NO_ACTIVE_SUBSCRIPTION | No active API subscription |
| 403 | USER_NOT_IN_ORG | User email not in your organisation |
| 404 | NOT_FOUND | Resource not found |
| 429 | RATE_LIMIT_EXCEEDED | Too many requests |
| 500 | INTERNAL_ERROR | Server error |
MCP is an open standard that lets AI assistants connect directly to In Practise. Available to users whose organisation has an active API-enabled subscription.
MCP authentication upgraded to OAuth
Old token-based URLs (/api/v1/mcp/<token>) no longer work. Reconfigure your clients with the URL below -- you will be prompted to sign in to In Practise on first connect.
https://inpractise.com/api/v1/mcpOAuth login required -- your MCP client will open an In Practise sign-in window the first time it connects. No personal token or API key is needed.
Add the following to your Claude configuration (claude_desktop_config.json):
{
"mcpServers": {
"inpractise": {
"url": "https://inpractise.com/api/v1/mcp"
}
}
}On first launch, Claude will pop up a browser window asking you to sign in to In Practise. After approving access the OAuth credentials are stored by Claude -- nothing else to configure.
Add the URL above as an MCP Action endpoint in ChatGPT settings. ChatGPT will walk you through the OAuth sign-in on first use.
| Tool | Description |
|---|---|
get_core_data | Platform context: your watchlist, top companies, moats, business models, latest articles |
search_articles | Semantic search across the article library with filters |
get_articles_by_slug | Retrieve full article content by slug |
search_companies | Fuzzy company search by name/ticker |
add_to_watchlist | Add companies, moats, business models, industries to watchlist |
remove_from_watchlist | Remove items from watchlist |
The MCP endpoint authenticates each user via OAuth against your In Practise account -- no API key or personal token is required. Access is granted to users whose organisation has an active API-enabled subscription.
Retrieve paginated articles with full content and metadata
Page number for pagination. Default is 1.
Filter articles published after this date. Accepts any format that JavaScript Date can parse.
Filter articles published before this date. Accepts any format that JavaScript Date can parse.
Click refresh to view rate limit status
curl -X GET \
-H "Authorization: Bearer $API_KEY" \
"https://inpractise.com/api/v1/articles"{
"pagination": {
"currentPage": 1,
"totalPages": 27,
"totalArticles": 2689,
"hasNextPage": true,
"hasPreviousPage": false
},
"articles": [
{
"id": "046f8a5c-da85-49b8-9b32-826b15e97986",
"url": "https://inpractise.com/articles/terravest-asian-threat-in-the-small-propane-tank-market",
"title": "TerraVest: Asia Manufacturing Threat",
"type": "3p_interview",
"publishedDate": "2024-10-13T17:26:08.948Z",
"executiveTitle": "Former VP at Manchester Tank",
"executiveBio": "The expert is a Former VP at Manchester Tank, where he spent 14 years (2014-2023).",
"tags": {
"gics": [
{
"name": "Energy",
"code": 10,
"parent": null,
"level": 1
}
],
"businessModel": [
"Serial Acquirer"
],
"moat": [],
"other": []
},
"fullContent": "**Full article content here...**",
"topQuotes": "> The equipment is the biggest constraint...",
"whyInteresting": "TerraVest owns Manchester Tank, a leading North American propane tank manufacturer, and this interview explores Asian competition threats and manufacturing dynamics.",
"companies": [
{
"id": "7b5c4a3d-eb91-4a9c-9a87-215b25f98987",
"name": "TerraVest Industries",
"nameDisplay": "TerraVest",
"ticker": "TVK",
"slug": "terravest-industries",
"primary": true,
"businessModel": [
"Serial Acquirer"
],
"moat": [
"Manufacturing Scale"
],
"industries": [
{
"name": "Energy",
"code": 10,
"parent": null,
"level": 1
}
],
"whyInteresting": "Serial acquirer rolling up niche manufacturing businesses in North America."
}
]
}
]
}/**
* Article type enum - the type of content
*/
type ArticleType =
| 'interview' // Core executive interview by In Practise
| '3p_interview' // Partner interview from third-party sources
| 'analysis' // IP Research Analysis piece
| 'value_chain' // Value chain analysis
| 'company_profile' // Company profile
| 'resource' // IP Research Resource
| 'weekly_update' // Weekly update
| 'ip_dialogue' // In Practise dialogue format
| 'survey' // Industry survey results
| 'podcast' // Podcast episode
| 'interview_clip' // Deprecated: excerpt from an interview
| null; // Type not determined
/**
* GICS (Global Industry Classification Standard) taxonomy
*/
interface GicsTag {
/** Human-readable name (e.g., "Communication Services") */
name: string;
/** GICS code (e.g., 50 for Communication Services) */
code: number;
/** Parent GICS code (null for top-level sectors) */
parent: number | null;
/** Hierarchy level (1-4, where 1 is sector, 4 is sub-industry) */
level: number;
}
/**
* Article tags for categorization
*/
interface ArticleTag {
/** Industry classifications from GICS */
gics: GicsTag[];
/** Business models */
businessModel: string[];
/** Moats */
moat: string[];
/** Other content tags */
other: string[];
}
/**
* Company information related to an article
*/
interface ArticleCompany {
/** Unique company identifier (UUID) */
id: string;
/** Company name as stored in database */
name: string;
/** Display name for the company (may differ from name) */
nameDisplay: string;
/** Stock ticker symbol */
ticker: string;
/** URL-friendly slug for the company */
slug: string;
/** Whether this is the primary company for the article */
primary: boolean;
/** Business models associated with the company */
businessModel: string[];
/** Moats associated with the company */
moat: string[];
/** Industry classifications from GICS */
industries: GicsTag[];
/** Brief explanation of why this company is interesting */
whyInteresting: string;
}
/**
* Main article object
*/
interface Article {
/** Unique article identifier (UUID) */
id: string;
/** Full URL to the article on inpractise.com */
url: string;
/** Article title */
title: string;
/** Type of content (see ArticleType enum) */
type: ArticleType;
/** ISO 8601 date string (e.g., "2024-10-13T17:26:08.948Z") */
publishedDate: string | null;
/** Executive's job title (e.g., "Former VP at Manchester Tank") */
executiveTitle: string | null;
/** Executive's biography/background */
executiveBio: string | null;
/** Categorization tags */
tags: ArticleTag;
/** Complete article content in markdown format */
fullContent: string;
/** Notable quotes from the article in markdown format */
topQuotes: string;
/** Brief explanation of why this article is interesting */
whyInteresting: string;
/** Companies mentioned or analyzed in the article */
companies: ArticleCompany[];
}
/**
* Pagination information
*/
interface Pagination {
/** Current page number (1-indexed) */
currentPage: number;
/** Total number of pages available */
totalPages: number;
/** Total count of articles across all pages */
totalArticles: number;
/** Whether there is a next page */
hasNextPage: boolean;
/** Whether there is a previous page */
hasPreviousPage: boolean;
}
/**
* API response structure
*/
interface ApiResponse {
/** Pagination metadata */
pagination: Pagination;
/** Array of articles (max 100 per page) */
articles: Article[];
}
/**
* Error response structure
*/
interface ApiError {
/** Human-readable error message */
error: string;
/** Machine-readable error code */
code: string;
/** Additional error details (for validation errors) */
details?: any;
/** When rate limit resets (ISO 8601, for 429 errors) */
resetTime?: string;
}
/**
* Query parameters for the API
*/
interface QueryParams {
/** Page number (default: 1, min: 1) */
page?: number;
/** Filter by publish date start (ISO 8601) */
publishDateStart?: string;
/** Filter by publish date end (ISO 8601) */
publishDateEnd?: string;
}Download a compressed archive of articles for organizations with archive access
Organizations with active article archive subscriptions can download pre-generated ZIP files containing their configured article sets. The archive includes full article content and metadata in JSON format.
# Direct browser access or curl
curl -L "https://inpractise.com/api/v1/article-archive/your-secret-token-here"
# The endpoint will redirect to a signed S3 download URL
# Download will start automatically with filename: inpractise-articles-{org-id}.zipFound (Redirect)
Successfully authenticated. Redirects to signed S3 download URL.
Bad Request
Missing archive secret in URL
Not Found
Invalid archive secret or archive file not yet generated
Forbidden
No active subscription with article archive access
The downloaded ZIP file contains a single JSON file with the following structure:
{
"generatedAt": "2024-01-15T02:00:00.000Z",
"organisationId": "uuid-here",
"filters": {
"articleTypes": ["company_profile", "analysis"],
"publishDateStart": null,
"publishDateEnd": "2024-01-01T00:00:00.000Z"
},
"totalArticles": 150,
"articles": [
{
"id": "article-uuid",
"url": "https://inpractise.com/articles/article-slug",
"title": "Article Title",
"type": "company_profile",
"publishedDate": "2023-06-15T10:30:00.000Z",
"fullContent": "Complete article content in markdown...",
"topQuotes": "Key quotes from the article...",
"companies": [...],
"tags": {...}
}
]
}Note: Both publishDateStart and publishDateEnd are optional. A null value for publishDateStart means all articles from the beginning will be included. A null value for publishDateEnd means all articles up to the current date will be included.
Retrieve a single article by its slug or UUID with full content
Article slug or UUID
Bearer token (org API key)
1,000 requests / 24 hours
Article slug (e.g., "microsoft-azure-strategy") or UUID
{
"id": "046f8a5c-...",
"title": "Microsoft Azure Strategy",
"slug": "microsoft-azure-strategy",
"url": "https://inpractise.com/articles/microsoft-azure-strategy",
"type": "ip_hosted",
"publishedDate": "2024-01-15T00:00:00.000Z",
"content": "Full article markdown content...",
"companies": [
"Microsoft"
],
"industries": [
"Technology"
],
"businessModels": [
"Cloud"
],
"moats": [
"Switching Costs"
],
"tags": [
"cloud",
"azure"
],
"expertName": "Former Director at Microsoft",
"expertTitle": "Director, Azure Platform",
"expertBlurb": "10 years at Microsoft...",
"isPrivate": false,
"isFree": false
}interface ArticleDetail {
/** Unique article identifier (UUID) */
id: string;
/** Article title */
title: string;
/** URL-friendly slug */
slug: string;
/** Full URL to the article */
url: string;
/** Article type */
type: string;
/** ISO 8601 publish date */
publishedDate: string;
/** Full article content in markdown format */
content: string;
/** Company names associated with the article */
companies: string[];
/** Industry names */
industries: string[];
/** Business model names */
businessModels: string[];
/** Moat names */
moats: string[];
/** Content tags */
tags: string[];
/** Expert's name/title attribution */
expertName: string;
/** Expert's job title */
expertTitle: string;
/** Brief expert background */
expertBlurb: string;
/** Whether the article is private */
isPrivate: boolean;
/** Whether the article is free to access */
isFree: boolean;
}UNAUTHORIZED / INVALID_API_KEY / NO_ACTIVE_SUBSCRIPTION
Missing or invalid authorization, or no active API subscription
NOT_FOUND
Article not found
RATE_LIMIT_EXCEEDED
Too many requests
INTERNAL_ERROR
Server error
Search articles by keywords, companies, industries, moats, and business models
Search keywords
Page number (default 1)
Comma-separated: ip_analysis, ip_resource, ip_hosted, 3p_interview, etc.
Comma-separated company names
Comma-separated symbols (e.g., AAPL,MSFT)
Comma-separated industries
Comma-separated moats
Comma-separated business models
Bearer token (org API key)
5,000 requests / 24 hours
Search keywords
Page number for pagination
Comma-separated article types: ip_analysis, ip_resource, ip_hosted, 3p_interview, ip_dialogue, ip_weekly_update, ip_company_profile, ip_value_chain, ip_podcast, ip_survey
Comma-separated company names
Comma-separated FMP symbols (e.g., AAPL,MSFT)
Comma-separated industry names
Comma-separated moat names
Comma-separated business model names
{
"page": 1,
"totalPages": 5,
"totalHits": 230,
"articles": [
{
"id": "046f8a5c-da85-49b8-9b32-826b15e97986",
"title": "TerraVest: Asia Manufacturing Threat",
"slug": "terravest-asian-threat",
"url": "https://inpractise.com/articles/terravest-asian-threat",
"type": "3p_interview",
"datePublished": "2024-10-13T17:26:08.948Z",
"companies": [
"TerraVest"
],
"industries": [
"Energy"
],
"businessModels": [
"Serial Acquirer"
],
"moats": [
"Manufacturing Scale"
],
"tags": [
"propane",
"manufacturing"
],
"expertName": "Former VP at Manchester Tank",
"expertTitle": "VP Manufacturing",
"expertBlurb": "14 years in propane tank manufacturing",
"content": "Matched content section from search..."
}
]
}interface SearchArticlesResponse {
/** Current page number */
page: number;
/** Total number of pages */
totalPages: number;
/** Total number of matching articles */
totalHits: number;
/** Array of matching articles */
articles: SearchArticle[];
}
interface SearchArticle {
/** Unique article identifier (UUID) */
id: string;
/** Article title */
title: string;
/** URL-friendly slug */
slug: string;
/** Full URL to the article */
url: string;
/** Article type */
type: string;
/** ISO 8601 publish date */
datePublished: string;
/** Company names associated with the article */
companies: string[];
/** Industry names */
industries: string[];
/** Business model names */
businessModels: string[];
/** Moat names */
moats: string[];
/** Content tags */
tags: string[];
/** Expert's name/title attribution */
expertName: string;
/** Expert's job title */
expertTitle: string;
/** Brief expert background */
expertBlurb: string;
/** Matched content section from search */
content: string;
}VALIDATION_ERROR
Invalid parameters
UNAUTHORIZED / INVALID_API_KEY / NO_ACTIVE_SUBSCRIPTION
Missing or invalid authorization, or no active API subscription
RATE_LIMIT_EXCEEDED
Too many requests
INTERNAL_ERROR
Server error
Search for companies by name, ticker, or symbol
Company name, ticker, or symbol
Bearer token (org API key)
5,000 requests / 24 hours
Company name, ticker, or symbol to search
{
"total": 3,
"companies": [
{
"id": "7b5c4a3d-eb91-4a9c-9a87-215b25f98987",
"name": "Apple",
"symbol": "AAPL",
"country": "US",
"articleCount": 150
}
]
}interface SearchCompaniesResponse {
/** Total number of matching companies */
total: number;
/** Array of matching companies */
companies: CompanyResult[];
}
interface CompanyResult {
/** Unique company identifier (UUID) */
id: string;
/** Company name */
name: string;
/** Stock ticker symbol */
symbol: string;
/** Country code (e.g., "US") */
country: string;
/** Number of articles about this company */
articleCount: number;
}VALIDATION_ERROR
Missing or invalid search parameter
UNAUTHORIZED / INVALID_API_KEY / NO_ACTIVE_SUBSCRIPTION
Missing or invalid authorization, or no active API subscription
RATE_LIMIT_EXCEEDED
Too many requests
INTERNAL_ERROR
Server error
Retrieve platform context data including watchlist, moats, business models, top companies, and latest articles
Email of a user in your organization
Bearer token (org API key)
5,000 requests / 24 hours
Email of a user in your organization
interface CoreDataResponse {
watchlist: {
companies: Array<{
symbol: string;
name: string;
moats: string[];
businessModels: string[];
articleCount: number;
}>;
industries: string[];
moats: string[];
businessModels: string[];
};
allMoats: Array<{
name: string;
articleCount: number;
companyCount: number;
}>;
allBusinessModels: Array<{
name: string;
articleCount: number;
companyCount: number;
}>;
topCompanies: {
"50+ articles": string[];
"30-49 articles": string[];
"20-29 articles": string[];
"11-19 articles": string[];
};
latestArticles: Array<{
title: string;
slug: string;
publishedDate: string;
companies: string[];
businessModels: string[];
moats: string[];
expertTitle: string;
}>;
}VALIDATION_ERROR
Missing userEmail parameter
UNAUTHORIZED / INVALID_API_KEY / NO_ACTIVE_SUBSCRIPTION / USER_NOT_IN_ORG
Missing or invalid authorization, no active subscription, or user not in your organization
USER_NOT_FOUND
User email not found
RATE_LIMIT_EXCEEDED
Too many requests
INTERNAL_ERROR
Server error
Retrieve a user's watchlist including companies, industries, moats, and business models
Email of a user in your organization
Bearer token (org API key)
5,000 requests / 24 hours
Email of a user in your organization
{
"companies": [
{
"id": "uuid",
"name": "Apple",
"symbol": "AAPL",
"country": "US",
"articleCount": 150,
"businessModels": [
"Hardware"
],
"moats": [
"Brand"
]
}
],
"industries": [
{
"code": 100,
"name": "Technology"
}
],
"moats": [
{
"id": "uuid",
"name": "Network Effects"
}
],
"businessModels": [
{
"id": "uuid",
"name": "SaaS"
}
]
}interface WatchlistResponse {
companies: Array<{
id: string;
name: string;
symbol: string;
country: string;
articleCount: number;
businessModels: string[];
moats: string[];
}>;
industries: Array<{
code: number;
name: string;
}>;
moats: Array<{
id: string;
name: string;
}>;
businessModels: Array<{
id: string;
name: string;
}>;
}VALIDATION_ERROR
Missing userEmail parameter
UNAUTHORIZED / INVALID_API_KEY / NO_ACTIVE_SUBSCRIPTION / USER_NOT_IN_ORG
Missing or invalid authorization, no active subscription, or user not in your organization
USER_NOT_FOUND
User email not found
RATE_LIMIT_EXCEEDED
Too many requests
INTERNAL_ERROR
Server error
Add items to a user's watchlist
Email of a user in your organization
JSON body
Bearer token (org API key)
5,000 requests / 24 hours
Email of a user in your organization
{
"items": [
{
"type": "company",
"idOrName": "Apple"
},
{
"type": "moat",
"idOrName": "Network Effects"
},
{
"type": "businessModel",
"idOrName": "SaaS"
},
{
"type": "industry",
"idOrName": "Technology"
}
]
}Item type: company, moat, businessModel, or industry
UUID or name of the item to add
{
"success": true,
"message": "Successfully added 4 items to watchlist",
"addedItems": {
"companies": 1,
"moats": 1,
"businessModels": 1,
"industries": 1
}
}VALIDATION_ERROR
Invalid parameters or request body
UNAUTHORIZED / INVALID_API_KEY / NO_ACTIVE_SUBSCRIPTION / USER_NOT_IN_ORG
Missing or invalid authorization, no active subscription, or user not in your organization
USER_NOT_FOUND / NOT_FOUND
User email not found or watchlist item not found
RATE_LIMIT_EXCEEDED
Too many requests
INTERNAL_ERROR
Server error
Remove items from a user's watchlist
Email of a user in your organization
JSON body
Bearer token (org API key)
5,000 requests / 24 hours
Email of a user in your organization
{
"items": [
{
"type": "company",
"idOrName": "Apple"
},
{
"type": "moat",
"idOrName": "Network Effects"
}
]
}Item type: company, moat, businessModel, or industry
UUID or name of the item to remove
{
"success": true,
"message": "Successfully removed 2 items from watchlist",
"removedItems": {
"companies": 1,
"moats": 1,
"businessModels": 0,
"industries": 0
}
}VALIDATION_ERROR
Invalid parameters or request body
UNAUTHORIZED / INVALID_API_KEY / NO_ACTIVE_SUBSCRIPTION / USER_NOT_IN_ORG
Missing or invalid authorization, no active subscription, or user not in your organization
USER_NOT_FOUND / NOT_FOUND
User email not found or watchlist item not found
RATE_LIMIT_EXCEEDED
Too many requests
INTERNAL_ERROR
Server error