People Inc Content API

Integration Guide — Content Retrieval & Search — v1

1. Overview

The People Inc Content API lets licensed clients retrieve the editorial content of any People Inc article as clean, structured markdown. The markdown is suitable for direct ingestion into LLM prompts, RAG pipelines, or any system that benefits from plain-text document representation.

The API exposes two complementary endpoints:

Both endpoints share the same authentication, rate-limit, and error conventions. This guide covers inputs, outputs, and integration patterns for each.

Base URL All sample requests use the base URL https://contentmarketplace.people.inc.
Versioning This is version v1, reflected in the /v1/ path prefix. Non-breaking additions (e.g. new optional fields) may land in v1 without notice. A breaking change would be introduced under a new path (e.g. /v2/) rather than changing v1's existing behavior in place.

2. Quickstart

Get a key, make one request, read the response. Full details on each step are linked below.

  1. Request an API key from the People Inc Content Marketplace team.
  2. Pick an endpoint and include the API key in the X-API-Key header (see Authentication):
    • Known article URL → GET /v1/markdown (see Content retrieval)
    • Natural-language question → POST /v1/search (see Search)

Retrieve by URL

# Retrieve an Investopedia article
curl -G https://contentmarketplace.people.inc/v1/markdown \
  --data-urlencode "url=https://www.investopedia.com/how-experts-recommend-managing-a-usd50k-inheritance-for-lasting-financial-securi-12004329" \
  -H "X-API-Key: YOUR_API_KEY"
{
  "status": 200,
  "markdown": "## How Experts Recommend Managing a $50K Inheritance\n\n...",
  "metadata": { /* ... */ }
}

Search by question

# Ground a question with ranked licensed sources
curl -X POST https://contentmarketplace.people.inc/v1/search \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{
    "question": "best meal prep tips for beginners"
  }'
{
  "question": "best meal prep tips for beginners",
  "documents": [ /* ranked grounding results */ ],
  "selection_summary": { /* ... */ }
}

That's it — you have a working integration. See Getting started checklist for the full pre-launch checklist, including error handling for statuses you'll see in normal operation.

3. Authentication

Every request to either endpoint must include an X-API-Key header containing the API key issued to your organization by the People Inc Content Marketplace team.

HeaderValue
X-API-Key Your issued API key Required
Key provisioning API keys are provisioned manually. Contact the People Inc Content Marketplace team to request a key. Do not share your key or commit it to source control.

A request with a missing or invalid key returns 401 Unauthorized. See Status codes for the full error shape.

4. Rate limits

Each API key is rate limited independently per route. By default, a key may make up to 100 requests per second against each of /v1/markdown and /v1/search. Requests beyond that limit receive a 429 Too Many Requests response.

Every 429 response includes a Retry-After header:

HeaderDescription
Retry-After Number of seconds to wait before retrying.
// 429 — rate limit exceeded
HTTP/1.1 429 Too Many Requests
Retry-After: 1

{
  "type": "about:blank",
  "status": 429,
  "title": "Too Many Requests",
  "detail": "Rate limit exceeded. Retry after the period indicated by Retry-After.",
  "instance": "/v1/markdown?url=..."
}
Need a higher limit? Starting at 100 requests per second per key, higher throughput can be arranged on a per-key basis. Contact the Content Marketplace team to discuss your volume needs.

5. Billing

Every successful (200) response from /v1/markdown is recorded as a billable event. 304 Not Modified responses to conditional requests (see Markdown response format) and error responses (4xx/5xx) are not billed.

Billing for /v1/search is governed by your licensing agreement. Contact the Content Marketplace team with questions about search usage or billing.

Usage visibility For questions about your usage or billing, contact the Content Marketplace team.

6. Content retrieval — GET /v1/markdown

GET /v1/markdown

Returns the markdown representation of the People Inc article at the given canonical URL.

Query parameters

ParameterTypeDescription
url string (URI) The canonical URL of the People Inc article you want to retrieve. Must be a fully-qualified URL. Use the https:// form and the canonical form of the URL — no trailing slash or query string. Required

Request headers

HeaderTypeDescription
X-API-Key string Your issued API key. See Authentication. Required
If-None-Match string Conditional-request header for caching. Pass the ETag value from a previous 200 response for the same url. If the article content is unchanged, the API responds 304 Not Modified with an empty body; if it has changed, you receive a normal 200 with the new content and a new ETag. See Markdown response format for details. Optional

