Query Contents
Paginate the content items collected for your workspace.
Content endpoints expose content created or collected for the authenticated workspace.
Request body
| Field | Type | Description |
|---|---|---|
| page | integer | Page number (default 1). |
| page_size | integer | Number of items per page (default 25). |
| date_from | string | ISO 8601 timestamp. Include content created at or after this date. |
| date_to | string | ISO 8601 timestamp. Include content created at or before this date. |
| content_type | string[] | Filter by content type. Native JSON array. Valid values: linkedinComment, recentlyPromoted, linkedinPost, linkedinCompanyPost, linkedinJobPosting, webArticle, pressRelease, blogPost. |
| company_id | integer | Filter by company numeric SQL id. Takes priority over all human-identifier fields. |
| company_domain | string[] | Filter by company domain(s). Native JSON array. Maximum 100 values. Resolved to company IDs via a single-winning-tier waterfall: company_id > company_linkedin_handle > company_linkedin_url > company_domain. Only the highest-priority supplied tier is used. |
| company_linkedin_handle | string[] | Filter by company LinkedIn handle(s) (slug, e.g. acme-corp). Native JSON array. Maximum 100 values. See company_domain for tier priority. |
| company_linkedin_url | string[] | Filter by company LinkedIn URL(s) (e.g. https://www.linkedin.com/company/acme-corp). Native JSON array. Maximum 100 values. See company_domain for tier priority. |
| lead_id | integer | Filter for content authored by one lead. Use the lead_id shown on each content item, returned by the signals endpoints, or from the lead lookup endpoint. |
| response_format | string | Controls whether the data field is included and how detailed it is. Valid values: normalized (default), concise, detailed (deprecated alias of normalized). See Response formats. |
Response formats
The response_format field controls what each item's data field contains:
normalized(default): a clean, type-specific object built from the underlying content. See the shapes below.concise: thedatafield is omitted entirely. Lowest token footprint, useful when you only need ids, types and timestamps.detailed: deprecated alias ofnormalized, kept for backward compatibility. Usenormalizedgoing forward.
Every field inside data is best-effort: a field the underlying content does not carry (engagement, mentions, images, …) is simply omitted rather than sent as null.
engagement uses the same flat shape for posts and comments: likes, comments (comments on a post, or replies to a comment), shares (posts only), and a per-reaction-type breakdown — praise, empathy, interest, appreciation — whenever the source exposes it.
LinkedIn posts (linkedinPost, linkedinCompanyPost)
{
"post_id": "7440055204630249472",
"original_post_id": "7439950617915080704",
"is_repost": true,
"link": "https://www.linkedin.com/posts/sillage-signals_last-week-arnaud-weiss-and-arthur-coudouy-activity-7440055204630249472-vKkM",
"text": "Thank you for featuring us! 🔥",
"posted_at": "2026-03-18T15:23:10.325Z",
"engagement": { "likes": 1, "comments": 0, "shares": 0, "praise": 0, "empathy": 0 },
"author": {
"type": "company",
"company_name": "Sillage",
"linkedin_url": "https://www.linkedin.com/company/sillage-signals/"
},
"mentions": {
"profiles": [
{
"name": "Arnaud Weiss",
"linkedin_url": "https://www.linkedin.com/in/arnaud-weiss-60b6758a"
}
],
"companies": [
{
"name": "Salesforce",
"linkedin_url": "https://www.linkedin.com/company/salesforce/"
}
]
},
"images": [
"https://media.licdn.com/dms/image/v2/D4E22AQE.../feedshare-shrink_800/0/1710000000000"
]
}images is an array of image URL strings attached to the post, in no particular order.
author.type is profile or company. Profile authors carry full_name, headline (nullable), and linkedin_url; company authors carry company_name and linkedin_url (no headline). A repost keeps this same flat shape: is_repost is true and original_post_id points at the original post, which you can fetch separately if you need its own content.
Each entry in mentions.profiles and mentions.companies is intentionally lightweight — just name and linkedin_url, with no type discriminator — since which array the entry appears in already tells you whether it's a profile or a company.
LinkedIn comments (linkedinComment)
{
"linkedin_id": "7175492449631371265",
"text": "Congrats on the launch!",
"linkedin_url": "https://www.linkedin.com/feed/update/urn:li:activity:123?commentUrn=456",
"posted_at": "2026-03-18T15:05:14.196Z",
"engagement": {
"comments": 0,
"likes": 1,
"praise": 0,
"empathy": 0,
"interest": 0,
"appreciation": 0
},
"author": {
"type": "profile",
"full_name": "Jean Dupont",
"headline": "VP Sales @ Acme",
"linkedin_url": "https://www.linkedin.com/in/jeandupont"
},
"post_content_id": 10762
}linkedin_id is the comment's own LinkedIn id and linkedin_url links to it on LinkedIn. posted_at is when the comment was left. engagement.comments is the number of replies to this comment; engagement.likes and the reaction breakdown work the same way as on posts. author is the person who left the comment. post_content_id is the workspace content ID of the post the comment was left on — pass it to GET /api/v2/contents/{id} to fetch the full post. It is null when that post is not among your workspace's contents.
LinkedIn job postings (linkedinJobPosting)
{
"linkedin_id": "9988776655",
"linkedin_url": "https://www.linkedin.com/jobs/view/senior-software-engineer-at-sillage-9988776655",
"title": "Senior Software Engineer",
"min_salary": null,
"max_salary": null,
"location": "Paris, ÃŽle-de-France, France",
"posted_at": "2025-11-12T00:00:00.000Z",
"description": "About Us — Sillage helps go-to-market teams turn public signals into pipeline…"
}linkedin_id is the job posting's own LinkedIn id. description is the full plain-text job description. min_salary and max_salary are null when LinkedIn does not expose a salary range for the posting. As with the other shapes, any field the underlying content does not carry is omitted rather than sent as null.
LinkedIn reactions (linkedinReaction)
linkedinReaction cannot be requested through content_type on this endpoint, but a reaction can still be returned when you fetch a stored content item directly by id with GET /api/v2/contents/{id}.
{
"reaction_type": "CELEBRATE",
"author": {
"type": "profile",
"full_name": "Jean Dupont",
"headline": "VP Sales @ Acme",
"linkedin_url": "https://www.linkedin.com/in/jeandupont"
},
"post": {
"post_id": "7440055204630249472",
"link": "https://www.linkedin.com/posts/sillage-signals_activity-7440055204630249472",
"text": "We just closed our pre-seed…",
"author": {
"type": "company",
"company_name": "Sillage",
"linkedin_url": "https://www.linkedin.com/company/sillage-signals/"
}
}
}Other content types
For every other content_type, data is { "text": "…" } when text content is available, and omitted entirely otherwise.
Example request
curl -X POST "https://api.getsillage.com/api/v2/contents/query" \
-H "Authorization: Bearer $SILLAGE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"page":1,"page_size":10,"company_domain":["acme.com","example.com"]}'const response = await fetch('https://api.getsillage.com/api/v2/contents/query', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SILLAGE_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
page: 1,
page_size: 10,
company_domain: ['acme.com', 'example.com'],
}),
})
const result = await response.json()import { request } from 'node:https'
const body = JSON.stringify({
page: 1,
page_size: 10,
company_domain: ['acme.com', 'example.com'],
})
const req = request(
new URL('https://api.getsillage.com/api/v2/contents/query'),
{
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SILLAGE_API_KEY}`,
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(body),
},
},
(res) => {
let data = ''
res.on('data', (chunk) => {
data += chunk
})
res.on('end', () => {
console.log(JSON.parse(data))
})
},
)
req.write(body)
req.end()import os
import requests
response = requests.post(
"https://api.getsillage.com/api/v2/contents/query",
json={
"page": 1,
"page_size": 10,
"company_domain": ["acme.com", "example.com"],
},
headers={"Authorization": f"Bearer {os.environ['SILLAGE_API_KEY']}"},
timeout=30,
)
response.raise_for_status()
result = response.json()Example response
{
"data": [
{
"id": 120384,
"content_type": "linkedinPost",
"created_at": "2026-06-12T09:15:00.000Z",
"data": {
"post_id": "7440055204630249472",
"is_repost": false,
"link": "https://www.linkedin.com/posts/sillage-signals_activity-7440055204630249472-vKkM",
"text": "Thank you for featuring us! 🔥",
"posted_at": "2026-06-12T09:00:00.000Z",
"engagement": { "likes": 12, "comments": 2, "shares": 1 },
"author": {
"type": "profile",
"full_name": "Jean Dupont",
"headline": "VP Sales @ Acme",
"linkedin_url": "https://www.linkedin.com/in/jeandupont"
}
},
"lead_id": 3301,
"company_id": 8421
}
],
"meta": {
"pagination": {
"page": 1,
"page_size": 10,
"page_count": 5,
"total": 47
},
"resolved_companies": [
{
"company_id": 8421,
"matched_by": "domain",
"identifier": "acme.com"
},
{
"company_id": 9103,
"matched_by": "domain",
"identifier": "example.com"
}
]
}
}meta.resolved_companies
Contains one entry per company matched from a company filter (company_id, company_domain, company_linkedin_handle, or company_linkedin_url).
| Field | Type | Description |
|---|---|---|
| company_id | integer | Numeric SQL id of the matched company. |
| matched_by | string | Which identifier tier produced this match. One of: company_id, linkedin_handle, linkedin_url, domain. |
| identifier | string | The original identifier value supplied by the caller (domain, handle, URL, or numeric id echoed as a string). |
All entries share the same matched_by value for a given response — only the single winning tier resolves. When no company filter is supplied, resolved_companies is an empty array.