TABLE OF CONTENTS
ADMIN PRIVILEGES REQUIRED
Overview
The Stack Internal API content endpoints allow you to add knowledge from locations that do not have a premade Stack Internal source. This could be knowledge stored in your company's intranet, another online system, or documents on a local drive.
The ingestion process starts when you prep the content, source details, and access control information in the format needed by the content API. You then push the content to the API, where Stack Internal ingests it for processing with your other knowledge sources.
You can read technical details of the API at https://api.stackinternal.com/apis/v1/content, including content endpoints, schema, and responses.
The API content endpoints release on 9/30/26. The API is in active development, and should be considered an alpha release. Use at your own risk.
Authentication
You'll use the normal Stack Internal API authentication process to access the content API. To connect quickly to the API, read the Stack Internal API Quick Connect Guide. For more details, read the API Applications article.
You'll send a Stack Internal OAuth access token with every request in the authorization header, like this: Authorization: Bearer [token]. The token must be for the Stack Internal workspace that will own the content.
Creating and updating content requires the content:ingest permission. Deleting content requires the content:delete permission.
API request payload
Every content API call has a set of common properties (fields), plus a data object whose properties differ based on content type. Required common properties include:
- source The Source ID of an API source you connected (registered) on the Stack Internal Control Center "Sources" page.
- sourceId Use the unique ID assigned by the source system. If it doesn't provide one, create a unique ID that identifies the item and doesn't change. Example: "benefits-ovw_2028-10-22_h4bu92c".
- sourceUri The source's location (absolute uniform resource identifier). Examples: "file:///C:/docs/benefits.xls", "urn:isbn:1234567890", "https://intranet.company.com/articles/12345".
- acls Who can view the source item (access control list). Add an entry for each allowed group, domain, or person. Specify kind, provider, and identifier. Example: "[{ "kind": "group", "provider": "entra", "identifier": "engineering-all" }]". Valid kind values:
- domain
- group
- user
- anyone
- entityType See "Content type" section below.
- data This property object defines the actual data sent, and includes several properties specific to the type of data.
- data.representation Set this to "archetype".
- data.dataSchema See "Content type" section below.
- data.representationVersion Set this to 1.
- data.archetype See "data.archetype" section below.
- data.data The main data object. The properties included here differ by archetype. For more information on the properties used for each data archetype, see the "Data archetypes" section at the end of this article.
The content's source plus sourceId (combined) must be unique.
Content type
Correctly determining and identifying the type of content you're sending to the API is one of the most important steps in the data upload process. The payload's entityType property indicates the overall content type, while data.archetype defines the specific structure of the uploaded data.
entityType
Set entityType as a consistent "broad strokes" source-specific label for the content type. Stack Internal pairs this with the content's source value to select the correct processing and relationship logic when it creates knowledge nodes. The content API doesn't specify values for the entityType string–you can define them for your use case, just be sure to implement the values consistently.
entityType examples:
- answer
- attachment
- article
- message
- markdown-file
- document
Each piece of content you send by API should have an entityType that closely matches its type and purpose.
data.archetype
Unlike entityType, which is a broad description of the content, data.archetype identifies the specific schema (structure) of the data you're sending to the API. That schema defines the data properties and processing rules for the content. For example: the properties you'll send for the "conversation" archetype differ from those of the "document" archetype.
Valid data.archetype values are shown below, with their respective data.dataSchema values.
data.archetype |
data.dataSchema |
|---|---|
changeArtifact |
com.stackoverflow.stackinternal.content.archetype.changeArtifact.v1 |
container |
com.stackoverflow.stackinternal.content.archetype.container.v1 |
conversation |
com.stackoverflow.stackinternal.content.archetype.conversation.v1 |
document |
com.stackoverflow.stackinternal.content.archetype.document.v1 |
message |
com.stackoverflow.stackinternal.content.archetype.message.v1 |
metricSnapshot |
com.stackoverflow.stackinternal.content.archetype.metricSnapshot.v1 |
session |
com.stackoverflow.stackinternal.content.archetype.session.v1 |
sourceEvent |
com.stackoverflow.stackinternal.content.archetype.sourceEvent.v1 |
structuredRecord |
com.stackoverflow.stackinternal.content.archetype.structuredRecord.v1 |
workItem |
com.stackoverflow.stackinternal.content.archetype.workItem.v1 |
For more information on data archetypes, see the "Data archetypes" section at the end of this article.
Use the API
To use the API, send all requests to https://api.stackinternal.com (or https://api.eu.stackinternal.com for users in the EU).
POST
To add content with the API, send a POST request. If the call is successful, the API will return the new content's contentId in the "201 Created" response. Copy that value and attach it to the source file in your system. You'll need to specify the contentId to update or delete the item later.
If you post content whose source + sourceID already exists in the database, you'll receive a "409 Conflict" response. That response's Location header will contain the contentId of the existing content. Use that ID with a PUT request to update the existing content.
PUT
To update an item, send a PUT request. You can update the sourceUri, acls, entityType, and data values. Include all four properties in every PUT request.
The PUT "200 OK" response returns a new contentId. Be sure to capture that value and attach it to the updated content in your system.
DELETE
To remove an item, send a DELETE request. A successful deletion returns "204 No Content". DELETE calls have no request body.
Deleting a content record with the API removes that stored record only; it does not remove derived knowledge nodes. To remove ingested content, contact Stack Internal support.
Where the API gets content
The content API receives all content from the API request itself, in properties specified by the archetype. It never follows a link (for example: sourceUri) to access content.
POST example
This example adds a document to Stack Internal for ingestion. Some things to note:
- It uses the document archetype.
- It specifies a document on a local filesystem (
sourceUri). - It supplies the content of the document, in plain text, in the
data.textContentproperty. - It includes an intranet link for users to see the original source (
data.data.sourceUri).
{
"source": "HR-NAS",
"sourceId": "article-12345",
"sourceUri": "file:///S:/docs/accounting/benefits.docx",
"acls": [
{
"kind": "group",
"provider": "entra",
"identifier": "hr-all"
}
],
"entityType": "document",
"data": {
"representation": "archetype",
"representationVersion": 1,
"archetype": "document",
"dataSchema": "com.stackoverflow.stackinternal.content.archetype.document.v1",
"data": {
"title": "Benefits article",
"textContent": "The full content of the article, in text format.",
"summary": "Information about employee benefits.",
"documentType": "article",
"createdAt": "2026-09-15T09:00:00Z",
"lastModifiedAt": "2026-09-15T14:30:00Z",
"personaRefs": [
"employee-123",
"employee-456"
],
"containerRef": "folder:human-resources",
"sourceUri": "https://intranet.company.com/docs/human-resources/benefits.docx",
"mimeType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"language": "en",
"tagsJson": "[\"benefits\",\"human-resources\"]",
"status": "published",
"sourceVersion": "1",
"metadataJson": "{\"department\":\"human-resources\"}"
}
}
}
Common response codes
Below are common request codes, their meaning, and the endpoints that generate them.
| Response code | Meaning | Endpoint |
|---|---|---|
| 200 OK | Returns contentId for the newly stored content version. |
PUT |
| 201 Created | Returns contentId for the stored content version that was created. |
POST |
| 204 No Content | PUT: No new version is created because the content is unchanged. DELETE: The content exists and is deleted. | PUT, DELETE |
| 400 Bad Request | The request is missing a required value or does not match the selected content schema. Review the response details and correct the request. | POST, PUT, DELETE |
| 401 Unauthorized | Check that you sent a valid token with the required permission for the correct workspace. | All |
| 403 Forbidden | Check that you sent a valid token with the required permission for the correct workspace. | All |
| 404 Not Found | The contentId specified does not exist in your workspace. Check the ID you saved when the item was created. |
PUT, DELETE |
| 409 Conflict | An item with the same source and sourceId already exists. Use the returned contentId in the Location header to update that item instead. |
POST |
Get help
If you need help with the content API, reach out to our support team.
Data archetypes
changeArtifact
A versioned change unit whose primary meaning is the proposed or completed change itself. Most visible in GitHub, but is intentionally cross-source.
more details
Representative source mappings
- GitHub:
commit,pull_request,release
Data structure
| Property | Definition |
|---|---|
title |
Commit subject, pull request title, or release name. |
descriptionText |
Commit body, pull request description, or release notes. |
changeType |
Commit, pull request, release, patch, or version bump. |
createdAt |
Creation time. |
updatedAt |
Latest metadata change. |
authoredByPersonaRef |
Author, creator, or publisher identifier. |
state |
Open, merged, closed, published, draft, or prerelease. |
baseRef |
Target branch, base version, or prior state. |
headRef |
Source branch, head SHA, or new state. |
mergedOrPublishedAt |
When the change landed or was published. |
linkedWorkItemRefsJson |
Related issues, tickets, or milestones. |
reviewMessageRefsJson |
Reviews and review comments. |
sourceUri |
Deep link to the change artifact. |
metadataJson |
Source-specific data such as SHA, tag, file stats, or merge queue state. |
Use when
- The object represents a concrete code, configuration, or release change.
- Review and provenance are part of its meaning.
Don't use when
- The object is primarily a task tracker entry; use Work Item.
- The object is a runtime occurrence; use Source Event.
Read more about the changeArtifact archetype in the API documentation.
container
A stable place that groups other content: spaces, repositories, projects, channels, teams, boards, and similar top-level or mid-level organizational units. This archetype matters because many user questions are scoped to a place rather than to one document or ticket.
more details
Representative source mappings
- Confluence:
space - Slack:
channel - Microsoft Teams:
team,channel - Jira:
project,board,service - GitHub:
repository,project_v_2,team
Data structure
| Property | Definition |
|---|---|
displayName |
Display name. |
descriptionText |
Purpose, description, topic, or charter. |
containerType |
Space, repository, board, team, channel, project, room, or service. |
createdAt |
Creation time. |
updatedAt |
Most recent metadata change. |
ownerRefs |
Owners, leads, maintainers, or administrators. |
visibility |
Public, private, internal, shared, or archived. |
parentContainerRef |
Parent team, organization, portfolio, or space. |
sourceUri |
Deep link to the container. |
metadataJson |
Source-specific context such as default branch or moderation settings. |
Use when
- The object is a durable grouping context that contains many artifacts.
Don't use when
- The object is an ordered exchange; use Conversation.
- The object is a time-bounded live interaction; use Session.
Read more about the container archetype in the API documentation.
conversation
An ordered exchange context that holds multiple messages and usually has stable participants, a time range, and a shared topic. The conversation is the container for the exchange, while individual utterances should usually become Message records.
more details
Representative source mappings
- Slack: channel threads, DMs, and group DMs
- Microsoft Teams: chats and channel threads
- Zoom: channels and conversations
- Confluence: comment threads
Data structure
| Property | Definition |
|---|---|
title |
Channel name, thread subject, topic, or generated label. |
summary |
Optional discussion summary. |
conversationType |
DM, group chat, channel thread, comment thread, or Q&A thread. |
startedAt |
Conversation start time. |
lastActivityAt |
Most recent activity time. |
participantRefs |
Observed source-system participant identifiers. |
messages |
Ordered normalized message archetypes. |
messageCount |
Number of messages. |
containerRef |
Containing workspace, team, channel, space, or project. |
status |
Active, closed, archived, resolved, or locked. |
sourceUri |
Deep link to the thread, chat, or channel. |
metadataJson |
Source-specific thread IDs, reply counts, and visibility details. |
Use when
- The sequence and participants of an exchange matter.
Don't use when
- You need only one utterance; use Message.
Read more about the conversation archetype in the API documentation.
document
A durable authored artifact whose primary value is its content, not its workflow state. This archetype covers wiki pages, blog posts, long-form custom content, and file-backed documents.
more details
Representative source mappings
- Confluence: pages, blog posts, custom content, attachments
- Google Docs and Drive: documents and staged files
- Slack: bookmarks and remote files
- Jira: analyzable attachments
Data structure
| Property | Definition |
|---|---|
title |
Human-readable document name. |
textContent |
Extracted body, OCR, or normalized text. |
summary |
Optional synopsis. |
documentType |
Page, blog post, file, note, knowledge article, or attachment. |
createdAt |
Creation time. |
lastModifiedAt |
Most recent modification time. |
personaRefs |
Observed identifiers for people who created or edited the document. |
containerRef |
Parent space, repository, drive, folder, channel, or project. |
sourceUri |
Canonical deep link to the source object. |
mimeType |
File or media type. |
language |
Natural language of the extracted content. |
tagsJson |
Serialized labels, categories, or taxonomies. |
status |
Draft, published, archived, deleted, or current. |
sourceVersion |
Version number or revision identifier. |
metadataJson |
Source-specific properties not promoted to the canonical surface. |
Use when
- Long-form text is the primary content.
Don't use when
- The object is primarily a conversation, task, or property-driven record.
Read more about the document archetype in the API documentation.
message
A single human- or system-authored entry within a conversation, work item, review flow, or comment thread. This archetype unifies chat messages, comments, review notes, replies, Q&A entries, and similar granular utterances.
more details
Representative source mappings
- Slack: messages and scheduled messages
- Microsoft Teams: chat and channel messages
- Confluence: inline and footer comments
- Jira: comments and worklogs
- GitHub: issue comments and review comments
Data structure
| Property | Definition |
|---|---|
textContent |
Message body or normalized text. |
title |
Optional subject or generated snippet. |
messageType |
Chat, comment, review, reply, Q&A, note, or announcement. |
createdAt |
Creation time. |
lastModifiedAt |
Latest edit time. |
personaRef |
Observed identifier of the author or sender. |
conversationRef |
Parent conversation. |
parentRef |
Parent work item, document, message, or review. |
replyToRef |
Direct parent message or comment. |
mentions |
Observed identifiers of mentioned users or entities. |
attachmentsJson |
Serialized attachments or linked artifacts. |
reactionsJson |
Serialized reaction metadata. |
sourceUri |
Deep link to the message. |
metadataJson |
Source-specific subtype, visibility, or context. |
Use when
- The unit of meaning is a single utterance.
Don't use when
- The main object is the overall thread; use Conversation.
Read more about the message archetype in the API documentation.
metricSnapshot
An aggregate measurement captured for a subject and a time window. This archetype is for analytics-style records rather than narrative content.
more details
Representative source mappings
- GitHub Copilot and GitHub: metrics
- Zoom: reports
- Jira: SLA data
- ServiceNow: reporting tables
Data structure
| Property | Definition |
|---|---|
metricFamily |
Usage, attendance, traffic, queue performance, or SLA. |
subjectRef |
The measured user, organization, repository, session, queue, or service. |
capturedAt |
Snapshot or period timestamp. |
periodStartAt |
Period start. |
periodEndAt |
Period end. |
dimensionsJson |
Serialized dimension values. |
measurementsJson |
Serialized numeric measures by metric name. |
aggregationLevel |
User, team, organization, repository, session, or queue. |
sourceUri |
Deep link to the source report. |
metadataJson |
Source-specific rollup data. |
Use when
- Numeric measures are the main payload.
Don't use when
- The row is one raw occurrence; use Source Event.
Read more about the metricSnapshot archetype in the API documentation.
session
A time-bounded live interaction such as a meeting, webinar, call, or event. The time window, participation, and runtime outcomes are core to its meaning.
more details
Representative source mappings
- Microsoft Teams: calls and sessions
- Zoom: meetings, webinars, events, phone calls, and SMS sessions
Data structure
| Property | Definition |
|---|---|
title |
Session name, topic, or generated label. |
descriptionText |
Description, agenda, or source summary. |
sessionType |
Meeting, webinar, call, event, or SMS session. |
startAt |
Start time. |
endAt |
End time. |
durationSeconds |
Duration. |
hostRefs |
Observed host, organizer, or owner identifiers. |
participantRefs |
Observed participant identifiers. |
status |
Scheduled, live, completed, canceled, or no-show. |
joinUrl |
Join URL or entry point. |
containerRef |
Containing organizational boundary. |
transcriptText |
Transcript or normalized spoken text. |
recordingRefsJson |
Serialized recording links or artifacts. |
sourceUri |
Deep link to the session. |
metadataJson |
Source-specific session context. |
Use when
- Participation and timing are as important as the text.
Don't use when
- The object is an ongoing thread; use Conversation.
Read more about the session archetype in the API documentation.
sourceEvent
An immutable occurrence from a source: something that happened at a point in time. This archetype fits webhook payloads, status transitions, automation runs, alerts, and other what-happened records.
more details
Representative source mappings
- API, SDK, and webhook: inbound rows
- GitHub: workflow and deployment events
- Jira: alerts and history rows
- Zoom: engagement events and call logs
Data structure
| Property | Definition |
|---|---|
eventType |
Name of the occurrence. |
title |
Optional short label. |
occurredAt |
When the event happened. |
actorRefs |
Observed identifiers of users, systems, or services that caused it. |
subjectRef |
The object affected by the event. |
containerRef |
Grouping context. |
status |
Outcome or resulting state. |
payloadText |
Textual payload or normalized description. |
payloadJson |
Serialized raw or normalized event payload. |
sourceUri |
Deep link to the source event. |
metadataJson |
Source-specific event context. |
Use when
- The row is an inherently timestamped occurrence.
Don't use when
- The row is an aggregate; use Metric Snapshot.
Read more about the sourceEvent archetype in the API documentation.
structuredRecord
A property-driven business object whose main value is its structured attributes rather than long-form prose or chronological exchange. This archetype is the escape valve that prevents over-specializing around source-specific custom objects.
more details
Representative source mappings
- API, SDK, and webhook: business-data rows
- ServiceNow: CMDB, asset, company, and custom tables
- Jira: assets, organizations, request types, and forms
- Zoom: registrations and surveys
- GitHub: project items and custom properties
Data structure
| Property | Definition |
|---|---|
recordType |
Broad business-object type. |
title |
Best human-readable label. |
summary |
Optional synthesized summary. |
propertiesJson |
Serialized canonicalized key-value attributes. |
textContent |
Flattened text from important properties. |
status |
Current state. |
createdAt |
Creation time. |
updatedAt |
Latest update time. |
ownerRefs |
Observed owner or linked-person identifiers. |
containerRef |
Grouping context. |
sourceUri |
Deep link to the record. |
metadataJson |
Source-specific attributes not promoted to the canonical surface. |
Use when
- The source object is mostly schema-first and property-rich.
Don't use when
- The object is primarily a task; use Work Item.
Read more about the structuredRecord archetype in the API documentation.
workItem
A trackable unit of work with lifecycle, ownership, priority, and completion semantics. This archetype covers tickets, incidents, requests, tasks, problems, and other operational items where state and accountability are first-class.
more details
Representative source mappings
- Jira: issues, requests, incidents, problems, changes, and approvals
- ServiceNow: task and approval tables
- GitHub: issues
- Confluence: tasks
Data structure
| Property | Definition |
|---|---|
title |
Summary or short description. |
descriptionText |
Long-form description or normalized rich text. |
workItemType |
Issue, incident, request, task, change, approval, or problem. |
status |
Current lifecycle state. |
priority |
Urgency or importance. |
createdAt |
Creation time. |
updatedAt |
Latest update time. |
openedByPersonaRef |
Observed identifier of the reporter, requester, or creator. |
assigneeRefs |
Observed identifiers of owners or responders. |
dueAt |
Due date or target completion time. |
resolution |
Resolution code, outcome, or closure note. |
labelsJson |
Serialized tags, components, or categorization properties. |
containerRef |
Project, board, service, repository, or space. |
messageRefsJson |
Serialized comments, reviews, or discussion entries. |
sourceUri |
Deep link to the item. |
metadataJson |
Source-specific severity, sprint, milestone, SLA, watcher, or custom data. |
Use when
- Ownership and workflow state are central.
Don't use when
- The object is primarily a code or version artifact; use Change Artifact.
Read more about the workItem archetype in the API documentation.