Example request

# Retrieve an Investopedia article
curl -G https://contentmarketplace.people.inc/v1/markdown \
  --data-urlencode "url=https://www.investopedia.com/how-experts-recommend-managing-a-usd50k-inheritance-for-lasting-financial-securi-12004329" \
  -H "X-API-Key: YOUR_API_KEY"
POST /v1/search

Accepts a natural-language question and returns ranked, licensed People Inc articles suitable for grounding an AI response. Results include the same clean markdown available from GET /v1/markdown, so a single search call can both discover and retrieve source text.

What you get back Every entry in documents is a source you should ground with: ranked, licensed, and returned with the full article markdown. selection_summary describes the returned set as a whole.

Request body

Send a JSON object with Content-Type: application/json.

FieldTypeDefaultDescription
question string (max 2000 chars) — The natural-language question to ground (e.g. "best meal prep tips for beginners"). Must contain non-whitespace content — empty or whitespace-only values are rejected. Leading/trailing whitespace is trimmed. Required
limit integer (1–5) 5 Maximum number of results returned. Ranking considers a larger candidate pool internally; limit only caps how many of the best picks come back. For time-sensitive questions, only sufficiently relevant, recent content is returned, so fewer than limit results (possibly none) can come back. Optional
strategy "balanced" "balanced" Ranking strategy preset. Only balanced is available in v1. Optional

Request headers

HeaderTypeDescription
X-API-Key string Your issued API key. See Authentication. Required
Content-Type string Must be application/json. Required

Example request

# Search with defaults
curl -X POST https://contentmarketplace.people.inc/v1/search \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{
    "question": "best meal prep tips for beginners"
  }'

# Search with limit
curl -X POST https://contentmarketplace.people.inc/v1/search \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{
    "question": "best meal prep tips for beginners",
    "limit": 2
  }'

Response body (200 OK)

The response is a JSON object with these top-level fields:

FieldTypeDescription
question string The question as submitted.
documents array Ranked grounding results, up to limit. Every entry is a result you should use.
selection_summary object Aggregate stats over the selection. See below.

documents[]

Every entry is a grounding result — use them all.

FieldTypeDescription
doc_id string Stable document identifier.
url string Canonical article URL. Suitable for citation and for a follow-up GET /v1/markdown call.
domain string Publisher / brand domain label for the article.
rank integer 1-based position in documents. Always >= 1 when results are present — never 0.
content object Object with a markdown string (full article body) and the same metadata shape returned by GET /v1/markdown (see section 10).

selection_summary

FieldTypeDescription
selected_count integer How many documents were returned as grounding picks (length of documents).
domain_count integer Number of distinct publisher domains in the selected set.
total_wordcount integer | null Sum of content.metadata.wordcount across the selected set.

Example response

{
  "question": "best meal prep tips for beginners",
  "documents": [
    {
      "doc_id": "12345678",
      "domain": "Lifestyle",
      "url": "https://www.allrecipes.com/article/meal-prep-guide/",
      "rank": 1,
      "content": {
        "markdown": "# The Ultimate Guide to Meal Prep for Beginners\n\n...",
        "metadata": {
          "title": "The Ultimate Guide to Meal Prep for Beginners",
          "wordcount": 1850,
          "sourcetype": 0
        }
      }
    }
  ],
  "selection_summary": {
    "selected_count": 5,
    "domain_count": 4,
    "total_wordcount": 1850
  }
}
Recommended client usage Iterate documents in order (already sorted by rank) and pass each content.markdown (or url + a follow-up retrieval) into your LLM context.

8. Status codes

