Documentation Index
Fetch the complete documentation index at: https://docs.getcitable.com/llms.txt
Use this file to discover all available pages before exploring further.
What it does
Emits a single piece of content for the brand: validates persona-intent, drafts tostatus='queued', and records the action so its 30-day citation and share-of-voice impact can be measured. One atomic emit bundles what create_content_draft, schedule_content, and mark_content_posted do separately — the fine-grained tools remain available for step-by-step human-UI flows.
Hub vs spoke is built in: set fan_out_role='hub' on the long-form canonical piece, then call emit_content again with fan_out_role='spoke' and parent_action_id=<hub action id> for each channel adaptation. Spoke outcomes roll up to the hub so you can see “this hub’s Reddit spoke delivered 3× the LinkedIn spoke” as a queryable fact.
When to use
- The user (or upstream agent) has decided WHAT to post and on WHICH channel.
- You want one atomic emit that produces a measurable action record.
- You’re building a hub-spoke fan-out — one hub call, N spoke calls referencing the hub.
When not to use
- The user is brainstorming (no decision yet) — use
ingest_conversationinstead. - The content is a paid ad — use
emit_paid. - The action is an outreach reply on a social thread — use
emit_outreach.
Inputs
persona_id(number, required) — the persona this content targets.intent('engagement'|'commercial', required) —engagementbuilds relationships;commercialdrives a buy decision.platform('linkedin'|'twitter'|'reddit'|'blog'|'instagram'|'youtube', required).body(string, 1–8000 chars, required) — the draft. Long-form for blogs; short-form for socials.title(string, ≤200 chars, optional) — defaults tobody[:80].source_task_id(number, optional) — anchor: action ticket this responds to. Either this ORfrom_conversation_id.from_conversation_id(number, optional) — anchor: ingested conversation. Either this ORsource_task_id.action_subtype(string, ≤40 chars, optional) — e.g.'long_form_hub','reddit_spoke','linkedin_spoke'.fan_out_role('hub'|'spoke', optional) — set'hub'on the canonical piece,'spoke'on adaptations.parent_action_id(number, optional) — required whenfan_out_role='spoke'; the hub action’s id.target_prompt_ids(number[], optional) — tracked prompts this content targets. Scopes 30-day outcome measurement.override_reason(string, ≥8 chars, optional) — bypass block-severity persona-intent violations with an audit record.
Response
isError: true with structuredContent: { status: 'blocked', violations: [...] }. Fix the body or pass override_reason to retry.
Persona-intent validation
Every content emit is persona-scoped —persona_id and intent must be supplied so the validation matrix can fire. Block-severity rules halt the emit unless override_reason ≥ 8 chars is passed (one audit record per blocked rule, with the action tagged validation_status='overridden').