Sources

Attach a source to a project.

Accepts inline text, markdown, URL, and PDF sources. Requires Idempotency-Key for safe retries. Check /api/v1/capabilities.sources.types before sending a type. Set metadata.sourceContextMode to full when planning and final artifact writing must receive the complete integrity-verified retained text instead of the normal digest + preview; full mode fails rather than clipping. A producer that sends one source per item names it with producer + externalId; a repeat of an item the project already holds returns that source with deduplicated: true instead of storing it again.

post/story-projects/{projectId}/sources

Request

  • Base URL: https://docs.sleeperhit.studio/api/v1
  • URL: https://docs.sleeperhit.studio/api/v1/story-projects/{projectId}/sources
  • Auth: HTTP bearer

Headers

Idempotency-Keystring required

Customer-generated stable identifier for safe retries of idempotent POST requests.

Request body

type'text' | 'markdown' | 'url' | 'pdf' required

Source payload type. Inline text and markdown are accepted synchronously; url and pdf extract asynchronously through the source worker.

contentstring

Inline payload for text and markdown types. Max 4,000,000 bytes (UTF-8). Retained text is normally capped at 1,500,000 characters.

uristring uri

URL for url and pdf sources. Must be http or https; SSRF-blocked addresses (private, link-local, cloud metadata, multicast) are rejected.

labelstring
retentionPolicy'EXTRACTED_ONLY' | 'STORE_ORIGINAL' | 'METADATA_ONLY'

How long the API persists source content. EXTRACTED_ONLY (default) stores the extracted text and metadata. STORE_ORIGINAL keeps the raw bytes too. METADATA_ONLY drops extracted text after the digest pass.

producerstring

For a program that sends one source per item it covers: the producer's name (e.g. hackernewsradio). Send with externalId, or neither. The integration: prefix is reserved. A producer's items are episode material, not canon: Bible generation never reads them, and a season pins one only when it was curated into that season (items sent here never are). A full-context producer item is not digested: digestStatus: SKIPPED ("Used in full by its episode plan.") is terminal and by design.

externalIdstring

The producer's id for this item (for hackernewsradio, the numeric Hacker News story id). A project holds one live source per producer + externalId: a repeat returns that source with deduplicated: true, including one still PENDING/EXTRACTING. Delete the source to send the item again (and delete one that never becomes READY).

originatedAtstring date-time

When the source material itself was made, not when it is attached: a thread's posting time, an article's publication time. ISO 8601; at most a day in the future. Stored as metadata.originatedAt and returned as originatedAt. A project with seasonCadence: "monthly" files the episode made from this source under that month (UTC); without it, the source's createdAt is used.

metadataobject

Freeform source metadata. Reserved policy: sourceContextMode: "full" makes both StoryPlan generation and final artifact writing consume the complete hash-verified retained text. Full mode requires EXTRACTED_ONLY or STORE_ORIGINAL retention and fails instead of clipping above 1,500,000 characters. sourceProducer is refused: send the top-level producer and externalId. originatedAt here is held to the same rule as the top-level field, and must agree with it when both are sent.

Response

The created source, or the live source already holding this item (deduplicated: true).

deduplicatedboolean required

True when the project already held a live source for this producer + externalId: that source is returned and nothing new is stored.

Changes

No recorded changes to this operation across all 1 revision of this API.