CodeMeaningApplies toWhat to do
200 Success Both Markdown: read the markdown field. Search: use every entry in documents.
304 Not modified /v1/markdown Returned for a conditional request (If-None-Match) when the content is unchanged since the supplied ETag. The body is empty — reuse your cached copy. See Markdown response format.
401 Unauthorized Both Your X-API-Key is missing or invalid. Verify the key and header name.
403 Not licensed /v1/markdown The article exists but is not available under your licensing agreement. Contact the Content Marketplace team if you believe this is in error.
404 Not found /v1/markdown If the article has moved, the Problem Details body includes a redirectUrl field — re-request that URL (see the "Moved articles" guidance in section 12). Otherwise, no content is available at the given URL. This can mean the URL is simply wrong, or that the article existed but is no longer available — for example it was unpublished, archived, or removed. The response does not distinguish between these cases; verify the article still exists on People Inc and that the URL is spelled correctly.
422 Invalid request Both Markdown: the url parameter is missing or is not a valid URI. Search: the JSON body failed validation (e.g. missing, empty, or whitespace-only question, question over 2000 characters, or limit out of range). Check the errors array in the Problem Details body.
429 Too many requests Both You have exceeded your API key's rate limit for that route. Check the Retry-After header and wait that many seconds before retrying. See Rate limits.
500 Server error Both An unexpected error occurred on our side. Retry with exponential backoff. If the issue persists, contact the People Inc Content Marketplace team.

9. Markdown response format

200 OK

The response body is a JSON object with the following fields:

FieldTypeDescription
status number The HTTP status code (200).
markdown string The full article content rendered as markdown.
metadata object Article metadata. See the field table below.

metadata fields:

FieldTypeDescription
title string Optional. The article title.
wordcount number Optional. Word count of the article body.
pubdate string (ISO 8601) Optional. When the article was first published.
update string (ISO 8601) Optional. When the article was last updated.
author array of strings Optional. Author name(s).
language string The article's language/locale (e.g. en-US).
sourcetype number Content origin per the CoMP convention: 0 = human created, 1 = AI created, 2 = hybrid.
cattax number Optional. IAB category taxonomy in use. Always 9 (IAB Content Category Taxonomy 3.1) for our content today.
cat array of strings Optional. IAB Tech Lab content category values for the article, per the cattax taxonomy. Omitted when no category could be matched.
published number Optional. CoMP publication status: 1 = publicly available. Always 1 for our content today.
provenance number Optional. Whether content-provenance data (e.g. C2PA) is available: 0 = no, 1 = yes. Always 0 for our content today.
ext object Optional. Implementer-specific extensions. Carries only bylineBlock (array of strings — formatted names for every non-author byline type, e.g. fact-checkers and reviewers) for our content today.
{
  "status": 200,
  "markdown": "## How Experts Recommend Managing a $50K Inheritance\n\n...",
  "metadata": {
    "title": "How Experts Recommend Managing a $50K Inheritance",
    "wordcount": 1240,
    "pubdate": "2023-11-14T22:13:20.000Z",
    "update": "2023-11-16T02:40:00.000Z",
    "author": ["Jane Doe"],
    "language": "en-US",
    "sourcetype": 0,
    "cattax": 9,
    "cat": ["216"],
    "published": 1,
    "provenance": 0,
    "ext": {
      "bylineBlock": ["John Smith, MD"]
    }
  }
}

Every 200 response also includes the following header:

HeaderDescription
ETag A quoted opaque identifier for this version of the article's markdown (e.g. "d41d8cd98f00b204e9800998ecf8427e"). The same content always yields the same ETag, and it changes whenever the underlying article changes. Store it and send it back via If-None-Match on your next request to revalidate.

304 Not Modified

When you send an If-None-Match header whose value matches the current ETag, the API responds 304 Not Modified with an empty body. Your previously cached markdown is still current — reuse it. If the content has changed, you instead receive a normal 200 with the updated markdown and a new ETag. This lets polling clients revalidate cheaply without re-downloading unchanged articles.

4xx / 5xx errors

All error responses follow RFC 9457 Problem Details:

FieldTypeDescription
typestring (URI)A URI identifying the error type.
statusnumberThe HTTP status code.
titlestringShort human-readable summary of the error type.
detailstringHuman-readable explanation of this specific occurrence.
instancestringThe request path that produced this error.
errorsarray422 only. Array of validation error objects, each with a path, message, and code.
redirectUrlstring404 only, when the article has moved. A new /v1/markdown request URL (relative) to re-request instead.
requestIdstring (UUID)Optional. Include this in any support request — it correlates this error to server-side logs.
// 401 — missing key
{
  "type": "about:blank",
  "status": 401,
  "title": "Unauthorized",
  "detail": "X-API-Key header is required",
  "instance": "/v1/markdown?url=..."
}

// 422 — invalid url parameter
{
  "type": "about:blank",
  "status": 422,
  "title": "Unprocessable Entity",
  "detail": "Invalid request payload",
  "instance": "/v1/markdown?url=not-a-url",
  "errors": [{ "path": ["url"], "message": "Invalid URL", "code": "invalid_format" }]
}

// 404 — article not found
{
  "type": "about:blank",
  "status": 404,
  "title": "Request Error",
  "detail": "Document not found",
  "instance": "/v1/markdown?url=...",
  "requestId": "f75d48b1-9c57-4844-a51b-8027c4fd7260"
}

10. Markdown conventions

The markdown returned by GET /v1/markdown and by documents[].content.markdown on POST /v1/search follows a consistent set of conventions designed for LLM ingestion. Understanding these will help you parse or post-process the content reliably.

Structure

Images

Links

Whitespace

11. Request & response examples

Successful markdown retrieval

### Request
GET /v1/markdown?url=https%3A%2F%2Fwww.investopedia.com%2Fhow-experts-recommend-managing-a-usd50k-inheritance-for-lasting-financial-securi-12004329
X-API-Key: YOUR_API_KEY

### Response — 200 OK
{
  "status": 200,
  "markdown": "## How Experts Recommend Managing a $50K Inheritance for Lasting Financial Security\n\nInheriting money can feel overwhelming...\n\n### Key Takeaways\n\n> - Consult a fee-only financial advisor before making any moves.\n> - Pay off high-interest debt first.\n\n## What To Do First...",
  "metadata": {
    "title": "How Experts Recommend Managing a $50K Inheritance for Lasting Financial Security",
    "wordcount": 1240,
    "pubdate": "2023-11-14T22:13:20.000Z",
    "update": "2023-11-16T02:40:00.000Z",
    "author": ["Jane Doe"],
    "language": "en-US",
    "sourcetype": 0,
    "cattax": 9,
    "cat": ["216"],
    "published": 1,
    "provenance": 0
  }
}

Conditional request (caching)

The first response returns an ETag. On the next poll, send it back via If-None-Match; if nothing changed you get a 304 with no body and can reuse your cached copy.

### First request
GET /v1/markdown?url=https%3A%2F%2Fwww.investopedia.com%2Fhow-experts-recommend-managing-a-usd50k-inheritance-for-lasting-financial-securi-12004329
X-API-Key: YOUR_API_KEY

### Response — 200 OK
ETag: "d41d8cd98f00b204e9800998ecf8427e"

{ "status": 200, "markdown": "## How Experts Recommend..." }

### Follow-up request — revalidate with the ETag
GET /v1/markdown?url=https%3A%2F%2Fwww.investopedia.com%2Fhow-experts-recommend-managing-a-usd50k-inheritance-for-lasting-financial-securi-12004329
X-API-Key: YOUR_API_KEY
If-None-Match: "d41d8cd98f00b204e9800998ecf8427e"

### Response — 304 Not Modified (empty body; reuse cached markdown)

Successful search

### Request
POST /v1/search
Content-Type: application/json
X-API-Key: YOUR_API_KEY

{
  "question": "best meal prep tips for beginners",
  "limit": 5
}

### Response — 200 OK
{
  "question": "best meal prep tips for beginners",
  "documents": [
    {
      "doc_id": "12345678",
      "url": "https://www.allrecipes.com/article/meal-prep-guide/",
      "domain": "Lifestyle",
      "rank": 1,
      "content": {
        "markdown": "# The Ultimate Guide to Meal Prep for Beginners\n\n...",
        "metadata": { "title": "The Ultimate Guide to Meal Prep for Beginners", "sourcetype": 0 }
      }
    }
  ],
  "selection_summary": {
    "selected_count": 5,
    "domain_count": 4
  }
}

Article moved

### Request
GET /v1/markdown?url=https%3A%2F%2Fwww.investopedia.com%2Fold-article-slug-12345
X-API-Key: YOUR_API_KEY

### Response — 404 Not Found
{
  "type":        "about:blank",
  "status":      404,
  "title":       "Not Found",
  "detail":      "Document has moved",
  "instance":    "/v1/markdown?url=...",
  "redirectUrl": "/v1/markdown?url=https%3A%2F%2Fwww.investopedia.com%2Fnew-article-slug-12345"
}

Article not found

### Response — 404 Not Found
{
  "type":      "about:blank",
  "status":    404,
  "title":     "Request Error",
  "detail":    "Document not found",
  "instance":  "/v1/markdown?url=...",
  "requestId": "f75d48b1-9c57-4844-a51b-8027c4fd7260"
}

Example client wrapper (TypeScript)

Not an official SDK There is no official SDK for this API today, in any language — the snippet below is a minimal example wrapper to illustrate the integration pattern, not a package you install. Adapt it to your own language and conventions, or contact the Content Marketplace team if an official SDK would help your integration.
// Minimal typed wrapper — adapt baseUrl and key storage to your environment
const BASE_URL = "https://contentmarketplace.people.inc";

interface ArticleMetadata {
  title?: string;
  wordcount?: number;
  pubdate?: string;
  update?: string;
  author?: string[];
  language: string;
  sourcetype: number;
  cattax?: number;
  cat?: string[];
  published?: number;
  provenance?: number;
  ext?: { bylineBlock?: string[] };
}

interface ArticleResponse {
  status: number;
  markdown: string;
  metadata: ArticleMetadata;
}

// Thrown instead of a plain Error when the article has moved, so callers can
// branch on it explicitly rather than have the redirect silently followed.
// A redirect can mean the requested article was replaced, corrected, or taken
// down (e.g. under embargo) — the content at redirectUrl is not guaranteed to
// be "the same article". If the caller is acting on a human's behalf (for
// example, an LLM agent), confirm with the human before re-requesting rather
// than assuming the new URL satisfies their original request.
class ArticleMovedError extends Error {
  constructor(public readonly redirectUrl: string) {
    super(`Article moved: ${redirectUrl}`);
  }
}

async function getArticle(articleUrl: string, apiKey: string): Promise<ArticleResponse> {
  const endpoint = new URL("/v1/markdown", BASE_URL);
  endpoint.searchParams.set("url", articleUrl);

  const response = await fetch(endpoint.toString(), {
    headers: { "X-API-Key": apiKey },
  });

  if (!response.ok) {
    const err = await response.json();

    if (err.redirectUrl) {
      throw new ArticleMovedError(new URL(err.redirectUrl, BASE_URL).toString());
    }

    throw new Error(`[${response.status}] ${err.detail ?? err.title}`);
  }

  return response.json();
}

// Caller decides whether to re-request — do not do this automatically.
try {
  const article = await getArticle("https://www.example.com/old-article-slug", apiKey);
} catch (err) {
  if (err instanceof ArticleMovedError) {
    // Confirm with the user before fetching err.redirectUrl.
  }
}

12. Error handling guidance

Retries

5xx responses are safe to retry. Use exponential backoff with jitter, starting at 1 second and capping at 30 seconds. Do not retry 4xx responses — they indicate a problem with the request itself.

Moved articles

When an article's canonical URL has changed, the API responds 404 with a redirectUrl field in the Problem Details body (see section 9) rather than issuing an HTTP redirect. Check for this field on every 404 response.

Don't auto-follow without confirmation A redirectUrl does not guarantee the destination is the same article — redirects also occur when content is replaced, corrected, or taken down (e.g. under embargo). Treat it as a candidate, not a guaranteed match. If your integration acts on behalf of a human (for example, an LLM agent retrieving content per a user's request), confirm with the user before re-requesting the new URL rather than silently substituting different content for what they asked for.

URL encoding

The url query parameter must be percent-encoded. Use your language's standard URI encoding function (encodeURIComponent in JavaScript, urllib.parse.quote in Python, etc.) rather than encoding it manually. A common mistake is passing the URL unencoded, which causes the article URL's path to be misinterpreted as part of the request path.

13. Getting started checklist

  1. Request an API key from the People Inc Content Marketplace team.
  2. Make a test GET /v1/markdown request using the curl example in section 6 with a known article URL. Verify a 200 with a non-empty markdown field.
  3. Make a test POST /v1/search request using the curl example in section 7. Verify a 200 with at least one documents entry.
  4. Integrate the X-API-Key header into your HTTP client — ensure the key is read from an environment variable or secrets manager, not hardcoded.
  5. Handle the status codes documented in section 8, particularly 404s on markdown (check for a redirectUrl before treating them as not-found), 403 not-licensed, 422 validation errors, and 429 rate-limiting, which will occur in normal operation.

14. Contact

For any questions or support, please contact the People Inc Content Marketplace team at [email protected].